I'm trying to rotate an object in a 3d view
using pans. There are 2 axes of rotation: the objects y-axis and a global fixed x-axis. Around the y axis i rotate simply using rotation matrices generated by method CATransform3DRotate
and around fixed x-axis i use quaternions.
Here i some code wich demonstrates the behaviour:
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView: viewController.view];
CGPoint lastLoc = [touch previousLocationInView: viewController.view];
CGPoint diff = CGPointMake(lastLoc.x - location.x, lastLoc.y - location.y);
float rotX = 1 * DEGREES_TO_RADIANS(diff.y / 4.0);
float rotY = -1 * DEGREES_TO_RADIANS(diff.x / 4.0);
CATransform3D m = glView.modelTransform;
if(fabs(diff.y) > fabs(diff.x) * 5.0) { //up-down
Vector3D xAxis = {1.0, 0.0, 0.0};
Vector4D quaternion = [self makeQuaternionFromAxis: xAxis andAngle:rotX];
Vector4D currentQuaterion = [self makeQuaternionFromRotationMatrix: m];
quaternion = [self multiplyQuaternion:currentQuaterion buAnother:quaternion];
m = [self makeRo
tationMatrixFromQuaternion:quaternion];
m = CATransform3DConcat(m, origin);
}
else { //right-left
Vector3D yAxis = {0.0, 1.0, 0.0};
m = CATransform3DRotate(m, rotY, yAxis.x, yAxis.y,yAxis.z);
}
glView.modelTransform = m;
I separate horizontal and vertical movement. The origin variable is original posiotion of the object in 3d view.The problem is that sometimes the object gets yaw angle rotation and and the rotation gets messed up and sometimes the object itself! This situation appears when i chaotically make pans on the screen. I tried to normalize the movement but this didnt helped me. Can someone tell me what i'm doing wrong.
Fixed code like this:
Vector4D quaternion;
if( fabs(diff.y) > fabs(diff.x) ) { //up-down
Vector3D xAxis = {1.0, 0.0, 0.0};
quaternion = [self makeQuaternionFromAxis: xAxis andAngle:rotX];
quaternion = [self multiplyQuaternion:quaternion buAnother:currentQuaterion];
}
else { //right-left
Vector3D yAxis = {0.0, 1.0, 0.0};
quaternion = [self makeQuaternionFromRotationMatrix:CATransform3DMakeRotation(rotY, yAxis.x, yAxis.y,yAxis.z);
quaternion = [self multiplyQuaternion:quaternion buAnother:currentQuaterion]
}
currentQuaterion = quaternion;
glView.modelTransform = CATransform3DConcat([self makeRotationMatrixFromQuaternion:quaternion],perspective);
currentQuaternion
holds current object rotation.
My summary: To multiply 'rotations' always use quaternions, and than transform tham into rotation matrix.