Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ARKit nodes dissapear after sceneView.session.setWorldOrigin transformation

I have some code that is comprised of the delegate method for obtaining a heading, and a transformation. I take the heading and turn it into radians and use the angle to rotate around the y-axis:

    ┌                             ┐
Y = |  cos(ry)    0   sin(ry)   0 |
    |  0          1   0         0 |
    |  -sin(ry)   0   cos(ry)   0 |
    |  0          0   0         1 |
    └                             ┘

What are the first two columns in SCNMatrix4

code:

func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
        print("received heading: \(String(describing: newHeading))")
        self.currentHeading = newHeading
        print("\(Float(currentHeading.trueHeading)) or for magneticHeading: \(currentHeading.magneticHeading)")
        let headingInRadians = degreesToRadians(deg: Float(currentHeading.trueHeading))
        print("\(headingInRadians) -------- headingInRadians")

        var m = matrix_float4x4()
        m.columns.3 = [0.0, 0.0, 0.0, 1.0]
        m.columns.2 = [sin(headingInRadians), 0.0, cos(headingInRadians), 0.0]
        m.columns.1 = [0.0, 1.0, 0.0, 0.0]
        m.columns.0 = [cos(headingInRadians), 0.0, -sin(headingInRadians), 0.0]

        sceneView.session.setWorldOrigin(relativeTransform: m)
    }

It is removing all the nodes when I call setWorldOrigin. I have tried pausing the session, running the function, and then starting the session again, and I get this weird wonky low fps, low light situation. I know it is the function call to setWorldOrigin because when I remove it I see the nodes and they persist.

UPDATE

Ive been working on this...I am debugging by simply trying to change the scale by 2...all I should see happen is the nodes I have placed in a grid should spread out...however I am still getting the same result. After trying to setWorldOrigin the nodes are removed. Does using this function reset something? Is there a special place I am supposed to use it? (some delegate function)?

UPDATE

print("\(sceneView.scene.rootNode) --- rootNode in renderer") produces:

<SCNNode: 0x1c01f8100 | 111 children> --- rootNode in renderer

So it appears that the rootNode and its children are still somewhere...but where are they going with such a simple and small transformation?

UPDATE

print("\(sceneView.scene.rootNode.position) --- rootNode in renderer") produces:

SCNVector3(x: 0.0, y: 0.0, z: 0.0) --- rootNode in renderer

Yet...I see none of the children...so the rootNode appears to be somewhere else.

UPDATE

I can confirm that the transform is not happening...the positioning of the childnodes (that I can't see) is still the same as its original state (a node every 2 grid blocks (meters) i.e.:

SCNVector3(x: 6.0, y: 0.0, z: -4.0) --- rootNode child node
SCNVector3(x: 6.0, y: 0.0, z: -2.0) --- rootNode child node

UPDATE

The narrowest view of this problem I have now is that even a simple rotate removes the nodes from view...since there is no position change...this means that something is going on with the rendering process I believe.

func viewDidLoad() {    

    ...

    sceneView.scene = scene
    view.addSubview(sceneView)

    let angle = coordinateConverter.getUprightMKMapCameraHeading()
    print("\(angle) --- angle")

    mRotate = matrix_float4x4()
    mRotate.columns.3 = [0.0, 0.0, 0.0, 1.0]
    mRotate.columns.2 = [Float(sin(angle)), 0.0, Float(cos(angle)), 0.0]
    mRotate.columns.1 = [0.0, 0.0, 0.0, 0.0]
    mRotate.columns.0 = [Float(cos(angle)), 0.0, Float(-sin(angle)), 0.0]

    sceneView.session.setWorldOrigin(relativeTransform: mRotate)

console output:

281.689248803283 --- angle

Still, the virtual objects remain invisible, but placed at the origin...which should still be the same.

I also should note that the standard 1,1,1,1 transform DOES work...but obviously, it does nothing...but I guess just using the function doesn't make them disappear...they only disappear if your transform actually does something...

...

var identity = matrix_float4x4()
identity.columns.3 = [0.0, 0.0, 0.0, 1.0]
identity.columns.2 = [0.0, 0.0, 1.0, 0.0]
identity.columns.1 = [0.0, 1.0, 0.0, 0.0]
identity.columns.0 = [1.0, 0.0, 0.0, 0.0]

sceneView.session.setWorldOrigin(relativeTransform: identity)

...

The above transforms nothing...and the nodes remain in view.

If I change the matrix to this (translate by 10,10):

var identity = matrix_float4x4()
identity.columns.3 = [10.0, 0.0, 10.0, 1.0]
identity.columns.2 = [0.0, 0.0, 1.0, 0.0]
identity.columns.1 = [0.0, 1.0, 0.0, 0.0]
identity.columns.0 = [1.0, 0.0, 0.0, 0.0]

It works...

I'm just thinking... do I have to scale my world down (real-world MKMapKit coordinates/unit) maybe because the hardware can't handle a world that is scaled. Also, from the above test...I think I realized that the origin moves when you use this function, but the nodes do not, so If I want the nodes to remain at my position after the transform...and I need to transform them back. Still, the result is the same:

print("\(transformerFromPDFToMk.tx) -- tx")
print("\(transformerFromPDFToMk.ty) -- ty")

m = matrix_float4x4()
m.columns.3 = [Float(transformerFromPDFToMk.tx), 0.0, Float(transformerFromPDFToMk.ty), 1.0]
m.columns.2 = [0.0, 0.0, 1.0, 0.0]
m.columns.1 = [0.0, 1.0, 0.0, 0.0]
m.columns.0 = [1.0, 0.0, 0.0, 0.0]

sceneView.session.setWorldOrigin(relativeTransform: m)

for node in scene.rootNode.childNodes {
    node.position = SCNVector3Make(-Float(transformerFromPDFToMk.tx) + node.position.x, node.position.y, Float(transformerFromPDFToMk.ty) + node.position.z)
}

console output:

81145547.3824476 -- tx
99399579.5362287 -- ty

UPDATE

I SEE MY OBJECTS (kind of)! I thought I had tried this before...but its working a little better now - the code package I used defined a scale (coordinateConverter.unitSizeInMeters)...and I was converting to it improperly. But...they are flickering in and out rapidly...

m = matrix_float4x4()
m.columns.3 = [Float(transformerFromPDFToMk.tx) / Float(coordinateConverter.unitSizeInMeters), 0.0, Float(transformerFromPDFToMk.ty) / Float(coordinateConverter.unitSizeInMeters), 1.0]
m.columns.2 = [0.0, 0.0, 1.0, 0.0]
m.columns.1 = [0.0, 1.0, 0.0, 0.0]
m.columns.0 = [1.0, 0.0, 0.0, 0.0]

sceneView.session.setWorldOrigin(relativeTransform: m)

sceneView.session.setWorldOrigin(relativeTransform: m)

for node in scene.rootNode.childNodes {
    node.position = SCNVector3Make(-Float(transformerFromPDFToMk.tx) / 
       Float(coordinateConverter.unitSizeInMeters) + node.position.x / 
       Float(coordinateConverter.unitSizeInMeters), node.position.y / 
       Float(coordinateConverter.unitSizeInMeters), -
       Float(transformerFromPDFToMk.ty) / 
       Float(coordinateConverter.unitSizeInMeters) + node.position.z / 
       Float(coordinateConverter.unitSizeInMeters))
}

UPDATE

Is the flickering "z-fighting"? https://en.wikipedia.org/wiki/Z-fighting

like image 895
ewizard Avatar asked Oct 16 '22 22:10

ewizard


1 Answers

After resolving the scaling issues, I reduced the size of the world (scale) and put the objects a little further apart from each other (to fix the flickering/"z-fighting") - wikipedia's page was very helpful, I'm pretty sure all I needed to do was reduce the world size.

like image 150
ewizard Avatar answered Oct 21 '22 05:10

ewizard