Глядя на ваш вопрос, я предполагаю, что вы хотите, чтобы ваш SCNText отображался по центру между вашими двумя точками и над линией, расположенной между ними, и реагировал на изменение положения камеры, например, всегда лицом к текущему pointOfView
.
Как таковой, я создал SCNNode Subclass
, который справляется с этим относительно легко:
class TextNode: SCNNode{
var textGeometry: SCNText!
/// Creates An SCNText Geometry
///
/// - Parameters:
/// - text: String (The Text To Be Displayed)
/// - depth: Optional CGFloat (Defaults To 1)
/// - font: UIFont
/// - textSize: Optional CGFloat (Defaults To 3)
/// - colour: UIColor
init(text: String, depth: CGFloat = 1, font: String = "Helvatica", textSize: CGFloat = 0.1, colour: UIColor) {
super.init()
//1. Create A Billboard Constraint So Our Text Always Faces The Camera
let constraints = SCNBillboardConstraint()
//2. Create An SCNNode To Hold Out Text
let node = SCNNode()
let max, min: SCNVector3
let tx, ty, tz: Float
//3. Set Our Free Axes
constraints.freeAxes = .Y
//4. Create Our Text Geometry
textGeometry = SCNText(string: text, extrusionDepth: depth)
//5. Set The Flatness To Zero (This Makes The Text Look Smoother)
textGeometry.flatness = 0
//6. Set The Alignment Mode Of The Text
textGeometry.alignmentMode = kCAAlignmentCenter
//7. Set Our Text Colour & Apply The Font
textGeometry.firstMaterial?.diffuse.contents = colour
textGeometry.firstMaterial?.isDoubleSided = true
textGeometry.font = UIFont(name: font, size: textSize)
//8. Position & Scale Our Node
max = textGeometry.boundingBox.max
min = textGeometry.boundingBox.min
tx = (max.x - min.x) / 2.0
ty = min.y
tz = Float(depth) / 2.0
node.geometry = textGeometry
node.scale = SCNVector3(0.001, 0.001, 0.001)
node.pivot = SCNMatrix4MakeTranslation(tx, ty, tz)
self.addChildNode(node)
self.constraints = [constraints]
}
/// Places The TextNode Between Two SCNNodes
///
/// - Parameters:
/// - nodeA: SCNode
/// - nodeB: SCNode
func placeBetweenNodes(_ nodeA: SCNNode, and nodeB: SCNNode){
let minPosition = nodeA.position
let maxPosition = nodeB.position
let x = ((maxPosition.x + minPosition.x)/2.0)
let y = (maxPosition.y + minPosition.y)/2.0 + 0.01
let z = (maxPosition.z + minPosition.z)/2.0
self.position = SCNVector3(x, y, z)
}
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
Примером использования этого является следующий (обратите внимание, я не поставилмежду узлами), но, тем не менее, это должно указать вам правильное направление:
/// Generates Two SCNNodes & Places An SCNTextGeometry Between Them
func generateNodes(){
//1. Create An SCNSphere
let sphereNode = SCNNode()
let sphereNodeGeometry = SCNSphere(radius: 0.01)
sphereNodeGeometry.firstMaterial?.diffuse.contents = UIColor.cyan
sphereNode.geometry = sphereNodeGeometry
//2. Add The Starter Node And Place It 0.5m To The Left Of Our World Origin
let starterNode = sphereNode.clone()
starterNode.position = SCNVector3(-0.5, 0, -0.5)
self.augmentedRealityView.scene.rootNode.addChildNode(starterNode)
//3. Add The End Node And Place It 0.5m To The Right Of Our World Origin
let endNode = sphereNode.clone()
endNode.position = SCNVector3(0.5, 0, -0.5)
self.augmentedRealityView.scene.rootNode.addChildNode(endNode)
//4. Although We Know The Distance Between The Nodes Is 1m, Calculate It Anyway
if let formattedDistance = calculateDistanceBetween(starterNode, and: endNode)?.distance{
//5. Create The Distance Label
let distanceLabel = TextNode(text: "\(formattedDistance)m", colour: .white)
//6. Call The TextNode Place Between Nodes Function To Center The Text Between The Nodes
distanceLabel.placeBetweenNodes(starterNode, and: endNode)
//7. Add It To Our Scene
self.augmentedRealityView.scene.rootNode.addChildNode(distanceLabel)
}
}
/// Calculates The Distance Between Two SCNNodes
///
/// -
/// - Returns: (distance: Float, nodeA: GLKVector3, nodeB: GLKVector3)
func calculateDistanceBetween(_ starterNode: SCNNode, and endNode: SCNNode) -> (distance: Float, nodeA: GLKVector3, nodeB: GLKVector3)?{
//1. Convert The SCNVector3 Positions To GLKVector3
let nodeAVector3 = GLKVector3Make(starterNode.position.x, starterNode.position.y, starterNode.position.z)
let nodeBVector3 = GLKVector3Make(endNode.position.x, endNode.position.y, endNode.position.z)
//2. Calculate The Distance
let distance = GLKVector3Distance(nodeAVector3, nodeBVector3)
let meters = Measurement(value: Double(distance), unit: UnitLength.meters)
print("Distance Between Markers Nodes = \(String(format: "%.2f", meters.value))m")
//4. Return The Distance A Positions Of The Nodes
return (distance: distance , nodeA: nodeAVector3, nodeB: nodeBVector3)
}
Если вам это интересно, вы можете получить более подробный и подробный пример здесь: Измерение вARKit
Надеюсь, это поможет ...