修订问题:
我不明白为什么白色节点在它是一个盒子或球体时是居中的,而不是在它的文本时。您可以注释/取消注释whiteGeometry变量,以查看每个不同几何体的显示方式。我原本以为我必须通过确定框的宽度和文本以及计算文本的位置来手动居中文本。我需要这样做吗?为什么文本表现不同?
import SceneKit
import PlaygroundSupport
let scene = SCNScene()
let sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
sceneView.scene = scene
sceneView.backgroundColor = .darkGray
sceneView.autoenablesDefaultLighting = true
sceneView.allowsCameraControl = true
PlaygroundPage.current.liveView = sceneView
// Camera
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
scene.rootNode.addChildNode(cameraNode)
cameraNode.position = SCNVector3(x: 0, y: 0, z: 25)
sceneView.pointOfView = cameraNode
let blackGeometry = SCNBox(width: 10.0, height: 10.0, length: 10.0, chamferRadius: 0)
blackGeometry.firstMaterial?.diffuse.contents = UIColor.black
print("blackGeometry min=\(blackGeometry.boundingBox.min)")
print("blackGeometry max=\(blackGeometry.boundingBox.max)")
let blackNode = SCNNode(geometry: blackGeometry)
blackNode.position = SCNVector3(x: 0, y: 0, z: 0)
scene.rootNode.addChildNode(blackNode)
// let whiteGeometry = SCNBox(width: 3.0, height: 3.0, length: 3.0, chamferRadius: 0)
let whiteGeometry = SCNText(string: "L", extrusionDepth: 0)
whiteGeometry.alignmentMode = kCAAlignmentLeft
whiteGeometry.font = UIFont.systemFont(ofSize: 8.0)
// let whiteGeometry = SCNSphere(radius: 3.0)
whiteGeometry.firstMaterial?.diffuse.contents = UIColor.white
print("whiteGeometry min=\(whiteGeometry.boundingBox.min)")
print("whiteGeometry max=\(whiteGeometry.boundingBox.max)")
let whiteNode = SCNNode(geometry: whiteGeometry)
let boxWidth = blackGeometry.boundingBox.max.x - blackGeometry.boundingBox.min.x
let boxHeight = blackGeometry.boundingBox.max.y - blackGeometry.boundingBox.min.y
print("boxWidth=\(boxWidth)")
print("boxHeight=\(boxHeight)")
let txtWidth = whiteGeometry.boundingBox.max.x - whiteGeometry.boundingBox.min.x
let txtHeight = whiteGeometry.boundingBox.max.y - whiteGeometry.boundingBox.min.y
print("txtWidth=\(txtWidth)")
print("txtHeight=\(txtHeight)")
whiteNode.position = SCNVector3(x: -5.0, y: -5.0, z: 10)
scene.rootNode.addChildNode(whiteNode)
//blackNode.addChildNode(whiteNode)
print("done")
原始问题(旧):
假设我有两个SCNBox节点(我正在简化它以使其清楚,但解决方案必须适用于其他几何)。一个大黑盒子和一个小白盒子。我想把白框放在黑匣子前面。
为此,我需要确定两个节点的宽度和高度。请记住,节点可能不是像球体或文本这样的框。据我所知,确定宽度/高度的唯一方法是通过几何体上的boundingBox属性。它的最小值和最大值在Apple的参考手册中没有明确和完整描述。为了获得高度,似乎我会基于boundingBox.max.y和boundingBox.min.y来计算它。所以看一下10x10x10盒子下面的例子,我看不出我怎么能得到10.0作为高度,因为max.y 5.20507812
e.g。
let box = SCNBox(width: 10.0, height: 10.0, length: 10.0, chamferRadius: 0)
print("box min=\(box.boundingBox.min)")
print("box max=\(box.boundingBox.max)")
的产率:
box min=SCNVector3(x: -5.0, y: -5.0, z: -5.0)
box max=SCNVector3(x: 5.0, y: 5.20507812, z: 5.0)
为什么max.y = 5.20507812?我该如何确定高度/宽度?
另请参阅:SCNBoundingVolume
答案 0 :(得分:2)
我想我现在明白了。
看起来您正试图在对象前放置一些文本,文本以相对于相机的对象为中心。而这个问题本身并不是关于边界框的问题。正确?
您会看到白色几何体是球体或SCNText的不同行为,因为SCNText使用与其他具体SCNGeometry类不同的原点约定。其他几何形状将原点放在中心位置。 SCNText将它放在文本的左下角。如果我没记错的话,"降低"表示字体的底部(最低下降),而不是基线。
因此,您需要计算文本的边界框,并在定位文本节点时将其考虑在内,以使其居中。您不需要为其他几何类型执行此操作。如果被遮盖的物体或相机正在移动,您需要在渲染循环中计算从摄像机到被遮盖物体的光线,并更新文本的位置。
Swift Scenekit - Centering SCNText - the getBoundingBoxMin:Max issue是相关的。
如果您只想要叠加文字,您可能会发现将文字放在SKScene叠加层中会更容易。这方面的一个例子是https://github.com/halmueller/ImmersiveInterfaces/tree/master/Tracking%20Overlay(警告,有点腐烂可能已经开始,我还没试过这段代码)。