Search code examples
iosswiftarkitbounding-boxscntext

Is it normal that if a node is scaled the contained bounding box of scntext is not too?


I have been looking to display some text using arkit. To achieve this I have created an SCNText object, given it a font size and scaled it down. This appears to be the recommended way to regulate its size.

Now for the positioning I need to calculate the height of the SCNText object. For this there is the boundingBox method that returns a (min, max) tuple.

The problem is that the bounding box parameters still describe the original bounding box without scaling.

Am I missing something here? My only goal is to get a decent sized 3d text and knowing its height.

Thank you!

private func displayBarValue(barNode: ARBarChartBar) {
    let barValueText = SCNText(string: String(barNode.value), extrusionDepth: 0.0)
    let fontSize = CGFloat(1)
    barValueText.font = UIFont (name: "Arial", size: fontSize)
    barValueText.firstMaterial!.isDoubleSided = true
    barValueText.firstMaterial!.diffuse.contents = UIColor.white

    let barValueLabel = SCNNode()
    barValueLabel.geometry = barValueText

    let scale = Float(0.05/fontSize)
    barValueLabel.scale = SCNVector3(scale, scale, scale)
    center(node: barValueLabel)

    let min = barValueLabel.boundingBox.min
    let max = barValueLabel.boundingBox.max
    let barValueLabelHeight = max.y - min.y
    let spaceBetweenBarAndText = Float(0.012)

    barValueLabel.position = SCNVector3(x: 0, y: barNode.barHeight/2+barValueLabelHeight/2+spaceBetweenBarAndText, z: 0)

    barNode.addChildNode(barValueLabel)
    }
}

func center(node: SCNNode) {
  let (min, max) = node.boundingBox
  let dx = min.x + 0.5 * (max.x - min.x)
  let dy = min.y + 0.5 * (max.y - min.y)
  let dz = min.z + 0.5 * (max.z - min.z)
  node.pivot = SCNMatrix4MakeTranslation(dx, dy, dz)
}

Solution

  • Am I missing something here?

    Sounds like it. According to the docs, the bounding box is defined in terms of the local coordinate system, but transformations such as scaling are usually done by adjusting the way the local coordinate system is mapped to the container's coordinate system. From the SCNBoundingVolume docs:

    The bounding volume of a node with an attached geometry is the bounding volume of the geometry, expressed in the node’s local space.

    In short, you want to know how big the text is relative to other things in the scene, but you're getting the size in the text node's local coordinate system. If you want to know the size in a different coordinate space, you'll need to apply the node's transformation to the bounding box.