Get “up” side of SCNNode from Orientation

前端 未结 2 1361
庸人自扰
庸人自扰 2021-02-10 18:14

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

2条回答
  •  余生分开走
    2021-02-10 18:42

    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;
    }
    

提交回复
热议问题