【问题标题】:Aligning SCNText with SCNBox in iOS SceneKit with boundingBox?iOS SceneKit中的SCNText与SCNBox与boundingBox对齐?
【发布时间】:2017-08-23 08:55:08
【问题描述】:

修改后的问题:

我不明白为什么白色节点在它是一个盒子或球体时是居中的,而在它是文本时却不是。您可以注释/取消注释 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

例如

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

【问题讨论】:

  • 白盒是黑盒的子节点吗?您是否正在做任何翻译、旋转等以使其出现在前面?如果您能发布更多代码会很有帮助。
  • 我在操场上运行该代码 sn-p 并得到每个值的 +/- 5。
  • 是的,我将白盒设置为黑盒的子项。当它不是黑盒子的孩子时,max.y 值为 5.0。我正在 Swift 操场上修改代码以澄清问题。

标签: ios swift scenekit


【解决方案1】:

我想我现在明白了。

看起来您正试图在对象前面放置一些文本,文本以相对于相机的对象为中心。这个问题与边界框本身无关。对吧?

您会看到白色几何体是球体或 SCNText 的不同行为,因为 SCNText 使用与其他具体 SCNGeometry 类不同的原点约定。其他几何图形将原点置于中心。 SCNText 将它放在文本的左下方。如果我没记错的话,“lower”是指字体的底部(最低下降),而不是基线。

因此,您需要计算文本的边界框,并在定位文本节点时将其考虑在内,以使其居中。对于其他几何类型,您不需要这样做。如果被覆盖的物体或相机正在移动,您需要在渲染循环中计算从相机到被覆盖物体的光线,并更新文本的位置。

Swift Scenekit - Centering SCNText - the getBoundingBoxMin:Max issue 是相关的。

如果您只想要覆盖文本,您可能会发现将文本放在 SKScene 覆盖中更容易。这方面的一个例子是https://github.com/halmueller/ImmersiveInterfaces/tree/master/Tracking%20Overlay(警告,可能已经设置了位腐烂,我有一段时间没有尝试过该代码)。

【讨论】:

  • 我在发布之前阅读了其他帖子。它没有帮助,因为它已经过时,不完整等......我更新了上面的代码。我为盒子宽度/高度和文本宽度/高度添加了一些计算。我尝试手动设置文本的位置,但它没有正确对齐。如果我可以直观地看到框和文本节点的边界框,那将会很有帮助。
  • 我有一个问题是 SCNText 是否有 sizeToFit ?当您为 SCNText 节点设置文本时,它的大小是适合文本的最小大小还是其他一些默认值?
  • 我发现 SKScene 覆盖很容易做到,但性能却很糟糕。它浪费了CPU来转换坐标。静态节点很好。但是,如果您希望 2d 标签跟踪 3d 节点,那么它会立即影响性能。在我的实验中,我在一个场景中显示了大约 30 个跟踪标签,并且帧速率下降到 20fps。
猜你喜欢
  • 2014-10-28
  • 2019-05-09
  • 2017-12-23
  • 2015-02-19
  • 1970-01-01
  • 2020-05-18
  • 1970-01-01
  • 2016-12-03
  • 2014-10-05
相关资源
最近更新 更多