In my application, the user draws a 2D rectangle on the screen using Core Graphics. Once they release their mouse I need to create a SCNPlane and place it into my SceneKit scene at the same screen size and position. I plan on setting the z position of the plane to a constant value away from the camera (lets say 10 units away from the camera).
The part I'm having trouble with is how to position and scale the plane so it looks exactly like what they drew in Core Graphics. BTW the Core Graphics view is on top of the SceneKit view at the same size.
I plan on using the billboard constraint so the plane is facing the camera properly.
I'm sure there is some math to accomplish this using the camera's properties, but I have no clue how to do it.
Best bet is to make a screen-aligned container with its origin and scale set to give you pixel-alignment and your choice of zero-zero location.
your building blocks are sceneView.unprojectPoint and sceneView.frame
import Cocoa // (or UIKit for iOS)
import SceneKit
import PlaygroundSupport;
// create a scene view with an empty scene
var sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
var scene = SCNScene()
sceneView.scene = scene
// have it show in your playground
PlaygroundPage.current.liveView = sceneView;
// a camera
var cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3(0, 0, 3)
scene.rootNode.addChildNode(cameraNode)
var origin = sceneView.unprojectPoint(SCNVector3(0,0,0))
var viewWidth = sceneView.frame.width;
var topRight = sceneView.unprojectPoint(SCNVector3(sceneView.frame.width, 0, 0));
var scale = 2 * (topRight.x - origin.x) / sceneView.frame.width
var container = SCNNode()
origin.z *= -1
origin.x = -2 * topRight.x;
origin.y = -2 * topRight.y;
container.position = origin;
container.scale = SCNVector3(scale, -scale, scale)
cameraNode.addChildNode(container);
func addBox(w:CGFloat, h:CGFloat, x:CGFloat, y:CGFloat) {
let box = SCNNode(geometry: SCNPlane(width: w, height: h))
box.geometry?.firstMaterial?.diffuse.contents = NSColor.red
//SCNPlane geometry is still center-origin
box.position = SCNVector3(x + w / 2, y + h / 2,0)
container.addChildNode(box)
}
addBox(w: 10, h:10, x: 290, y:290)
addBox(w: 10, h:10, x: 0, y:0)
addBox(w: 10, h:10, x: 0, y:290)
addBox(w: 10, h:10, x: 290, y:0)