'Finding a SIMD<Float> between 2 points in RealityKit

I have implemented a function, which allows me to find a SIMD3 Vector between two points.

private func getMidPosition(_ a: SIMD3<Float>, 
                            _ b: SIMD3<Float>) -> SIMD3<Float> {
    var position: SIMD3<Float> = [0, 0, 0]
    position.x = abs(a.x + b.x) / 2
    position.y = abs(a.y + b.y) / 2
    position.z = abs(a.z + b.z) / 2
    return position
}

I get the position and now I am trying to add some text between those points.

// add text anchor in the middle
let midPosition = getMidPosition(startAnchor!.position(relativeTo: nil), 
                                 startAnchor!.position(relativeTo: nil))
print(midPosition)
                
let textAnchor = AnchorEntity(world: midPosition)
let text = ModelEntity(mesh: .generateText("\(distance)", 
                              extrusionDepth: 0.03, 
                              font: .systemFont(ofSize: 0.06), 
                              containerFrame: .zero, 
                              alignment: .center, 
                              lineBreakMode: .byCharWrapping), 
                  materials: [SimpleMaterial(color: .blue, isMetallic: true)])
                
textAnchor.addChild(text)
arView.scene.addAnchor(textAnchor)

I get no error but nothing gets added and I cannot see the text on the screen.

UPDATE:

// add text anchor in the middle
                let midPosition = getMidPosition(startAnchor!.position, endAnchor!.position)
                print(midPosition) // SIMD3<Float>(0.07334393, 0.0, 0.067246184)
                
                let textAnchor = AnchorEntity(world: midPosition)
                let text = ModelEntity(mesh: MeshResource.generateText("HELLO WORLD", extrusionDepth: 0.03, font: .systemFont(ofSize: 0.06), containerFrame: .zero, alignment: .center, lineBreakMode: .byCharWrapping), materials: [SimpleMaterial(color: .blue, isMetallic: true)])
                
                textAnchor.addChild(text)
                arView.scene.addAnchor(textAnchor)

UPDATE 2: It is added text but it is adding not between the two other anchors. It is adding SIMD3(0.07334393, 0.0, 0.067246184) distance from where I am sitting. So basically, I am sitting on the text and that is why I was not able to see it.

UPDATE 3: I removed the abs but for some reason when I get the SIMD3 vector it shows that the y coordinate is NOT 0. How is that possible when startAnchor and endAnchor has no Y-AXIS.

 // add text anchor in the middle
                let midPosition = getMidPosition(startAnchor!.position, endAnchor!.position)
                print(midPosition)
                
                
                let textAnchor = AnchorEntity(world: midPosition)
                textAnchor.position.y = 0 // EVEN SETTING Y = 0 IS MAKING IT FLOAT IN AIR 
                let text = ModelEntity(mesh: MeshResource.generateText("HELLO WORLD", extrusionDepth: 0.03, font: .systemFont(ofSize: 0.04), containerFrame: .zero, alignment: .center, lineBreakMode: .byCharWrapping), materials: [SimpleMaterial(color: .blue, isMetallic: true)])
                
                textAnchor.addChild(text)
                arView.scene.addAnchor(textAnchor)

The text is floating and not resting on the ground. The other positions like X and Z also does not look right.



Solution 1:[1]

Issues

  1. You provided the same anchor's position for both a and b method's arguments:

    startAnchor!.position(relativeTo: nil)
    
  2. There's no expression for distance property.

  3. If you need an anchor's "landing" on the ground, use plane detection and raycasting.

  4. Potentially, you may not use Y-axis value but zero level on the virtual grid and zero level on detected plane are quite different things.

Code modification

It seems your text is small and/or out of screen. And @Jessy is absolutely right – with abs() method, your anchor's XYZ position will be always positive (i.e. text will only be placed to the right of Origin, above it, and towards the camera, or sometimes even behind the camera). Here's macOS version:

import Cocoa
import RealityKit

class ViewController: NSViewController {
    
    @IBOutlet var arView: ARView!
    
    func getMidPosition(_ a: SIMD3<Float>, 
                        _ b: SIMD3<Float>) -> SIMD3<Float> {

        var position: SIMD3<Float> = [0, 0, 0]
        position = (b + a) / 2
        return position
    }
    
    override func awakeFromNib() {            
        arView.environment.background = .color(.black)
        
        let midPosition = getMidPosition([0,0,0], [1,0,0])   // hardcoding 
        print(midPosition)                                   // [0.5, 0, 0]
                              
        let text = ModelEntity(mesh: .generateText("RealityKit",
                                      extrusionDepth: 0.01,
                                      font: .systemFont(ofSize: 0.3)),
                          materials: [UnlitMaterial(color: .white)])
        
        let textAnchor = AnchorEntity(world: midPosition)
        textAnchor.addChild(text)
        arView.scene.addAnchor(textAnchor)
    }
}

enter image description here

Text's pivot alignment

If you need to center the pivot point of the alignmentContainer node, use the following logic:

import Cocoa
import RealityKit

class ViewController: NSViewController {
    
    @IBOutlet var arView: ARView!
    
    override func awakeFromNib() {
        
        arView.environment.background = .color(.black)
                                              
        let text = ModelEntity(mesh: .generateText("RealityKit",
                                      extrusionDepth: 0.01,
                                      font: .systemFont(ofSize: 0.3)),
                          materials: [UnlitMaterial(color: .white)])
        
        let boundingBox: BoundingBox? = text.model?.mesh.bounds

        let x = ((boundingBox?.max.x)! - (boundingBox?.min.x)!) / 2
        let y = ((boundingBox?.max.y)! - (boundingBox?.min.y)!) / 2
        let z = ((boundingBox?.max.z)! - (boundingBox?.min.z)!) / 2
        
        print(x,y,z)              // [0.69895023, 0.13945313, 0.005]

        let alignmentContainer = Entity()
        alignmentContainer.addChild(text)
        alignmentContainer.position = -1 * [x,y,z]
        
        let anchor = AnchorEntity(world: [0,0,0])
        anchor.addChild(alignmentContainer)
        arView.scene.addAnchor(anchor)
    }
}

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1