【问题标题】:How to scale SCNNodes to fit within a bounding box如何缩放 SCNNodes 以适应边界框
【发布时间】:2018-08-01 11:08:07
【问题描述】:

我正在下载 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)

截图:

正确缩放

缩放比例不正确

【问题讨论】:

  • 很难在没有看到更多发生的情况下判断出了什么问题。 (也许只是篮球运动员的个子往往很高......?)一种猜测是您将新的比例因子乘以节点的现有比例,这可能不是从 1.0 开始。
  • @rickster 哈,你不是第一个建议它按预期工作的人,因为篮球运动员很高 :) 我更新了代码 sn-p 以包含更多细节。如果您有任何想法,请告诉我!这个让我发疯,我觉得我一定错过了一些明显的东西。
  • 你介意分享那个不正确的模型吗?
  • @JurajAntas 这是尺寸不正确的篮球运动员:3d.cdn.gometa.io/ea4ba1fb-5d79-42f6-8b75-e2c39c66bad5.zip 和正确尺寸的宇航员:3d.cdn.gometa.io/4ceb2bf3-078a-47bd-a0d5-f06e6c1cf011.zip
  • 谢谢。我看了看。不同的是模型内部的转换。我会建议您不要使用模型节点的比例,而是使用模型中存储的相机。无需缩放,您可以将相机移动到您想要的位置。 (甚至可能在 xcode 中),而不是使用该相机参数来显示模型。

标签: ios swift 3d scenekit arkit


【解决方案1】:

所以我最终做的有点不同,因为我想将我的资产精确地缩放到参考大小。

  1. 在我的 .scn 文件中,转到 Node Inspector 选项卡并查看我正在使用的资产的边界框:

  1. 了解参考图像的大小。这是您应该在现实世界中衡量的东西,并将其输入到您的 Assets.xcassets 资源中

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

guard let imageAnchor = anchor as? ARImageAnchor else { return } let referenceImage = imageAnchor.referenceImage print(referenceImage.physicalSize.width) print(referenceImage.physicalSize.height)

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

let threeDimensionalAssetToRealReferenceImageScale = referenceImageWidth / threeDimensionalAssetBoundingBoxWidth

  1. 在您的SCNNode 上致电scale

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

【讨论】:

    猜你喜欢
    • 2012-04-17
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-26
    • 2019-07-24
    • 1970-01-01
    相关资源
    最近更新 更多