SceneKit invert Y axis without inverting geometry normals
Asked Answered
U

1

8

Generally what I'm trying to achieve: we have map data that historically was all 2D, and the coordinate system we use is the origin point (0,0) at the top left, positive x goes right, positive y goes down. We have now added 3D data by adding a z axis, positive z coming out of the screen towards you (think top-down map view). This is a left handed coordinate system, but SceneKit is a right handed coordinate system. I would like to apply some transform at the top level of my SceneKit Scene that will convert the Scene into a left handed coordinate system such that I can modify/position/add nodes to the scene in terms of our custom mapping coordinate system and things will just work.

So far I have this:

let scene = SCNScene()

let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.scale = SCNVector3(1,-1,1)
scene.rootNode.addChildNode(cameraNode)

This achieves exactly what I want, but has one big problem. It inverts all of the geometry faces, so my geometry's disappear unless I change their material's cullMode:

let mapLength = 1000 //max X axis 
let mapWidth = 800 //max Y axis
let mapHeight = 100 //max Z axis

cameraNode.position = SCNVector3(mapLength / 2, mapWidth / 2, 2000)

let mapPlane = SCNNode()
mapPlane.position = SCNVector3(mapLength / 2, mapWidth / 2, 0)
mapPlane.geometry = SCNPlane(width: mapLength, height: mapWidth)
mapPlane.geometry?.firstMaterial?.diffuse.contents = UIColor.blackColor()
scene.rootNode.addChildNode(mapPlane)

mapPlane doesn't show at all! You have to rotate the camera to the underside of mapPlane in order to see it. You can easily fix this by adding a single line:

mapPlane.geometry?.firstMaterial?.cullMode = .Front

But I don't want to have to change the cullMode for every geometry/material. Is there a way to achieve this without requiring extra code at each geometry/material? Some transform that would invert the geometry face normals for all child nodes of rootNode? Ideally this would be achieved entirely by settings on the actual Scene, or by transforms on rootNode or the camera.

Unconditional answered 24/2, 2016 at 17:25 Comment(2)
Hi - did you ever figure this out? Struggling with it now...Sf
Either change the geometry so it matches the engine (invert all coordinates, change order to make right-handed triangles) or "fake" it within the engine using scale and cullMode as you suggested. I don't see a middle ground.Chiaki
N
0

You can change the winding order of the front faces vs. back faces in OpenGL, which changes which face is considered to be the front face. This is a global state, so should apply to all primitives.

See https://www.khronos.org/opengl/wiki/Face_Culling for more information.

Nessi answered 18/2 at 1:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.