ios - 如何缩放 SCNNodes 以适应边界框

标签 ios swift 3d scenekit arkit

我正在下载 Collada DAE 场景并在 SceneKit 中渲染它们,但无法让下载的节点“适应”其父节点。我主要关心缩放它的 y 高度以适应父节点。

这是我使用的代码:

// Reset everything
node.position = SCNVector3(0, 0, 0)
node.pivot = SCNMatrix4Identity
node.scale = SCNVector3(1, 1, 1)

// Calculate absolute bounding box
let (min, max) = node.boundingBox
let size = max - min

// Get the biggest dimension of the node
guard let scaleRef = [size.x, size.y, size.z].max() else {
    return
}

// Desired bounding box is of size SCNVector3(0.4, 0.4, 0.4)
let parentSize: Float = 0.4

let ratio = (parentSize/scaleRef)
node.scale = SCNVector3(node.scale.x * ratio, node.scale.y * ratio, node.scale.z * ratio)

//Correctly position the node at the bottom of its parent node by setting pivot
let (minNode, maxNode) = node.boundingBox

let dx = (maxNode.x - minNode.x) / 2
let dy = minNode.y
let dz = (maxNode.z - minNode.z) / 2
node.pivot = SCNMatrix4Translate(node.pivot, dx, dy, dz)

node.position.x = dx * ratio
node.position.y = dy * ratio
node.position.z = dz * ratio

这似乎适用于大多数情况,但我最终得到了一些比例不正确的情况。

例如,此对象正确缩放(Poly Astornaut):

MIN: SCNVector3(x: -1.11969805, y: -0.735845089, z: -4.02169418)
MAX: SCNVector3(x: 1.11969805, y: 0.711179018, z: 0.0)
NEW SCALE: SCNVector3(x: 0.099460572, y: 0.099460572, z: 0.099460572)

这个不是(篮球运动员):

MIN: SCNVector3(x: -74.8805618, y: 0.0459594727, z: -21.4300499)
MAX: SCNVector3(x: 74.8805618, y: 203.553589, z: 15.6760511)
NEW SCALE: SCNVector3(x: 0.00196552835, y: 0.00196552835, z: 0.00196552835)

截图:

正确缩放

Correct image

缩放不正确

Incorrect image

最佳答案

所以我最终做的有点不同,因为我想将我的 Assets 精确扩展到引用大小。

  1. 在我的 .scn 文件中,转到“节点检查器”选项卡并查看我正在使用的 Assets 的边界框:

Bounding Box as listed in Scene graph, node inspector tab

  1. 了解引用图片的尺寸。这是你应该在现实世界中衡量的东西,并将其输入到你的 Assets.xcassets 资源中

reference image size

  1. 此引用图像大小在 func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) 函数中传递给您。我通过以下代码访问我的:

guard 让 imageAnchor = anchor as? ARImageAnchor else { 返回 } 让 referenceImage = imageAnchor.referenceImage 打印(referenceImage.physicalSize.width) 打印(referenceImage.physicalSize.height)

  1. 无论您想缩放到哪里,您只需使用代数将边界框大小缩放到所需的大小。所以我们的规模很简单

让 threeDimensionalAssetToRealReferenceImageScale = referenceImageWidth/threeDimensionalAssetBoundingBoxWidth

  1. 在您的 SCNNode 上调用 scale

我写了这个,因为我对这种情况很困惑,我希望它能帮助别人。

关于ios - 如何缩放 SCNNodes 以适应边界框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48913192/

相关文章:

ios - UITabBarItem 图像颜色在第一次被选中后变为蓝色

javascript - 在直线上移动网格 三个 JS

ios - 是否有可能在 iOS 中强制 UI 自动旋转?

ios - 从 View 中的 UITableView 中的 xib 文件加载 UITableViewCell

android - 从 Sencha Touch 访问 native API/系统

swift - 具有动态 backgroundColor 的 Xcode 静态单元格

python - 绘制几个 3D 半空间的交集?

3d - webGL drawElementsInstancedANGLE 与实例化数组上的起始偏移量

ios - UIView不覆盖状态栏区域

ios - 无法在 IBM Worklight 应用程序中向 iOS 设备发送推送通知