admin管理员组文章数量:1322838
I'm looking to understand quaternions for three.js, but for all the tutorials, I haven't been able to translate them into the application I need. This is the problem:
Given a sphere centered at (0,0,0), I want to angle an object on the sphere's surface, that acts as the focal point for the camera. This point is to be moved and rotated on the surface with keyboard input. Setting the focal point into a chosen orbit is easy of course, but maintaining the right rotation perpendicular to the surface escapes me. I know quaternions are neccessary for smooth movement and arbitrary axis rotation, but I don't know where to start.
The second part then is rotating the camera offset with the focal point. The snippet I found for this does not have the desired effect anymore, as the cameraOffset does not inherit the rotation:
var cameraOffset = relativeCameraOffset.clone().applyMatrix4( focalPoint.matrixWorld );
camera.position.copy( focalPoint.position.clone().add(cameraOffset) );
camera.lookAt( focalPoint.position );
Update 1: Tried it with fixed camera on the pole and rotating the planet. But unless I'm missing something important, this fails as well, due to the directions getting skewed pletely when going towards the equator. (Left bees forward). Code in update is:
acceleration.set(0,0,0);
if (keyboard.pressed("w")) acceleration.x = 1 * accelerationSpeed;
if (keyboard.pressed("s")) acceleration.x = -1 * accelerationSpeed;
if (keyboard.pressed("a")) acceleration.z = 1 * accelerationSpeed;
if (keyboard.pressed("d")) acceleration.z = -1 * accelerationSpeed;
if (keyboard.pressed("q")) acceleration.y = 1 * accelerationSpeed;
if (keyboard.pressed("e")) acceleration.y = -1 * accelerationSpeed;
velocity.add(acceleration);
velocity.multiplyScalar(dropOff);
velocity.max(minV);
velocity.min(maxV);
planet.mesh.rotation.x += velocity.x;
planet.mesh.rotation.y += velocity.y;
planet.mesh.rotation.z += velocity.z;
So I'm still open for suggestions.
I'm looking to understand quaternions for three.js, but for all the tutorials, I haven't been able to translate them into the application I need. This is the problem:
Given a sphere centered at (0,0,0), I want to angle an object on the sphere's surface, that acts as the focal point for the camera. This point is to be moved and rotated on the surface with keyboard input. Setting the focal point into a chosen orbit is easy of course, but maintaining the right rotation perpendicular to the surface escapes me. I know quaternions are neccessary for smooth movement and arbitrary axis rotation, but I don't know where to start.
The second part then is rotating the camera offset with the focal point. The snippet I found for this does not have the desired effect anymore, as the cameraOffset does not inherit the rotation:
var cameraOffset = relativeCameraOffset.clone().applyMatrix4( focalPoint.matrixWorld );
camera.position.copy( focalPoint.position.clone().add(cameraOffset) );
camera.lookAt( focalPoint.position );
Update 1: Tried it with fixed camera on the pole and rotating the planet. But unless I'm missing something important, this fails as well, due to the directions getting skewed pletely when going towards the equator. (Left bees forward). Code in update is:
acceleration.set(0,0,0);
if (keyboard.pressed("w")) acceleration.x = 1 * accelerationSpeed;
if (keyboard.pressed("s")) acceleration.x = -1 * accelerationSpeed;
if (keyboard.pressed("a")) acceleration.z = 1 * accelerationSpeed;
if (keyboard.pressed("d")) acceleration.z = -1 * accelerationSpeed;
if (keyboard.pressed("q")) acceleration.y = 1 * accelerationSpeed;
if (keyboard.pressed("e")) acceleration.y = -1 * accelerationSpeed;
velocity.add(acceleration);
velocity.multiplyScalar(dropOff);
velocity.max(minV);
velocity.min(maxV);
planet.mesh.rotation.x += velocity.x;
planet.mesh.rotation.y += velocity.y;
planet.mesh.rotation.z += velocity.z;
So I'm still open for suggestions.
Share Improve this question edited Jan 25, 2014 at 8:08 Ineluki asked Jan 24, 2014 at 8:26 InelukiIneluki 1181 gold badge1 silver badge7 bronze badges 8- You may need help with quaternions, but not to solve your problem. See stackoverflow./questions/21005526/… – WestLangley Commented Jan 24, 2014 at 14:12
- I see how that would solve one-time positioning and alignment, but movement would be more and more distorted the closer you are to the poles and I don't see a way around that. – Ineluki Commented Jan 24, 2014 at 16:13
- Could you please explain exactly what you want to achieve in terms of what the keyboard shall do? Do you want the view to go up/down/left/right by the same angle every time the user presses one of these keys for a defined amount of time? (i.e.: avoid gimbal lock when looking at the poles and left/right do nothing). Ideally you'd need 6 keys: up-down, left-right, clowckwise-counterclockwise roll, but you may have something else in mind, so better ask before answering out of topic! – marcv81 Commented Jan 24, 2014 at 17:53
- 1 Can you keep the camera fixed above the north pole, and spin the planet underneath? Logically easier. – WestLangley Commented Jan 24, 2014 at 22:21
- 1 The current planet rotation, and the extra spin you want to add during each iteration have to be bined. This is not an addition like in your sample code. You have to create a new rotation for the current iteration and bine it with the previous planet total rotation. Combining rotations is equivalent to matrix multiplications or quaternion multiplications. – marcv81 Commented Jan 26, 2014 at 13:57
2 Answers
Reset to default 4Finally found the solution from a mixture of matrices and quaternions:
//Setup
var ux = new THREE.Vector3(1,0,0);
var uy = new THREE.Vector3(0,1,0);
var uz = new THREE.Vector3(0,0,1);
var direction = ux.clone();
var m4 = new THREE.Matrix4();
var dq = new THREE.Quaternion(); //direction quad base
var dqq; //final direction quad
var dq2 = new THREE.Quaternion();
dq2.setFromAxisAngle(uz,Math.PI/2); //direction perpendicular rot
//Update
if (velocity.length() < 0.1) return;
if (velocity.x) { focalPoint.translateY( velocity.x ); }
if (velocity.y) { focalPoint.translateX( velocity.y ); }
//create new direction from focalPoint quat, but perpendicular
dqq = dq.clone().multiply(focalPoint.quaternion).multiply(dq2);
velocity.multiplyScalar(dropOff);
//forward direction vector
direction = ux.clone().applyQuaternion(dqq).normalize();
//use Matrix4.lookAt to align focalPoint with the direction
m4.lookAt(focalPoint.position, planet.mesh.position, direction);
focalPoint.quaternion.setFromRotationMatrix(m4);
var cameraOffset = relativeCameraOffset.clone();
cameraOffset.z = cameraDistance;
cameraOffset.applyQuaternion(focalPoint.quaternion);
camera.position = focalPoint.position.clone().add(cameraOffset) ;
//use direction for camera rotation as well
camera.up = direction;
camera.lookAt( focalPoint.position );
This is the hard core of it. It pans (and with some extension rotates) around the planet without the poles being an issue.
I'm not sure to understand your problem. But for help, I draw a boat on a sphere with the code below.
var geometry = new THREE.ShapeGeometry(shape);
var translation = new THREE.Matrix4().makeTranslation(boat.position.x, boat.position.y, boat.position.z);
var rotationZ = new THREE.Matrix4().makeRotationZ(-THREE.Math.degToRad(boat.cap));
var rotationX = new THREE.Matrix4().makeRotationX(-THREE.Math.degToRad(boat.latitude));
var rotationY = new THREE.Matrix4().makeRotationY(Math.PI / 2 + THREE.Math.degToRad(boat.longitude));
var roationXY = rotationY.multiply(rotationX);
geometry.applyMatrix(rotationZ);
geometry.applyMatrix(roationXY );
geometry.applyMatrix(translation);
- First, I apply a rotation on Z to define boat cap
- Then, I apply rotation on Y,X to to set the boat perpendicular to the surface of the sphere
- Finally I apply a translation to put the boat on the surafce of the sphere
The rotations order is important
本文标签: javascriptTHREEjs Need Help rotating with QuaternionsStack Overflow
版权声明:本文标题:javascript - THREE.js: Need Help rotating with Quaternions - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742117097a2421517.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论