2

I am working on creating annotations using overlaySKScene something similar to this(https://sketchfab.com/models/1144d7be20434e8387a2f0e311eca9b1#). I followed https://github.com/halmueller/ImmersiveInterfaces/tree/master/Tracking%20Overlay to create the overlay.

But in the provided example, they are creating only one annotation and it is static. I want to create multiple annotations dynamically based on the number of child nodes we have and also should be able to position annotation on top of respective child node. How to achieve this?

I am adding overlay like below,

    sceneView.overlaySKScene = InformationOverlayScene(size: sceneView.frame.size)

where InformationOverlayScene is the SKScene in which i have added two childnodes to create one annotation.

Vidhya Sri
  • 1,773
  • 1
  • 17
  • 46

2 Answers2

1

You can add a SKScene or a CALayer as a material property.

You could create a SCNPlane with a specific width and height and add a SpriteKit scene as the material. You can find an example here.

Then you just position the plane where you want it to be and create and delete the annotations as you need them.

jlsiewert
  • 3,494
  • 18
  • 41
  • I want to add these kind of textbox for many child nodes dynamically. Also i want this to behave like an annotation. Even if i resize or move away from the 3D object, the annotations should still be the same size. Please refer to https://sketchfab.com/models/1144d7be20434e8387a2f0e311eca9b1#. By using this method can i achieve something like this? – Vidhya Sri Sep 22 '17 at 09:37
  • No this creates annotations that have a fixed position in space and scale accordingly. – jlsiewert Sep 22 '17 at 17:59
1

Create an array with the annotation sprites that is mapped to the childnodes array, and then do something like the following:

func renderer(_ aRenderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {

    let scnView = self.view as! SCNView
    //for each character
    for var i in 0...inBattleChars.count-1 {
        let healthbarpos = scnView.projectPoint(inBattleChars[i].position)

        battleSKO.healthbars[i].position = CGPoint(x: CGFloat(healthbarpos.x), y: (scnView.bounds.size.height-10)-CGFloat(healthbarpos.y))
    }
}

Before every frame is rendered this updates the position of an SKSprite (in healthBars) for each SCNNode in inBattleChars. The key part is where projectPoint is used to get the SK overlay scene's 2D position based on the SCNNode in the 3D scene.

To prevent the annotations of non-visible nodes from showing up (such as childnodes on the back side of the parent object) use the SCNRenderer’s nodesInsideFrustum(of:) method.

Xartec
  • 2,369
  • 11
  • 22
  • @ Xartec I did the exact same thing. Now i am able to see the overlay but at two different positions. When i open the camera session, it shows the overlay with 3D object correctly but when i move the camera to 180 degrees, i could see the same overlay again in some other position. It is visible only at 2 places and not anywhere else. How could this happen? – Vidhya Sri Oct 09 '17 at 07:17
  • This worked. But since we are changing the position of the overlay in updateAtTime method, the overlay seems to be shaky always and is not looking stable. Is there a way to update the position of overlay child objects only on some notable camera movement or 3d model movement? – Vidhya Sri Oct 28 '17 at 06:04