I have an SCNBox
in an SCNScene. Once the scene animates the SCNBox
changes is orientation which can be seen by checking its presentationNode.ori
Here is a method that returns the index of the face that's facing up. It assumes that "boxNode" is a box made of 6 faces with the following (arbitrary) order: front / right / back / left / up / bottom. It returns the index of the face that is facing up. Don't forget to import then . For an arbitrary mesh, you would have to use the face normals instead of "boxNormals" (which is not obvious to compute since SceneKit meshes have one normal per vertex, not one normal per face, so you would have to compute the normals per face yourself).
- (NSUInteger) boxUpIndex:(SCNNode *)boxNode
{
SCNVector4 rotation = boxNode.rotation;
SCNVector4 invRotation = rotation; invRotation.w = -invRotation.w;
SCNVector3 up = SCNVector3Make(0,1,0);
//rotate up by invRotation
SCNMatrix4 transform = SCNMatrix4MakeRotation(invRotation.w, invRotation.x, invRotation.y, invRotation.z);
GLKMatrix4 glkTransform = SCNMatrix4ToGLKMatrix4(transform);
GLKVector3 glkUp = SCNVector3ToGLKVector3(up);
GLKVector3 rotatedUp = GLKMatrix4MultiplyVector3(glkTransform, glkUp);
//build box normals (arbitrary order here)
GLKVector3 boxNormals[6] = {{{0,0,1}},
{{1,0,0}},
{{0,0,-1}},
{{-1,0,0}},
{{0,1,0}},
{{0,-1,0}},
};
int bestIndex = 0;
float maxDot = -1;
for(int i=0; i<6; i++){
float dot = GLKVector3DotProduct(boxNormals[i], rotatedUp);
if(dot > maxDot){
maxDot = dot;
bestIndex = i;
}
}
return bestIndex;
}