Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm trying to rotate a cube so that it's facing up, but am getting hung up on the final implementation details. It now reliably will rotate the x,y axis to the correct side, but the z-axis is never rotating (See photos of before and after rotation). When I'm using the code below I always get '0' for my rotationVector.z. What am I missing here?

// Define lookAt vector
lookAtVector = GLKVector3Make(0,0,1);

// Define axes vectors
axes[0] = GLKVector3Make(0,0,1);
axes[1] = GLKVector3Make(-1,0,0);
axes[2] = GLKVector3Make(0,1,0);
axes[3] = GLKVector3Make(1,0,0);
axes[4] = GLKVector3Make(0,-1,0);
axes[5] = GLKVector3Make(0,0,-1);

CGFloat highest_dot = -1.0;
GLKVector3 closest_axis;

for(int i = 0; i < 6; i++) {
    // multiply cube's axes by existing matrix
    GLKVector3 axis = GLKMatrix4MultiplyVector3(matrix, axes[i]);
    CGFloat dot = GLKVector3DotProduct(axis, lookAtVector);
    if(dot > highest_dot) {
        closest_axis = axis;
        highest_dot = dot;
    }
}

GLKVector3 rotationVector = GLKVector3CrossProduct(closest_axis, lookAtVector); 

// Get angle between vectors
CGFloat angle = atan2(GLKVector3Length(rotationVector), GLKVector3DotProduct(closest_axis, lookAtVector));

// normalize the rotation vector
rotationVector = GLKVector3Normalize(rotationVector);

// Create transform
CATransform3D rotationTransform = CATransform3DMakeRotation(angle,  rotationVector.x, rotationVector.y, rotationVector.z);

// add rotation transform to existing transformation
baseTransform = CATransform3DConcat(baseTransform, rotationTransform);
return baseTransform;

Before 3d Rotation Before

After 3d Rotation After

Implementation based on this post

share|improve this question
    
I'm not familiar with ios really, but it sounds like what you're doing is trying to take a cube and make one particular side be facing the same plane that is defined by the camera's position and look vector, or possibly make the cubes face directly towards the camera (which might not be what you want)? Is this correct and if so, which of those operations are you trying to do? –  Jeff Tucker Jun 4 '12 at 2:26
    
Is your lookat vector supposed to change, ever? –  indeed005 Jun 4 '12 at 5:24
add comment

3 Answers

lookAtVector = GLKVector3Make(0,0,1); 
(...) 
GLKVector3 rotationVector = GLKVector3CrossProduct(closest_axis, lookAtVector);

In 3D and higher dimensions, a cross-product returns a vector which is perpendicular to the two input vectors.

lookAtVector is defined as (0,0,1).

Hence, if you use it in a cross-product, no matter what the value of closest_axis might be, the result will have 0 as its z component, because if it did not, it would not be perpendicular to lookAtVector.

You don't say what you're actually trying to do, so I can't go on and explain how to actually do whatever your intent was. But I hope that the explanation of the maths is enough to help you solve your own issue, here!

share|improve this answer
    
Thanks. Answer is spot on. I ended up getting another face that was orthogonal and using that vector to get the Z rotation. Then I could combine the two rotation matrices and get the rotation matrix I needed to rotate the cube to face the camera. Maybe not most efficient way to do it, but works great. –  Steve Baughman Jun 7 '12 at 19:38
add comment

I don't think this is your entire problem, but you do at least need to be doing this:

CGFloat highest_abs_dot = 0.0;
GLKVector3 closest_axis;

for(int i = 0; i < 6; i++) {
    // multiply cube's axes by existing matrix
    GLKVector3 axis = GLKMatrix4MultiplyVector3(matrix, axes[i]);
    CGFloat abs_dot = fabsf(GLKVector3DotProduct(axis, lookAtVector));
    if(abs_dot > highest_abs_dot) {
        closest_axis = axis;
        highest_abs_dot = abs_dot;
    }
}
share|improve this answer
add comment

Remember that there are 4 possible orientations of the cube for any given face 'up'.

I made a game of rotating cubes before (search 'Obecolo').

To avoid floating point approximation errors accumulating in each cubes model matrix, I set up a multiply-linked list of the 24 possible orientations. I.e., each entry would have links to the 'adjacent' orientations obtained by rotating +-90 degrees on each axis.

I built the list on startup, one antry at a time, by multiplying basic 'building block' matrices (i.e., 90, 180 or 270 rotation on X, Y or Z).

To write the code above, it helped a lot to have a cube on my desk with the faces labeled 'TOP', 'BOTTOM', 'LEFT', 'RIGHT', 'FRONT' and 'BACK'. Also, texturing the cube faces with colors that provide a visual cue: RED for +X (cyan for -X), GREEN for +Y (magenta for -Y) and BLUE for +Z (yellow for -Z).

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.