gpt4 book ai didi

ios - ARKit - 如何在 SceneKit 编辑器中使用节点中心设置操纵器位置

转载 作者:搜寻专家 更新时间:2023-10-30 22:14:42 26 4
gpt4 key购买 nike

我从 Sketchfab 下载了两个不同的 3D 模型。我在 ARKit 3D 对象放置中导入了两个模型。放置 3D 模型时,节点未与其中一个模型的操纵器正确对齐。我附上了截图。 enter image description here

左侧是所选节点(视口(viewport))和操纵器正确对齐的位置。但是右侧选定的节点(视口(viewport))和操纵器没有正确对齐。我如何使节点和操纵器像左侧 3D 模型一样对齐到中心。请指导我。谢谢

@乔希·罗宾斯

我已经尝试了您的代码,但我仍然遇到同样的问题。

box.firstMaterial?.emission.contents = UIColor.green

box.firstMaterial?.shaderModifiers = [SCNShaderModifierEntryPoint.surface: sm]

box.firstMaterial?.isDoubleSided = true
let boxNode = SCNNode(geometry: box)
boxNode.position = SCNVector3(node.position.x,(node.position.y + Float((proheights * 0.0234)/2)),node.position.z)

let minimum = float3(treenode.boundingBox.min)
let maximum = float3(treenode.boundingBox.max)

let translation = (maximum - minimum) * 0.5

//3. Set The Pivot
treenode.pivot = SCNMatrix4MakeTranslation(translation.x, translation.y, translation.z)
boxNode.pivot = SCNMatrix4MakeTranslation(translation.x, translation.y, translation.z)

self.addChildNode(boxNode)

enter image description here

更新代码

let treenode = SCNNode()
let box = SCNBox(width: (prowidths * 0.0234), height: (proheights * 0.0234), length: (prolenght * 0.0234), chamferRadius: 0)

box.firstMaterial?.emission.contents = UIColor.green

box.firstMaterial?.shaderModifiers = [SCNShaderModifierEntryPoint.surface: sm]

box.firstMaterial?.isDoubleSided = true
let boxNode = SCNNode(geometry: box)
boxNode.position = SCNVector3(treenode.position.x,(treenode.position.y + Float((proheights * 0.0234)/2)),treenode.position.z)

let minimum = float3(treenode.boundingBox.min)
let maximum = float3(treenode.boundingBox.max)

let translation = (maximum - minimum) * 0.5

//3. Set The Pivot
treenode.pivot = SCNMatrix4MakeTranslation(translation.x, translation.y, translation.z)
boxNode.pivot = SCNMatrix4MakeTranslation(translation.x, translation.y, translation.z)

self.addChildNode(boxNode)

self.addChildNode(treenode)
return treenode

最佳答案

这似乎是一个热门问题。几分钟前我刚刚回答了一个类似的问题。查看下面的此功能是否有助于在不移动其位置的情况下将节点的枢轴居中。

set pivot of SCNNode to bounding volume center without changing the node's position

 func centerPivotWithOutMoving(for node: SCNNode) -> SCNNode {

let initialPos = treenode.presentation.position

var min = SCNVector3Zero
var max = SCNVector3Zero
node.__getBoundingBoxMin(&min, max: &max)

node.pivot = SCNMatrix4MakeTranslation(
min.x + (max.x - min.x)/2,
min.y + (max.y - min.y)/2,
min.z + (max.z - min.z)/2
)
let correctX = Float(min.x + (max.x - min.x)/2)
let correctY = Float(min.y + (max.y - min.y)/2)
let correctZ = Float(min.z + (max.z - min.z)/2)

if node.convertVector(SCNVector3(0,0,1), from: parentNode).z < 0 {
// if blue local z-axis is pointing downwards
node.position = SCNVector3(initialPos.x - correctX, initialPos.y - correctY, initialPos.z - correctZ)
} else {
// if blue local z-axis is pointing upwards
node.position = SCNVector3(initialPos.x + correctX, initialPos.y + correctY, initialPos.z + correctZ)
}

return node
}

要使用上面的函数,请执行以下操作:

 centerPivotWithOutMoving(for: treenode)

编辑: 我意识到我上面的方法并不是解决所有情况下的 centerPivotWithOutMoving 的最有效方法,因为在某些情况下,局部轴您尝试将枢轴居中的子节点可能与 ParentNode 轴不共面(局部轴和父轴共享同一平面)。一个更好的方法是在每个你想要将枢轴居中的节点周围放置一个 wrapperNode。

当轴不共面时,类似这样的东西将包裹每个节点以解决潜在问题。

    for child in (self.parentNode?.childNodes)! {
let wrapperNode = SCNNode()
child.geometry?.firstMaterial?.lightingModel = .physicallyBased
wrapperNode.addChildNode(child)
wrapperNode.name = child.name! + "_wrapper"
self.parentNode.addChildNode(wrapperNode)
}

我暂时这样做是为了在进入场景时在所有子节点上调用 CenerPivotWithOutMoving。

 for child in parentNode.childNodes {
let delayInSeconds = Double(0.1)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + delayInSeconds) {
self.centerPivotWithOutMoving(for: child)
}

}

这里是修改后的 centerPivotWithOutMoving,添加了一些代码,用于针对父级测试局部轴,只是为了显示它们现在对于所有包装器节点都是 1,1,1。如果没有包装器节点,这些数字在大多数情况下永远不会是 1、1、1。

  func centerPivot(for node: SCNNode) -> SCNNode {
var min = SCNVector3Zero
var max = SCNVector3Zero
node.__getBoundingBoxMin(&min, max: &max)
node.pivot = SCNMatrix4MakeTranslation(
min.x + (max.x - min.x)/2,
min.y + (max.y - min.y)/2,
min.z + (max.z - min.z)/2
)
return node
}



func centerPivotWithOutMoving(for node: SCNNode) -> SCNNode {

let initialPos = node.presentation.position

var min = SCNVector3Zero
var max = SCNVector3Zero
node.__getBoundingBoxMin(&min, max: &max)

// corrective factor for each axis
let correctX = Float(min.x + (max.x - min.x)/2)
let correctY = Float(min.y + (max.y - min.y)/2)
let correctZ = Float(min.z + (max.z - min.z)/2)

var xAxis = node.convertVector(SCNVector3(1,0,0), from: parentNode).x
var yAxis = node.convertVector(SCNVector3(0,1,0), from: parentNode).y
var zAxis = node.convertVector(SCNVector3(0,0,1), from: parentNode).z

// check the local axis is coplanar with parentNode axis
if (xAxis == 1) && (yAxis == 1) && (zAxis == 1) {
print(node.name)
centerPivot(for: node)
node.position = SCNVector3(initialPos.x + correctX, initialPos.y + correctY, initialPos.z + correctZ)
} else {
print("node axis is not coplanar with parent")
}

return node
}

关于ios - ARKit - 如何在 SceneKit 编辑器中使用节点中心设置操纵器位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49129325/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com