'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
You provided the same anchor's position for both
a
andb
method's arguments:startAnchor!.position(relativeTo: nil)
There's no expression for
distance
property.If you need an anchor's "landing" on the ground, use plane detection and raycasting.
Potentially, you may not use Y-axis value but
zero level
on the virtual grid andzero 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)
}
}
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)
}
}
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 |