统一。关节角度限制意味着什么?

时间:2017-04-05 09:08:58

标签: unity3d

我需要限制ConfigurableJoint的目标旋转,以避免扭曲或破坏关节。

为了了解角度限制是如何工作的,我已经做了一个实验。

  1. 在场景中放置一个人形模型。
  2. ConfigurableJoint添加到骨骼中;
  3. 通过欧拉角添加脚本来控制targetRotation属性。

    using UnityEngine;
    
    public class TestLimits : MonoBehaviour
    {
        [Range(-120, 120)]
        public float x;
        [Range(-120, 120)]
        public float y;
        [Range(-120, 120)]
        public float z;
        public Vector3 currentTorque; // to indicate limits
    
        private ConfigurableJoint j;
    
        void Start()
        {
            j = GetComponent<ConfigurableJoint>();
        }
    
        void Update()
        {
            j.targetRotation = Quaternion.Euler(x, y, z);
            currentTorque = j.currentTorque;
        }
    }
    
  4. 更改targetRotation我们可以看到联合动作的限制。

    正如所料,当角度达到极限值时,会观察到限制。但不总是。只有当其他两个角度等于零时才会发生。例如,如果  x = 91且y = 89,观察到z-限制在增加方向上的变化。

    这是什么意思? 如何限制目标旋转?

1 个答案:

答案 0 :(得分:1)

我在Phisx documentation.

中找到了答案
  

球形关节支持锥形极限,该极限限制两个约束框架的X轴之间的角度。 Actor1的X轴受到极限锥的约束,极限锥的轴是actor0约束帧的x轴。允许的极限值是该框架的y轴和z轴周围的最大旋转。可以指定y轴和z轴的不同值,在这种情况下,极限采用椭圆角锥的形式。

  1. y轴和z轴都是Actor0的轴。所以我们不能使用欧拉角。
  2. 极限是椭圆角锥。因此,y和z角由不等式y 2 / a 2 + z 2 / b 2 &lt; 1.这里a和b是限制。
  3. 然后看起来角锥相对于actor0绕扭转轴旋转。
  4. 此功能将旋转精确限制为关节限制。

    private Quaternion targetRotation(ConfigurableJoint j, float x, float y, float z)
    {
        // twist
        float angle = x;
        Vector3 axis = Vector3.right;
    
        if (angle > j.highAngularXLimit.limit)
            angle = j.highAngularXLimit.limit;
        if (angle < j.lowAngularXLimit.limit)
            angle = j.lowAngularXLimit.limit;
        Quaternion twist = Quaternion.AngleAxis(angle, axis);
    
        // swing
        angle = Mathf.Sqrt(y * y + z * z);
        axis = new Vector3(0, y, z);
    
        Vector3 t = twist * axis;
        float a = t.y / j.angularYLimit.limit;
        float b = t.z / j.angularZLimit.limit;
        float l = a * a + b * b;
        if (l > 1)
            angle = angle / Mathf.Sqrt(l);
    
        Quaternion swing = Quaternion.AngleAxis(angle, axis);
    
        return twist * swing;
    }