将SCNNode的枢轴设置为限制体积中心而不更改节点的位置

时间:2016-07-15 08:22:22

标签: ios objective-c scenekit

我正在寻找一种方法来设置SCNNodes的枢轴(从导入Collada文件获得)到它们的质心(或它们的边界框的中心)。 我得到了

的中心
 SCNVector3 center;
CGFloat radius;
[node getBoundingSphereCenter:&center radius:&radius];

但是,当我尝试将节点的枢轴(这是一个4D矢量而不是中心的3D矢量)设置到中心时,节点的位置也会发生变化。

node.pivot = SCNMatrix4MakeTranslation(center.x,center.y,center.z);

我怎样才能抵消这种运动 - 再说一遍。我怎样才能改变节点的枢轴而不影响它在太空中的位置? 或者甚至有一种方法(不使用额外的空节点)在Interface Builder中执行它?

2 个答案:

答案 0 :(得分:3)

枢轴不仅是旋转中心,它还是节点的位置参考点。重置枢轴时,枢轴相对于父对象的位置保持固定。实际上,您是相对于对象的当前位置移动几何体。

简单的解决方法是使用用于重置枢轴的负值重新定位节点。如果由于某种原因,您需要一个不允许这样的特定值,请将您的节点放在容器节点中,并使用容器节点作为位置,并使用重新旋转的节点进行轮换。

答案 1 :(得分:1)

同样的问题也在这里被问到Is it normal for an SCNNode pivot to change the nodes position? ...但是在网上搜索了几个小时后,我找不到任何解决这个问题的编码方法。哪个如何在不移动节点的情况下将节点的枢轴居中

所以最后我今天花了大部分时间来处理这个编码的答案。 我发现局部轴的方向决定了你是否减去或者为校正因子做了一个加法。

在下面骑这辆自行车。右侧踏板曲柄枢轴z轴(蓝色)指向上方,而在另一张照片中,左侧踏板曲柄枢轴z轴(蓝色)指向下方。因为这个轴不同的原因是当人们在SketchUp中绘制自行车模型时,他们只是将第一个踏板曲柄复制并翻转到另一侧。不幸的是,它非常普遍,可以通过ad-hoc枢轴定位和位置获得进口DAE模型!

enter image description here

enter image description here

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

    let initialPos = activeNode.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
}

我只是在上面显示的两个不同的z轴方向上测试了上面的代码,完整的代码也必须使用这两个条件来处理x,y轴。

  node.convertVector(SCNVector3(0,1,0), from: parentNode).z < 0

  node.convertVector(SCNVector3(1,0,0), from: parentNode).z < 0   

如果有更好的方法可以做到这一点...请分享?