I had the same problem recently, so I had a look at some of the THREE.*Controls files, similar to you.
Using those as a basis, I made this:
https://github.com/squarefeet/THREE.ObjectControls
The important bits are the following (see here for context):
var updateTarget = function( dt ) {
var velX = positionVector.x * dt,
velY = positionVector.y * dt,
velZ = positionVector.z * dt;
rotationQuaternion.set(
rotationVector.x * dt,
rotationVector.y * dt,
rotationVector.z * dt,
1
).normalize();
targetObject.quaternion.multiply( rotationQuaternion );
targetObject.translateX( velX );
targetObject.translateY( velY );
targetObject.translateZ( velZ );
};
The rotationVector
is probably of most interest to you, so here's what it's doing:
It's using a THREE.Vector3
to describe the rotation, the rotationVector
variable in this example.
Each component of the rotationVector
(x
, y
, z
) is relative to pitch, yaw, and roll respectively.
Set a quaternion's x
, y
, and z
values to the of the rotation vector, making sure the w
component is always 1
(to learn what the w
component does, see here, it's a great answer.
Normalizing this quaternion will get us a quaternion of length 1
, which is very handy when we come to the next step...
targetObject
in this case is an instance of THREE.Object3D
(a THREE.Mesh
, which inherits from THREE.Object3D
), so it has a quaternion we can play with.
So now, it's just a matter of multiplying your targetObject
's quaternion by your shiny new rotationQuaternion
.
Since our object is now rotated to where we want, we can move it along it's new axis angles by using translateX/Y/Z.
The important thing to note here is that quaternions don't act like Euler vectors. Rather than adding two quaternions together to get a new angle, you multiply them.
Anyway, I hope that helps you somewhat!