I need to draw 2D legends, 2D frame, etc. on top of a 3D scene. Here, I am trying to display a 2D label on top of a 3D sphere, so that the label will always face the user, even if they rotate the scene.
I am using a SCNView to draw the 3D scene (=> works fine) I am using its NSView parent (subclassed to override its draw function) to display the 2D text (=> nothing is displayed)
(var twoDCoordinates:CGPoint is extern)
in my viewController:
@IBOutlet weak var sceneView: SCNView!
func sceneSetup() {
let scene = SCNScene()
// (I set the light and the camera...)
// Adding the sphere
let geometry = SCNSphere (radius: 4.0)
geometry.firstMaterial!.diffuse.contents = CGColor.red
geometry.firstMaterial!.specular.contents = CGColor.white
sphereNode = SCNNode (geometry: geometry)
sphereNode.position = SCNVector3Make(-6, 0, 0)
scene.rootNode.addChildNode (sphereNode)
sceneView.scene = scene
sceneView.allowsCameraControl = true
// compute the 2D coordinates of the text to be displayed
var q = sphereNode.position
q.x += 6.0; q.y += 6.0; q.z += 6.0 // outside of the sphere
let projected = sceneView.projectPoint (q)
twoDCoordinates = CGPoint (x: projected.x, y: projected.y)
sceneView.needsDisplay = true
}
=> The 3D sphere is correctly displayed; twoDCoordinates is correct
In TwoDView:NSView class (which is the sceneView container)
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
// Drawing code here.
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = .byTruncatingTail
paragraphStyle.alignment = .left
let textAttributes = [
NSAttributedString.Key.font: NSFont.systemFont(ofSize: 72.0),
NSAttributedString.Key.paragraphStyle: paragraphStyle]
let label = "Sphere Label"
let size = label (withAttributes: textAttributes)
let rect = CGRect(x: twoDCoordinates.x, y: twoDCoordinates.y, width: size.width, height: size.height)
label.draw(in: rect, withAttributes: textAttributes)
}
=> the function draw is called, but no text is displayed.
I expect the text "Sphere label" to be displayed next to the 3D sphere, but only the 3D scene is displayed., even though function draw is called.