I don't know if this is an appropriate place for topics like this, but I'll give it a try. I'm building a framework for my WebGL project and at the moment I have a problem with a function which will rotate an object towards a target vector with a given angular speed. In Unity engine it's called rotateTowards(), and since I'm coding my framework from a scratch, I'm basing on my observations about how this function works. Lately I have abandoned an idea about interpolating two quaternions in this function using nLERP method, because an angular speed seems to be far more suitable factor. The function seems to be almost working - it works well only when there is no roll or pitch angle in the camera rotation involved, otherwise it makes strange curves and sets the final position after ridiculously long time. I suspect it may have something to do with me methodology of searching the shortest path of rotation between two vectors (which bases on an angle between them and a rotation axis calculated from their cross product). I've been trying to fix this for a long time, but without any success. What I also opt for is to restrict the rotation only to pitch and yaw axises (so no roll would be involved). My very first idea about how to do this was to convert the rotation to an Euler angles vector, nullify roll angle and convert it back to quaternion, but doing so will introduce Gimbal Lock problem, which is incongruous in this case. The code of this function below:
rotateTowards: function(vecTarget, angularSpeed) {
if (this.position.isEqual(vecTarget)) {
return;
}
var vecStart = this.rotation.getForwardVector();
vecTarget.addSelf(this.position);
vecTarget.normalize();
var angleLeft = Math.acos(vecStart.dot(vecTarget));
if (Math.areScalarsSimilar(angleLeft, 0)) {
return;
}
else if (Math.areScalarsSimilar(angleLeft, Math.PI)) {
this.rotation.multiply(this.tempQuat.axisToQuaternion(angularSpeed * deltaT, upVec()));
}
else {
var rotAxis = vecStart.cross(vecTarget);
if (angleLeft > angularSpeed * deltaT) {
this.rotation.multiply(this.tempQuat.axisToQuaternion(angularSpeed * deltaT, rotAxis));
}
else {
this.rotation.multiply(this.tempQuat.axisToQuaternion(angleLeft, rotAxis));
}
}
MVMatrix.setRotation(this.rotation.quaternionToMatrix());
},
Save the world, and give me a hint what is wrong with this code / my notion about this function ^^