예제 #1
0
        protected void GenerateFrame(int indexNumber, AnimationFrame[] resKeyFrames, ShapeElement[] elements, Dictionary <int, AnimationJoint> jointsById, float[] modelMatrix, List <ElementPose> transforms, bool recursive = true)
        {
            int frameNumber = resKeyFrames[indexNumber].FrameNumber;

            for (int i = 0; i < elements.Length; i++)
            {
                ShapeElement element = elements[i];

                ElementPose animTransform = new ElementPose();
                animTransform.ForElement = element;

                GenerateFrameForElement(frameNumber, element, ref animTransform);
                transforms.Add(animTransform);

                float[] animModelMatrix = Mat4f.CloneIt(modelMatrix);
                Mat4f.Mul(animModelMatrix, animModelMatrix, element.GetLocalTransformMatrix(null, animTransform));

                if (element.JointId > 0 && !jointsDone.Contains(element.JointId))
                {
                    resKeyFrames[indexNumber].SetTransform(element.JointId, animModelMatrix);
                    jointsDone.Add(element.JointId);
                }

                if (recursive && element.Children != null)
                {
                    GenerateFrame(indexNumber, resKeyFrames, element.Children, jointsById, animModelMatrix, animTransform.ChildElementPoses);
                }
            }
        }
예제 #2
0
        public void Add(ElementPose tf, ElementPose tfNext, float l, float weight)
        {
            if (tf.RotShortestDistance)
            {
                float distX = MathTools.GameMath.AngleDegDistance(tf.degX, tfNext.degX);
                float distY = MathTools.GameMath.AngleDegDistance(tf.degY, tfNext.degY);
                float distZ = MathTools.GameMath.AngleDegDistance(tf.degZ, tfNext.degZ);

                degX += (tf.degX + distX * l) * weight;
                degY += (tf.degY + distY * l) * weight;
                degZ += (tf.degZ + distZ * l) * weight;
            }
            else
            {
                degX += (tf.degX * (1 - l) + tfNext.degX * l) * weight;
                degY += (tf.degY * (1 - l) + tfNext.degY * l) * weight;
                degZ += (tf.degZ * (1 - l) + tfNext.degZ * l) * weight;
            }

            scaleX     += ((tf.scaleX - 1) * (1 - l) + (tfNext.scaleX - 1) * l) * weight;
            scaleY     += ((tf.scaleY - 1) * (1 - l) + (tfNext.scaleY - 1) * l) * weight;
            scaleZ     += ((tf.scaleZ - 1) * (1 - l) + (tfNext.scaleZ - 1) * l) * weight;
            translateX += (tf.translateX * (1 - l) + tfNext.translateX * l) * weight;
            translateY += (tf.translateY * (1 - l) + tfNext.translateY * l) * weight;
            translateZ += (tf.translateZ * (1 - l) + tfNext.translateZ * l) * weight;
        }
예제 #3
0
        protected override void LoadPosesAndAttachmentPoints(ShapeElement[] elements, List <ElementPose> intoPoses)
        {
            // Only load root pose and only the ones that have attachment points
            if (loadFully)
            {
                base.LoadPosesAndAttachmentPoints(elements, intoPoses);
                return;
            }

            ElementPose pose;

            for (int i = 0; i < elements.Length; i++)
            {
                ShapeElement elem = elements[i];
                if (elem.AttachmentPoints == null)
                {
                    continue;
                }

                intoPoses.Add(pose   = new ElementPose());
                pose.AnimModelMatrix = Mat4f.Create();
                pose.ForElement      = elem;

                for (int j = 0; j < elem.AttachmentPoints.Length; j++)
                {
                    AttachmentPoint apoint = elem.AttachmentPoints[j];
                    AttachmentPointByCode[apoint.Code] = new AttachmentPointAndPose()
                    {
                        AttachPoint = apoint,
                        CachedPose  = pose
                    };
                }
            }
        }
예제 #4
0
        protected virtual void LoadPosesAndAttachmentPoints(ShapeElement[] elements, List <ElementPose> intoPoses)
        {
            ElementPose pose;

            for (int i = 0; i < elements.Length; i++)
            {
                ShapeElement elem = elements[i];

                intoPoses.Add(pose   = new ElementPose());
                pose.AnimModelMatrix = Mat4f.Create();
                pose.ForElement      = elem;

                if (elem.AttachmentPoints != null)
                {
                    for (int j = 0; j < elem.AttachmentPoints.Length; j++)
                    {
                        AttachmentPoint apoint = elem.AttachmentPoints[j];
                        AttachmentPointByCode[apoint.Code] = new AttachmentPointAndPose()
                        {
                            AttachPoint = apoint,
                            CachedPose  = pose
                        };
                    }
                }

                if (elem.Children != null)
                {
                    pose.ChildElementPoses = new List <ElementPose>(elem.Children.Length);
                    LoadPosesAndAttachmentPoints(elem.Children, pose.ChildElementPoses);
                }
            }
        }
예제 #5
0
        protected virtual void LoadAttachmentPoints(List <ElementPose> cachedPoses)
        {
            for (int i = 0; i < cachedPoses.Count; i++)
            {
                ElementPose elem = cachedPoses[i];

                if (elem.ForElement.AttachmentPoints != null)
                {
                    for (int j = 0; j < elem.ForElement.AttachmentPoints.Length; j++)
                    {
                        AttachmentPoint apoint = elem.ForElement.AttachmentPoints[j];
                        AttachmentPointByCode[apoint.Code] = new AttachmentPointAndPose()
                        {
                            AttachPoint = apoint,
                            CachedPose  = elem
                        };
                    }
                }

                if (elem.ChildElementPoses != null)
                {
                    LoadAttachmentPoints(elem.ChildElementPoses);
                }
            }
        }
예제 #6
0
 public void Add(ElementPose tf, ElementPose tfNext, float l, float weight)
 {
     degX       += (tf.degX * (1 - l) + tfNext.degX * l) * weight;
     degY       += (tf.degY * (1 - l) + tfNext.degY * l) * weight;
     degZ       += (tf.degZ * (1 - l) + tfNext.degZ * l) * weight;
     scaleX     += ((tf.scaleX - 1) * (1 - l) + (tfNext.scaleX - 1) * l) * weight;
     scaleY     += ((tf.scaleY - 1) * (1 - l) + (tfNext.scaleY - 1) * l) * weight;
     scaleZ     += ((tf.scaleZ - 1) * (1 - l) + (tfNext.scaleZ - 1) * l) * weight;
     translateX += (tf.translateX * (1 - l) + tfNext.translateX * l) * weight;
     translateY += (tf.translateY * (1 - l) + tfNext.translateY * l) * weight;
     translateZ += (tf.translateZ * (1 - l) + tfNext.translateZ * l) * weight;
 }
예제 #7
0
        public float[] GetLocalTransformMatrix(float[] output = null, ElementPose tf = null)
        {
            if (tf == null)
            {
                tf = noTransform;
            }

            ShapeElement elem = this;

            if (output == null)
            {
                output = Mat4f.Create();
            }

            float[] origin = new float[] { 0f, 0f, 0f };

            if (elem.RotationOrigin != null)
            {
                origin[0] = (float)elem.RotationOrigin[0] / 16;
                origin[1] = (float)elem.RotationOrigin[1] / 16;
                origin[2] = (float)elem.RotationOrigin[2] / 16;
            }

            Mat4f.Translate(output, output, origin);

            if (elem.RotationX + tf.degX != 0)
            {
                Mat4f.RotateX(output, output, (float)(elem.RotationX + tf.degX) * GameMath.DEG2RAD);
            }
            if (elem.RotationY + tf.degY != 0)
            {
                Mat4f.RotateY(output, output, (float)(elem.RotationY + tf.degY) * GameMath.DEG2RAD);
            }
            if (elem.RotationZ + tf.degZ != 0)
            {
                Mat4f.RotateZ(output, output, (float)(elem.RotationZ + tf.degZ) * GameMath.DEG2RAD);
            }

            Mat4f.Scale(output, output, new float[] { (float)elem.ScaleX * tf.scaleX, (float)elem.ScaleY * tf.scaleY, (float)elem.ScaleZ * tf.scaleZ });

            Mat4f.Translate(output, output, new float[] { -origin[0], -origin[1], -origin[2] });

            Mat4f.Translate(output, output, new float[] {
                (float)elem.From[0] / 16 + tf.translateX,
                (float)elem.From[1] / 16 + tf.translateY,
                (float)elem.From[2] / 16 + tf.translateZ
            });



            return(output);
        }
예제 #8
0
        protected void lerpKeyFrameElement(AnimationKeyFrameElement prev, AnimationKeyFrameElement next, int forFlag, float t, ref ElementPose transform)
        {
            if (prev == null && next == null)
            {
                return;
            }

            t = GameMath.SmoothStep(t);

            // Applies the transforms in model space
            if (forFlag == 0)
            {
                transform.translateX = GameMath.Lerp((float)prev.OffsetX / 16f, (float)next.OffsetX / 16f, t);
                transform.translateY = GameMath.Lerp((float)prev.OffsetY / 16f, (float)next.OffsetY / 16f, t);
                transform.translateZ = GameMath.Lerp((float)prev.OffsetZ / 16f, (float)next.OffsetZ / 16f, t);
            }
            else if (forFlag == 1)
            {
                transform.degX = GameMath.Lerp((float)prev.RotationX, (float)next.RotationX, t);
                transform.degY = GameMath.Lerp((float)prev.RotationY, (float)next.RotationY, t);
                transform.degZ = GameMath.Lerp((float)prev.RotationZ, (float)next.RotationZ, t);
            }
            else
            {
                transform.scaleX = GameMath.Lerp((float)prev.StretchX, (float)next.StretchX, t);
                transform.scaleY = GameMath.Lerp((float)prev.StretchY, (float)next.StretchY, t);
                transform.scaleZ = GameMath.Lerp((float)prev.StretchZ, (float)next.StretchZ, t);
            }
        }
예제 #9
0
        protected void GenerateFrameForElement(int frameNumber, ShapeElement element, ref ElementPose transform)
        {
            for (int flag = 0; flag < 3; flag++)
            {
                AnimationKeyFrameElement curKelem, nextKelem;

                getTwoKeyFramesElementForFlag(frameNumber, element, flag, out curKelem, out nextKelem);

                if (curKelem == null)
                {
                    continue;
                }


                float t;

                if (nextKelem == null || curKelem == nextKelem)
                {
                    nextKelem = curKelem;
                    t         = 0;
                }
                else
                {
                    if (nextKelem.Frame < curKelem.Frame)
                    {
                        int quantity = nextKelem.Frame + (QuantityFrames - curKelem.Frame);
                        int framePos = GameMath.Mod(frameNumber - curKelem.Frame, QuantityFrames);

                        t = (float)framePos / quantity;
                    }
                    else
                    {
                        t = (float)(frameNumber - curKelem.Frame) / (nextKelem.Frame - curKelem.Frame);
                    }
                }


                lerpKeyFrameElement(curKelem, nextKelem, flag, t, ref transform);
            }
        }
예제 #10
0
        // Careful when changing around stuff in here, this is a recursively called method
        private void calculateMatrices(
            float dt,
            List <ElementPose> currentPoses,
            ShapeElementWeights[][] weightsByAnimationAndElement,
            float[] modelMatrix,
            List <ElementPose>[] transformsByAnimation,
            List <ElementPose>[] nextFrameTransformsByAnimation,
            int depth
            )
        {
            depth++;
            List <ElementPose>[]    childTransformsByAnimation          = this.transformsByAnimation[depth];
            List <ElementPose>[]    nextFrameChildTransformsByAnimation = this.nextFrameTransformsByAnimation[depth];
            ShapeElementWeights[][] childWeightsByAnimationAndElement   = this.weightsByAnimationAndElement[depth];


            for (int i = 0; i < currentPoses.Count; i++)
            {
                ElementPose  currentPose = currentPoses[i];
                ShapeElement elem        = currentPose.ForElement;

                currentPose.SetMat(modelMatrix);
                Mat4f.Identity(localTransformMatrix);

                currentPose.Clear();

                float weightSum = 0f;
                for (int j = 0; j < curAnimCount; j++)
                {
                    RunningAnimation    anim = CurAnims[j];
                    ShapeElementWeights sew  = weightsByAnimationAndElement[j][i];

                    if (sew.BlendMode != EnumAnimationBlendMode.Add)
                    {
                        weightSum += sew.Weight * anim.EasingFactor;
                    }
                }

                for (int j = 0; j < curAnimCount; j++)
                {
                    RunningAnimation    anim = CurAnims[j];
                    ShapeElementWeights sew  = weightsByAnimationAndElement[j][i];
                    //anim.CalcBlendedWeight(sew.Weight weightSum, sew.BlendMode); - that makes no sense for element weights != 1
                    anim.CalcBlendedWeight(weightSum / sew.Weight, sew.BlendMode);

                    ElementPose prevFramePose = transformsByAnimation[j][i];
                    ElementPose nextFramePose = nextFrameTransformsByAnimation[j][i];

                    int prevFrame = this.prevFrame[j];
                    int nextFrame = this.nextFrame[j];

                    // May loop around, so nextFrame can be smaller than prevFrame
                    float keyFrameDist = nextFrame > prevFrame ? (nextFrame - prevFrame) : (anim.Animation.QuantityFrames - prevFrame + nextFrame);
                    float curFrameDist = anim.CurrentFrame >= prevFrame ? (anim.CurrentFrame - prevFrame) : (anim.Animation.QuantityFrames - prevFrame + anim.CurrentFrame);

                    float lerp = curFrameDist / keyFrameDist;

                    currentPose.Add(prevFramePose, nextFramePose, lerp, anim.BlendedWeight);


                    childTransformsByAnimation[j]        = prevFramePose.ChildElementPoses;
                    childWeightsByAnimationAndElement[j] = sew.ChildElements;

                    nextFrameChildTransformsByAnimation[j] = nextFramePose.ChildElementPoses;
                }

                elem.GetLocalTransformMatrix(localTransformMatrix, currentPose);
                Mat4f.Mul(currentPose.AnimModelMatrix, currentPose.AnimModelMatrix, localTransformMatrix);

                if (elem.JointId > 0 && !jointsDone.Contains(elem.JointId))
                {
                    Mat4f.Mul(tmpMatrix, currentPose.AnimModelMatrix, elem.inverseModelTransform);

                    for (int l = 0; l < 16; l++)
                    {
                        TransformationMatrices[16 * elem.JointId + l] = tmpMatrix[l];
                    }

                    jointsDone.Add(elem.JointId);
                }

                if (currentPose.ChildElementPoses != null)
                {
                    calculateMatrices(
                        dt,
                        currentPose.ChildElementPoses,
                        childWeightsByAnimationAndElement,
                        currentPose.AnimModelMatrix,
                        childTransformsByAnimation,
                        nextFrameChildTransformsByAnimation,
                        depth
                        );
                }
            }
        }