Example #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);
        }
Example #2
0
 public void TransformBind(Mat2D xform)
 {
     if (m_BoneConnections != null)
     {
         foreach (BoneConnection bc in m_BoneConnections)
         {
             Mat2D.Multiply(bc.m_Bind, xform, bc.m_Bind);
             Mat2D.Invert(bc.m_InverseBind, bc.m_Bind);
         }
     }
 }
Example #3
0
        public static ActorImage Read(Actor actor, BinaryReader reader, ActorImage node = null)
        {
            if (node == null)
            {
                node = new ActorImage();
            }

            ActorNode.Read(actor, reader, node);

            bool isVisible = reader.ReadByte() != 0;

            if (isVisible)
            {
                node.m_BlendMode    = (BlendModes)reader.ReadByte();
                node.m_DrawOrder    = (int)reader.ReadUInt16();
                node.m_TextureIndex = (int)reader.ReadByte();

                int numConnectedBones = (int)reader.ReadByte();
                if (numConnectedBones != 0)
                {
                    node.m_BoneConnections = new BoneConnection[numConnectedBones];

                    for (int i = 0; i < numConnectedBones; i++)
                    {
                        BoneConnection bc = new BoneConnection();
                        bc.m_BoneIdx = reader.ReadUInt16();
                        Actor.ReadFloat32Array(reader, bc.m_Bind.Values);
                        Mat2D.Invert(bc.m_InverseBind, bc.m_Bind);

                        node.m_BoneConnections[i] = bc;
                    }

                    Mat2D worldOverride = new Mat2D();
                    Actor.ReadFloat32Array(reader, worldOverride.Values);
                    node.WorldTransformOverride = worldOverride;
                }

                uint numVertices  = reader.ReadUInt32();
                int  vertexStride = numConnectedBones > 0 ? 12 : 4;
                node.m_VertexCount = (int)numVertices;
                node.m_Vertices    = new float[numVertices * vertexStride];
                Actor.ReadFloat32Array(reader, node.m_Vertices);

                uint numTris = reader.ReadUInt32();
                node.m_Triangles     = new ushort[numTris * 3];
                node.m_TriangleCount = (int)numTris;
                Actor.ReadUInt16Array(reader, node.m_Triangles);
            }

            return(node);
        }
Example #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);
        }
Example #5
0
        public override void Update(byte dirt)
        {
            ActorBone      bone            = m_Parent as ActorBone;
            ActorBone      parentBone      = bone.Parent as ActorBone;
            JellyComponent parentBoneJelly = parentBone == null ? null : parentBone.m_Jelly;

            Mat2D inverseWorld = new Mat2D();

            if (!Mat2D.Invert(inverseWorld, bone.WorldTransform))
            {
                return;
            }

            if (m_InTarget != null)
            {
                Vec2D translation = m_InTarget.GetWorldTranslation(new Vec2D());
                Vec2D.TransformMat2D(m_InPoint, translation, inverseWorld);
                Vec2D.Normalize(m_InDirection, m_InPoint);
            }
            else if (parentBone != null)
            {
                if (parentBone.FirstBone == bone && parentBoneJelly != null && parentBoneJelly.m_OutTarget != null)
                {
                    Vec2D translation    = parentBoneJelly.m_OutTarget.GetWorldTranslation(new Vec2D());
                    Vec2D localParentOut = Vec2D.TransformMat2D(new Vec2D(), translation, inverseWorld);
                    Vec2D.Normalize(localParentOut, localParentOut);
                    Vec2D.Negate(m_InDirection, localParentOut);
                }
                else
                {
                    Vec2D d1 = new Vec2D(1.0f, 0.0f);
                    Vec2D d2 = new Vec2D(1.0f, 0.0f);

                    Vec2D.TransformMat2(d1, d1, parentBone.WorldTransform);
                    Vec2D.TransformMat2(d2, d2, bone.WorldTransform);

                    Vec2D sum = Vec2D.Add(new Vec2D(), d1, d2);
                    Vec2D.TransformMat2(m_InDirection, sum, inverseWorld);
                    Vec2D.Normalize(m_InDirection, m_InDirection);
                }
                m_InPoint[0] = m_InDirection[0] * m_EaseIn * bone.Length * CurveConstant;
                m_InPoint[1] = m_InDirection[1] * m_EaseIn * bone.Length * CurveConstant;
            }
            else
            {
                m_InDirection[0] = 1.0f;
                m_InDirection[1] = 0.0f;
                m_InPoint[0]     = m_InDirection[0] * m_EaseIn * bone.Length * CurveConstant;
            }

            if (m_OutTarget != null)
            {
                Vec2D translation = m_OutTarget.GetWorldTranslation(new Vec2D());
                Vec2D.TransformMat2D(m_OutPoint, translation, inverseWorld);
                Vec2D tip = new Vec2D(bone.Length, 0.0f);
                Vec2D.Subtract(m_OutDirection, m_OutPoint, tip);
                Vec2D.Normalize(m_OutDirection, m_OutDirection);
            }
            else if (bone.FirstBone != null)
            {
                ActorBone      firstBone      = bone.FirstBone;
                JellyComponent firstBoneJelly = firstBone.m_Jelly;
                if (firstBoneJelly != null && firstBoneJelly.m_InTarget != null)
                {
                    Vec2D translation     = firstBoneJelly.m_InTarget.GetWorldTranslation(new Vec2D());
                    Vec2D worldChildInDir = Vec2D.Subtract(new Vec2D(), firstBone.GetWorldTranslation(new Vec2D()), translation);
                    Vec2D.TransformMat2(m_OutDirection, worldChildInDir, inverseWorld);
                }
                else
                {
                    Vec2D d1 = new Vec2D(1.0f, 0.0f);
                    Vec2D d2 = new Vec2D(1.0f, 0.0f);

                    Vec2D.TransformMat2(d1, d1, firstBone.WorldTransform);
                    Vec2D.TransformMat2(d2, d2, bone.WorldTransform);

                    Vec2D sum = Vec2D.Add(new Vec2D(), d1, d2);
                    Vec2D.Negate(sum, sum);
                    Vec2D.TransformMat2(m_OutDirection, sum, inverseWorld);
                    Vec2D.Normalize(m_OutDirection, m_OutDirection);
                }
                Vec2D.Normalize(m_OutDirection, m_OutDirection);
                Vec2D scaledOut = Vec2D.Scale(new Vec2D(), m_OutDirection, m_EaseOut * bone.Length * CurveConstant);
                m_OutPoint[0] = bone.Length;
                m_OutPoint[1] = 0.0f;
                Vec2D.Add(m_OutPoint, m_OutPoint, scaledOut);
            }
            else
            {
                m_OutDirection[0] = -1.0f;
                m_OutDirection[1] = 0.0f;

                Vec2D scaledOut = Vec2D.Scale(new Vec2D(), m_OutDirection, m_EaseOut * bone.Length * CurveConstant);
                m_OutPoint[0] = bone.Length;
                m_OutPoint[1] = 0.0f;
                Vec2D.Add(m_OutPoint, m_OutPoint, scaledOut);
            }

            UpdateJellies();
        }
Example #6
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);
                }
            }
        }
Example #7
0
        public override void Constrain(ActorNode node)
        {
            ActorNode target      = m_Target as ActorNode;
            ActorNode grandParent = m_Parent.Parent;

            Mat2D transformA   = m_Parent.WorldTransform;
            Vec2D translationA = new Vec2D(transformA[4], transformA[5]);
            Vec2D translationB = new Vec2D();

            if (target == null)
            {
                Vec2D.Copy(translationB, translationA);
            }
            else
            {
                Mat2D transformB = new Mat2D(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);
                    }
                }
                translationB[0] = transformB[4];
                translationB[1] = transformB[5];

                if (!m_CopyX)
                {
                    translationB[0] = m_DestSpace == TransformSpace.Local ? 0.0f : translationA[0];
                }
                else
                {
                    translationB[0] *= m_ScaleX;
                    if (m_Offset)
                    {
                        translationB[0] += m_Parent.X;
                    }
                }

                if (!m_CopyY)
                {
                    translationB[1] = m_DestSpace == TransformSpace.Local ? 0.0f : translationA[1];
                }
                else
                {
                    translationB[1] *= m_ScaleY;

                    if (m_Offset)
                    {
                        translationB[1] += m_Parent.Y;
                    }
                }

                if (m_DestSpace == TransformSpace.Local)
                {
                    // Destination space is in parent transform coordinates.
                    if (grandParent != null)
                    {
                        Vec2D.TransformMat2D(translationB, translationB, grandParent.WorldTransform);
                    }
                }
            }

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

            if (clampLocal)
            {
                // Apply min max in local space, so transform to local coordinates first.
                Mat2D invert = new Mat2D();
                if (!Mat2D.Invert(invert, grandParent.WorldTransform))
                {
                    return;
                }
                // Get our target world coordinates in parent local.
                Vec2D.TransformMat2D(translationB, translationB, invert);
            }
            if (m_EnableMaxX && translationB[0] > m_MaxX)
            {
                translationB[0] = m_MaxX;
            }
            if (m_EnableMinX && translationB[0] < m_MinX)
            {
                translationB[0] = m_MinX;
            }
            if (m_EnableMaxY && translationB[1] > m_MaxY)
            {
                translationB[1] = m_MaxY;
            }
            if (m_EnableMinY && translationB[1] < m_MinY)
            {
                translationB[1] = m_MinY;
            }
            if (clampLocal)
            {
                // Transform back to world.
                Vec2D.TransformMat2D(translationB, translationB, grandParent.WorldTransform);
            }

            float ti = 1.0f - m_Strength;

            // Just interpolate world translation
            transformA[4] = translationA[0] * ti + translationB[0] * m_Strength;
            transformA[5] = translationA[1] * ti + translationB[1] * m_Strength;
        }