コード例 #1
0
        public override void Constrain(ActorNode node)
        {
            ActorNode target = m_Target as ActorNode;

            if (target == null)
            {
                return;
            }

            Mat2D transformA = m_Parent.WorldTransform;
            Mat2D transformB = new Mat2D(target.WorldTransform);

            if (m_SourceSpace == TransformSpace.Local)
            {
                ActorNode grandParent = target.Parent;
                if (grandParent != null)
                {
                    Mat2D inverse = new Mat2D();
                    if (!Mat2D.Invert(inverse, grandParent.WorldTransform))
                    {
                        return;
                    }
                    Mat2D.Multiply(transformB, inverse, transformB);
                }
            }
            if (m_DestSpace == TransformSpace.Local)
            {
                ActorNode grandParent = m_Parent.Parent;
                if (grandParent != null)
                {
                    Mat2D.Multiply(transformB, grandParent.WorldTransform, transformB);
                }
            }
            Mat2D.Decompose(transformA, m_ComponentsA);
            Mat2D.Decompose(transformB, m_ComponentsB);

            float angleA = m_ComponentsA.Rotation % PI2;
            float angleB = m_ComponentsB.Rotation % PI2;
            float diff   = angleB - angleA;

            if (diff > Math.PI)
            {
                diff -= PI2;
            }
            else if (diff < -Math.PI)
            {
                diff += PI2;
            }

            float ti = 1.0f - m_Strength;

            m_ComponentsB.Rotation = angleA + diff * m_Strength;
            m_ComponentsB.X        = m_ComponentsA.X * ti + m_ComponentsB.X * m_Strength;
            m_ComponentsB.Y        = m_ComponentsA.Y * ti + m_ComponentsB.Y * m_Strength;
            m_ComponentsB.ScaleX   = m_ComponentsA.ScaleX * ti + m_ComponentsB.ScaleX * m_Strength;
            m_ComponentsB.ScaleY   = m_ComponentsA.ScaleY * ti + m_ComponentsB.ScaleY * m_Strength;
            m_ComponentsB.Skew     = m_ComponentsA.Skew * ti + m_ComponentsB.Skew * m_Strength;

            Mat2D.Compose(m_Parent.WorldTransform, m_ComponentsB);
        }
コード例 #2
0
ファイル: MountToActor.cs プロジェクト: forkkit/Nima-Unity
        public void UpdateMount()
        {
            if (m_MountNode == null)
            {
                return;
            }
            //Matrix4x4 world = m_MountTargetObject.transform.localToWorldMatrix;

            Matrix4x4 localParent = Matrix4x4.identity;

            if (gameObject.transform.parent)
            {
                localParent = gameObject.transform.parent.worldToLocalMatrix;
            }
            Matrix4x4 localTransform = localParent * m_ActorGameObject.transform.localToWorldMatrix;
            // m_MountNode

            Mat2D world = m_MountNode.WorldTransform;
            Mat2D m2d   = new Mat2D();

            m2d[0] = localTransform[0, 0];
            m2d[1] = localTransform[1, 0];
            m2d[2] = localTransform[0, 1];
            m2d[3] = localTransform[1, 1];
            m2d[4] = localTransform[0, 3] + world[4] * ActorAsset.NimaToUnityScale * localTransform[0, 0];
            m2d[5] = localTransform[1, 3] + world[5] * ActorAsset.NimaToUnityScale * localTransform[1, 1];


            if (m_InheritRotation && m_InheritScale)
            {
                Vec2D scale = new Vec2D();
                float angle = Mat2D.Decompose(world, scale);
                transform.localEulerAngles = new Vector3(0.0f, 0.0f, angle * Mathf.Rad2Deg);
                transform.localScale       = new Vector3(scale[0] * m_ScaleModifier, scale[1] * m_ScaleModifier, 1.0f);
            }
            else if (m_InheritRotation)
            {
                float angle = (float)Math.Atan2(world[1], world[0]);
                transform.localEulerAngles = new Vector3(0.0f, 0.0f, angle * Mathf.Rad2Deg);
            }
            else if (m_InheritScale)
            {
                Vec2D scale = new Vec2D();
                Mat2D.GetScale(world, scale);
                transform.localScale = new Vector3(scale[0] * m_ScaleModifier, scale[1] * m_ScaleModifier, 1.0f);
            }

            transform.localPosition = new Vector3(m2d[4], m2d[5], transform.localPosition.z);
        }
コード例 #3
0
        public override void UpdateTransform()
        {
            if (m_ActorCollider == null)
            {
                return;
            }
            base.UpdateTransform();

            m_Collider.enabled = m_ActorCollider.IsCollisionEnabled;

            Mat2D world = m_ActorNode.WorldTransform;
            Vec2D scale = new Vec2D();
            float angle = Mat2D.Decompose(world, scale);

            transform.localEulerAngles = new Vector3(0.0f, 0.0f, angle * Mathf.Rad2Deg);
            transform.localScale       = new Vector3(scale[0] * ActorAsset.NimaToUnityScale, scale[1] * ActorAsset.NimaToUnityScale, 1.0f);
            transform.localPosition    = new Vector3(world[4] * ActorAsset.NimaToUnityScale, world[5] * ActorAsset.NimaToUnityScale, 0.0f);
        }
コード例 #4
0
        public override void Constrain(ActorNode node)
        {
            ActorNode target      = m_Target as ActorNode;
            ActorNode grandParent = m_Parent.Parent;

            Mat2D transformA = m_Parent.WorldTransform;
            Mat2D transformB = new Mat2D();

            Mat2D.Decompose(transformA, m_ComponentsA);
            if (target == null)
            {
                Mat2D.Copy(transformB, transformA);
                m_ComponentsB[0] = m_ComponentsA[0];
                m_ComponentsB[1] = m_ComponentsA[1];
                m_ComponentsB[2] = m_ComponentsA[2];
                m_ComponentsB[3] = m_ComponentsA[3];
                m_ComponentsB[4] = m_ComponentsA[4];
                m_ComponentsB[5] = m_ComponentsA[5];
            }
            else
            {
                Mat2D.Copy(transformB, target.WorldTransform);
                if (m_SourceSpace == TransformSpace.Local)
                {
                    ActorNode sourceGrandParent = target.Parent;
                    if (sourceGrandParent != null)
                    {
                        Mat2D inverse = new Mat2D();
                        if (!Mat2D.Invert(inverse, sourceGrandParent.WorldTransform))
                        {
                            return;
                        }
                        Mat2D.Multiply(transformB, inverse, transformB);
                    }
                }
                Mat2D.Decompose(transformB, m_ComponentsB);

                if (!m_Copy)
                {
                    m_ComponentsB.Rotation = m_DestSpace == TransformSpace.Local ? 1.0f : m_ComponentsA.Rotation;
                }
                else
                {
                    m_ComponentsB.Rotation *= m_Scale;
                    if (m_Offset)
                    {
                        m_ComponentsB.Rotation += m_Parent.Rotation;
                    }
                }

                if (m_DestSpace == TransformSpace.Local)
                {
                    // Destination space is in parent transform coordinates.
                    // Recompose the parent local transform and get it in world, then decompose the world for interpolation.
                    if (grandParent != null)
                    {
                        Mat2D.Compose(transformB, m_ComponentsB);
                        Mat2D.Multiply(transformB, grandParent.WorldTransform, transformB);
                        Mat2D.Decompose(transformB, m_ComponentsB);
                    }
                }
            }

            bool clampLocal = m_MinMaxSpace == TransformSpace.Local && grandParent != null;

            if (clampLocal)
            {
                // Apply min max in local space, so transform to local coordinates first.
                Mat2D.Compose(transformB, m_ComponentsB);
                Mat2D inverse = new Mat2D();
                if (!Mat2D.Invert(inverse, grandParent.WorldTransform))
                {
                    return;
                }
                Mat2D.Multiply(transformB, inverse, transformB);
                Mat2D.Decompose(transformB, m_ComponentsB);
            }
            if (m_EnableMax && m_ComponentsB.Rotation > m_Max)
            {
                m_ComponentsB.Rotation = m_Max;
            }
            if (m_EnableMin && m_ComponentsB.Rotation < m_Min)
            {
                m_ComponentsB.Rotation = m_Min;
            }
            if (clampLocal)
            {
                // Transform back to world.
                Mat2D.Compose(transformB, m_ComponentsB);
                Mat2D.Multiply(transformB, grandParent.WorldTransform, transformB);
                Mat2D.Decompose(transformB, m_ComponentsB);
            }

            float angleA = m_ComponentsA.Rotation % PI2;
            float angleB = m_ComponentsB.Rotation % PI2;
            float diff   = angleB - angleA;

            if (diff > Math.PI)
            {
                diff -= PI2;
            }
            else if (diff < -Math.PI)
            {
                diff += PI2;
            }
            float ti = 1.0f - m_Strength;

            m_ComponentsB.Rotation = m_ComponentsA.Rotation + diff * m_Strength;
            m_ComponentsB.X        = m_ComponentsA.X;
            m_ComponentsB.Y        = m_ComponentsA.Y;
            m_ComponentsB.ScaleX   = m_ComponentsA.ScaleX;
            m_ComponentsB.ScaleY   = m_ComponentsA.ScaleY;
            m_ComponentsB.Skew     = m_ComponentsA.Skew;

            Mat2D.Compose(m_Parent.WorldTransform, m_ComponentsB);
        }
コード例 #5
0
        public override void Constrain(ActorNode node)
        {
            ActorNode target = m_Target as ActorNode;

            if (target == null)
            {
                return;
            }
            Vec2D worldTargetTranslation = new Vec2D();

            target.GetWorldTranslation(worldTargetTranslation);

            if (m_InfluencedBones.Length == 0)
            {
                return;
            }

            // Decompose the chain.
            foreach (BoneChain item in m_FKChain)
            {
                ActorBone bone        = item.m_Bone;
                Mat2D     parentWorld = bone.Parent.WorldTransform;
                Mat2D.Invert(item.m_ParentWorldInverse, parentWorld);
                Mat2D.Multiply(bone.Transform, item.m_ParentWorldInverse, bone.WorldTransform);
                Mat2D.Decompose(bone.Transform, item.m_TransformComponents);
            }

            int count = m_BoneData.Count;

            if (count == 1)
            {
                Solve1(m_BoneData[0], worldTargetTranslation);
            }
            else if (count == 2)
            {
                Solve2(m_BoneData[0], m_BoneData[1], worldTargetTranslation);
            }
            else
            {
                BoneChain tip = m_BoneData[count - 1];
                for (int i = 0; i < count - 1; i++)
                {
                    BoneChain item = m_BoneData[i];
                    Solve2(item, tip, worldTargetTranslation);
                    for (int j = item.m_Index + 1; j < m_FKChain.Length - 1; j++)
                    {
                        BoneChain fk = m_FKChain[j];
                        Mat2D.Invert(fk.m_ParentWorldInverse, fk.m_Bone.Parent.WorldTransform);
                    }
                }
            }

            // At the end, mix the FK angle with the IK angle by strength
            if (m_Strength != 1.0)
            {
                foreach (BoneChain fk in m_FKChain)
                {
                    if (!fk.m_Included)
                    {
                        ActorBone bone = fk.m_Bone;
                        Mat2D.Multiply(bone.WorldTransform, bone.Parent.WorldTransform, bone.Transform);
                        continue;
                    }
                    float fromAngle = fk.m_TransformComponents.Rotation % PI2;
                    float toAngle   = fk.m_Angle % PI2;
                    float diff      = toAngle - fromAngle;
                    if (diff > PI)
                    {
                        diff -= PI2;
                    }
                    else if (diff < -PI)
                    {
                        diff += PI2;
                    }
                    float angle = fromAngle + diff * m_Strength;
                    ConstrainRotation(fk, angle);
                }
            }
        }