在不改变节点位置的情况下将 SCNNode 的枢轴设置为边界体积中心 [英] set pivot of SCNNode to bounding volume center without changing the node's position

查看:35
本文介绍了在不改变节点位置的情况下将 SCNNode 的枢轴设置为边界体积中心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 SCNVector3 中心;CGFloat 半径;[节点 getBoundingSphereCenter:&center radius:&radius];

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

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

我怎样才能抵消这种运动 - 分别.如何只更改节点的枢轴而不影响其在空间中的位置?或者有没有办法(不使用额外的空节点)在 Interface Builder 中做到这一点?

解决方案

这里也有人问了同样的问题

 func centerPivotWithOutMoving(for node: SCNNode) ->SCN节点{让 initialPos = activeNode.presentation.positionvar min = SCNVector3Zerovar max = SCNVector3Zeronode.__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)让正确X = Float(min.x + (max.x - min.x)/2)让正确Y = Float(min.y + (max.y - min.y)/2)让正确Z = Float(min.z + (max.z - min.z)/2)如果 node.convertVector(SCNVector3(0,0,1), from: parentNode).z <0 {//如果蓝色局部 z 轴指向下方node.position = SCNVector3(initialPos.x - CorrectX, initialPos.y - CorrectY, initialPos.z - CorrectZ)} 别的 {//如果蓝色局部 z 轴指向上方node.position = SCNVector3(initialPos.x + CorrectX, initialPos.y + CorrectY, initialPos.z + CorrectZ)}返回节点}

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

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

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

I am looking for a way to set the pivot of SCNNodes (obtained from importing Collada files) to their centroid (or the center of their bounding box. I get the center with

 SCNVector3 center;
CGFloat radius;
[node getBoundingSphereCenter:&center radius:&radius];

However, when I try to set the node's pivot (which is a 4D vector as opposed to the 3D vector of the center) to the center, the node's position also changes.

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

How can I offset this movement - resp. how can I only change the node's pivot without affecting its position in space? Or is there even a way (without using additional empty nodes) to do it in Interface Builder?

解决方案

The same question was also asked here Is it normal for an SCNNode pivot to change the nodes position? ... but after searching online for hours I couldn't find any coded solution to this problem. Which is how does one center the pivot of a node without moving the node.

So in the end I spend most of today working on this coded answer below. What I found was that the orientation of the local axis determines whether you subtract or do an addition for the correction factor.

Take this bike below. The right-hand pedal crank pivot z-axis (blue) is pointing upwards, whilst in the other photo, left-hand pedal crank pivot z-axis (blue) is pointing downwards. That reason these axis is different is when the person was drawing the bike model in SketchUp, they just copied and flipped the first pedal crank to the opposite side. So unfortunately, its very common to get imported DAE models with ad-hoc pivot orientation and positions!

 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
}

I've only tested the code above on the two different z-axis orientations shown above, the complete code would also have to deal with x, y axis using these two conditions.

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

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

If there is a better way to do this... please share?

这篇关于在不改变节点位置的情况下将 SCNNode 的枢轴设置为边界体积中心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆