swiftscenekitaugmented-realityarkithomogenous-transformation

SceneKit – What is the lowest row of elements in SCNMatrix4 for?


In SCNMatrix4 struct, the last m44 element is used for Homogeneous Coordinates.

I'd like to know what are m14, m24 and m34 elements in SCNMatrix4? And what exactly I can use these three elements for?

init(m11: Float, m12: Float, m13: Float, m14: Float, 
     m21: Float, m22: Float, m23: Float, m24: Float, 
     m31: Float, m32: Float, m33: Float, m34: Float, 
     m41: Float, m42: Float, m43: Float, m44: Float)

enter image description here


Solution

  • I could be wrong but I think m41, m42, and m43 can be used to get positional data and is essentially the same as using result.worldTransform.columns.3when performing a hitTest.

    As such when placing an SCNNode via performing an ARSCNHitTest you could use either:

    let hitTestTransform = SCNMatrix4(result.worldTransform)
    let positionFromMatrix4 = SCNVector3(hitTestTransform.m41, hitTestTransform.m42, hitTestTransform.m43)
    let positionFromColumns =  SCNVector3(result.worldTransform.columns.3.x, result.worldTransform.columns.3.y, result.worldTransform.columns.3.z) 
    

    The below example should help clarify things:

    /// Places Our Model At The Position Of An Existining ARPlaneAnchor
    ///
    /// - Parameter gesture: UITapGestureRecognizer
    @IBAction func placeModel(_ gesture: UITapGestureRecognizer){
    
        //1. Get The Touch Location
        let touchLocation = gesture.location(in: self.augmentedRealityView)
    
        //2. Perform An ARSCNHitTest For Any Existing Planes
        guard let result = self.augmentedRealityView.hitTest(touchLocation, types: [.existingPlane, .existingPlaneUsingExtent]).first else { return }
    
            //3. Get The World Transform
            let hitTestTransform = SCNMatrix4(result.worldTransform)
    
            //4. Initialize Our Position Either From .m41, .m42, .m43 Or From Columns.3
            let positionFromMatrix4 = SCNVector3(hitTestTransform.m41, hitTestTransform.m42, hitTestTransform.m43)
            let positionFromColumns =  SCNVector3(result.worldTransform.columns.3.x, result.worldTransform.columns.3.y, result.worldTransform.columns.3.z)
    
            //5. Log Them To Check I'm Not Being A Moron
            print(
                """
                Position From Matrix 4 == \(positionFromMatrix4)
                Position From Columns == \(positionFromColumns)
                """)
    
            /*
            Position From Matrix 4 == SCNVector3(x: -0.39050543, y: -0.004766479, z: 0.08107365)
            Position From Columns == SCNVector3(x: -0.39050543, y: -0.004766479, z: 0.08107365)
            */
    
            //6. Add A Node At The Position & Add It To The Hierachy
            let boxNode = SCNNode(geometry: SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0))
            boxNode.geometry?.firstMaterial?.diffuse.contents = UIColor.cyan
            boxNode.position = positionFromMatrix4
            self.augmentedRealityView.scene.rootNode.addChildNode(boxNode)
    }
    

    Hope it helps...