0

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.

Caconde
  • 4,177
  • 7
  • 35
  • 32
silberz
  • 105
  • 1
  • 5
  • Use SCNText within the scene view to show text. – El Tomato Aug 24 '19 at 04:31
  • If I use a SCNText node, then when I rotate the view, the label will rotate and will be soon upside down, whereas I need the label to always be readable (as well as other legends for the 3d figure) – silberz Aug 24 '19 at 13:32
  • Thanks El Tomato, you are right: I just used a transparent background for the SCNView and now I can see the legend on the NSView. – silberz Aug 24 '19 at 15:32

0 Answers0