Example #1
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
                    };
                }
            }
        }
        public EntityHeadController(IAnimationManager animator, EntityAgent entity, Shape entityShape)
        {
            this.entity      = entity;
            this.animManager = animator;

            HeadElement = entityShape.GetElementByName("head");
            NeckElement = entityShape.GetElementByName("neck");

            HeadGlobalMatrix         = Mat4f.Create();
            HeadGlobalMatrixInverted = Mat4f.Create();
            HeadLocalMatrix          = Mat4f.Create();

            // Head
            List <ShapeElement> elems = HeadElement.GetParentPath();

            for (int i = 0; i < elems.Count; i++)
            {
                ShapeElement elem           = elems[i];
                float[]      localTransform = elem.GetLocalTransformMatrix();
                Mat4f.Mul(HeadGlobalMatrix, HeadGlobalMatrix, localTransform);
            }

            Mat4f.Mul(HeadGlobalMatrix, HeadGlobalMatrix, HeadElement.GetLocalTransformMatrix());
            Mat4f.Invert(HeadGlobalMatrixInverted, HeadGlobalMatrix);
        }
Example #3
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);
                }
            }
        }
Example #4
0
        private void LoadWeights(ShapeElement[] elements, ShapeElementWeights[] intoList, Dictionary <string, float> elementWeight, Dictionary <string, EnumAnimationBlendMode> elementBlendMode)
        {
            for (int i = 0; i < elements.Length; i++)
            {
                ShapeElement elem = elements[i];
                intoList[i] = new ShapeElementWeights();

                float w;
                if (elementWeight.TryGetValue(elem.Name, out w))
                {
                    intoList[i].Weight = w;
                }
                else
                {
                    intoList[i].Weight = meta.Weight;
                }

                EnumAnimationBlendMode blendMode;
                if (elementBlendMode.TryGetValue(elem.Name, out blendMode))
                {
                    intoList[i].BlendMode = blendMode;
                }
                else
                {
                    intoList[i].BlendMode = meta.BlendMode;
                }


                if (elem.Children != null)
                {
                    intoList[i].ChildElements = new ShapeElementWeights[elem.Children.Length];
                    LoadWeights(elem.Children, intoList[i].ChildElements, elementWeight, elementBlendMode);
                }
            }
        }
Example #5
0
        ShapeElement GetElementByName(string name, ShapeElement[] elems, StringComparison stringComparison)
        {
            if (elems == null)
            {
                return(null);
            }

            foreach (ShapeElement elem in elems)
            {
                if (elem.Name.Equals(name, stringComparison))
                {
                    return(elem);
                }
                if (elem.Children != null)
                {
                    ShapeElement foundElem = GetElementByName(name, elem.Children, stringComparison);
                    if (foundElem != null)
                    {
                        return(foundElem);
                    }
                }
            }


            return(null);
        }
Example #6
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);
                }
            }
        }
Example #7
0
        private int seekRightKeyFrame(int aboveFrameNumber, ShapeElement forElement, int forFlag)
        {
            int firstIndex = -1;

            for (int i = 0; i < KeyFrames.Length; i++)
            {
                AnimationKeyFrame keyframe = KeyFrames[i];

                AnimationKeyFrameElement kelem = keyframe.GetKeyFrameElement(forElement);
                if (kelem != null && kelem.IsSet(forFlag))
                {
                    if (firstIndex == -1)
                    {
                        firstIndex = i;
                    }
                    if (keyframe.Frame <= aboveFrameNumber)
                    {
                        continue;
                    }

                    return(i);
                }
            }

            return(firstIndex);
        }
Example #8
0
        private bool applyStepParents(ShapeElement parentElem, ShapeElement[] elements, Shape toShape, string code, CompositeShape cshape, string shapePathForLogging)
        {
            bool added = false;

            foreach (var cElem in elements)
            {
                ShapeElement refelem;

                if (cElem.Children != null)
                {
                    added |= applyStepParents(cElem, cElem.Children, toShape, code, cshape, shapePathForLogging);
                }

                if (cElem.StepParentName != null)
                {
                    refelem = toShape.GetElementByName(cElem.StepParentName, StringComparison.InvariantCultureIgnoreCase);
                    if (refelem == null)
                    {
                        Api.World.Logger.Warning("Shape {0} requires step parent element with name {1}, but no such element was found in shape {2}. Will not be visible.", cshape.Base, cElem.StepParentName, shapePathForLogging);
                        continue;
                    }
                }
                else
                {
                    if (parentElem == null)
                    {
                        Api.World.Logger.Warning("Entity armor shape element {0} in shape {1} did not define a step parent element. Will not be visible.", cElem.Name, cshape.Base);
                    }
                    continue;
                }

                if (parentElem != null)
                {
                    parentElem.Children = parentElem.Children.Remove(cElem);
                }

                if (refelem.Children == null)
                {
                    refelem.Children = new ShapeElement[] { cElem };
                }
                else
                {
                    refelem.Children = refelem.Children.Append(cElem);
                }

                cElem.SetJointIdRecursive(refelem.JointId);

                cElem.WalkRecursive((el) =>
                {
                    foreach (var face in el.Faces)
                    {
                        face.Value.Texture = "#" + code + "-" + face.Value.Texture.TrimStart('#');
                    }
                });

                added = true;
            }

            return(added);
        }
Example #9
0
        public ShapeElement[] CloneElements()
        {
            ShapeElement[] elems = new ShapeElement[Elements.Length];

            for (int i = 0; i < elems.Length; i++)
            {
                elems[i] = Elements[i].Clone();
            }

            return(elems);
        }
Example #10
0
        internal AnimationKeyFrameElement GetKeyFrameElement(ShapeElement forElem)
        {
            if (forElem == null)
            {
                return(null);
            }
            AnimationKeyFrameElement kelem = null;

            ElementsByShapeElement.TryGetValue(forElem, out kelem);
            return(kelem);
        }
Example #11
0
        private void CollectAttachmentPoints(ShapeElement elem)
        {
            for (int j = 0; elem.AttachmentPoints != null && j < elem.AttachmentPoints.Length; j++)
            {
                AttachmentPointsByCode[elem.AttachmentPoints[j].Code] = elem.AttachmentPoints[j];
            }

            for (int j = 0; elem.Children != null && j < elem.Children.Length; j++)
            {
                CollectAttachmentPoints(elem.Children[j]);
            }
        }
Example #12
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);
        }
Example #13
0
        /// <summary>
        /// Walks the element tree and collects all parents, starting with the root element
        /// </summary>
        /// <returns></returns>
        public List <ShapeElement> GetParentPath()
        {
            List <ShapeElement> path       = new List <ShapeElement>();
            ShapeElement        parentElem = this.ParentElement;

            while (parentElem != null)
            {
                path.Add(parentElem);
                parentElem = parentElem.ParentElement;
            }
            path.Reverse();
            return(path);
        }
Example #14
0
        private int seekLeftKeyFrame(int leftOfKeyFrameIndex, ShapeElement forElement, int forFlag)
        {
            for (int i = 0; i < KeyFrames.Length; i++)
            {
                int index = GameMath.Mod(leftOfKeyFrameIndex - i - 1, KeyFrames.Length);
                AnimationKeyFrame keyframe = KeyFrames[index];

                AnimationKeyFrameElement kelem = keyframe.GetKeyFrameElement(forElement);
                if (kelem != null && kelem.IsSet(forFlag))
                {
                    return(index);
                }
            }

            return(-1);
        }
Example #15
0
        /// <summary>
        /// Collects all the elements in the shape recursively.
        /// </summary>
        /// <param name="elements"></param>
        /// <param name="elementsByName"></param>
        public void CollectElements(ShapeElement[] elements, Dictionary <string, ShapeElement> elementsByName)
        {
            if (elements == null)
            {
                return;
            }

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

                elementsByName[elem.Name] = elem;

                CollectElements(elem.Children, elementsByName);
            }
        }
Example #16
0
        AnimationKeyFrameElement FindKeyFrameElement(ShapeElement forElem)
        {
            if (forElem == null)
            {
                return(null);
            }

            foreach (var val in Elements)
            {
                if (forElem.Name == val.Key)
                {
                    return(val.Value);
                }
            }

            return(null);
        }
Example #17
0
        public ShapeElement Clone()
        {
            ShapeElement elem = new ShapeElement()
            {
                AttachmentPoints = (AttachmentPoint[])AttachmentPoints?.Clone(),
                Faces            = new Dictionary <string, ShapeElementFace>(Faces),
                From             = (double[])From?.Clone(),
                To = (double[])To?.Clone(),
                inverseModelTransform = (float[])inverseModelTransform?.Clone(),
                JointId                 = JointId,
                RenderPass              = RenderPass,
                RotationX               = RotationX,
                RotationY               = RotationY,
                RotationZ               = RotationZ,
                Reflective              = Reflective,
                RotationOrigin          = (double[])RotationOrigin?.Clone(),
                SeasonColorMap          = SeasonColorMap,
                ClimateColorMap         = ClimateColorMap,
                StepParentName          = StepParentName,
                Shade                   = Shade,
                WindMode                = WindMode,
                WindData                = WindData,
                WaterWave               = WaterWave,
                DisableRandomDrawOffset = DisableRandomDrawOffset,
                ZOffset                 = ZOffset,
                GradientShade           = GradientShade,
                ScaleX                  = ScaleX,
                ScaleY                  = ScaleY,
                ScaleZ                  = ScaleZ,
                Name = Name
            };

            if (Children != null)
            {
                elem.Children = new ShapeElement[Children.Length];
                for (int i = 0; i < Children.Length; i++)
                {
                    elem.Children[i] = Children[i].Clone();
                    elem.Children[i].ParentElement = elem;
                }
            }

            return(elem);
        }
Example #18
0
        /// <summary>
        /// Returns the full inverse model matrix (includes all parent transforms)
        /// </summary>
        /// <returns></returns>
        public float[] GetInverseModelMatrix()
        {
            List <ShapeElement> elems = GetParentPath();

            float[] modelTransform = Mat4f.Create();

            for (int i = 0; i < elems.Count; i++)
            {
                ShapeElement elem           = elems[i];
                float[]      localTransform = elem.GetLocalTransformMatrix();
                Mat4f.Mul(modelTransform, modelTransform, localTransform);
            }

            Mat4f.Mul(modelTransform, modelTransform, GetLocalTransformMatrix());

            float[] inverseTransformMatrix = Mat4f.Invert(Mat4f.Create(), modelTransform);

            return(inverseTransformMatrix);
        }
        protected virtual void ApplyTransformToElements(float[] matrix, float[] globMatrix, float[] globMatrixInverted, ShapeElement[] forElems, ShapeElement jointElement, int jointId)
        {
            float[] transformationMatrices = animManager.Animator.Matrices;

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

                if (elem == jointElement || elem.JointId != jointId)
                {
                    for (int i = 0; i < 16; i++)
                    {
                        tmpMatrix[i] = transformationMatrices[16 * elem.JointId + i];
                    }

                    float[] origin = new float[] {
                        (float)jointElement.RotationOrigin[0] / 16f,
                        (float)jointElement.RotationOrigin[1] / 16f,
                        (float)jointElement.RotationOrigin[2] / 16f
                    };

                    Mat4f.Mul(tmpMatrix, tmpMatrix, globMatrix);
                    Mat4f.Translate(tmpMatrix, tmpMatrix, origin);
                    Mat4f.Mul(tmpMatrix, tmpMatrix, matrix);
                    origin[0] = -origin[0];
                    origin[1] = -origin[1];
                    origin[2] = -origin[2];
                    Mat4f.Translate(tmpMatrix, tmpMatrix, origin);
                    Mat4f.Mul(tmpMatrix, tmpMatrix, globMatrixInverted);

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

                if (elem.Children != null)
                {
                    ApplyTransformToElements(matrix, globMatrix, globMatrixInverted, elem.Children, jointElement, jointId);
                }
            }
        }
Example #20
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);

                transform.RotShortestDistance = curKelem.RotShortestDistance;
            }
        }
Example #21
0
        private void ResolveReferences(ILogger errorLogger, string shapeName, Dictionary <string, ShapeElement> elementsByName, AnimationKeyFrame kf)
        {
            if (kf == null)
            {
                return;
            }

            foreach (var val in kf.Elements)
            {
                ShapeElement elem = null;
                elementsByName.TryGetValue(val.Key, out elem);

                if (elem == null)
                {
                    errorLogger.Error("Shape {0} has a key frame elmenent for which the referencing shape element {1} cannot be found.", shapeName, val.Key);

                    val.Value.ForElement = new ShapeElement();
                    continue;
                }

                val.Value.ForElement = elem;
            }
        }
Example #22
0
        protected void getTwoKeyFramesElementForFlag(int frameNumber, ShapeElement forElement, int forFlag, out AnimationKeyFrameElement left, out AnimationKeyFrameElement right)
        {
            left  = null;
            right = null;

            int rightKfIndex = seekRightKeyFrame(frameNumber, forElement, forFlag);

            if (rightKfIndex == -1)
            {
                return;
            }

            right = KeyFrames[rightKfIndex].GetKeyFrameElement(forElement);

            int leftKfIndex = seekLeftKeyFrame(rightKfIndex, forElement, forFlag);

            if (leftKfIndex == -1)
            {
                left = right;
                return;
            }

            left = KeyFrames[leftKfIndex].GetKeyFrameElement(forElement);
        }
Example #23
0
        /// <summary>
        /// Attempts to resolve all references within the shape. Logs missing references them to the errorLogger
        /// </summary>
        /// <param name="errorLogger"></param>
        /// <param name="shapeNameForLogging"></param>
        public void ResolveReferences(ILogger errorLogger, string shapeNameForLogging)
        {
            Dictionary <string, ShapeElement> elementsByName = new Dictionary <string, ShapeElement>();

            CollectElements(Elements, elementsByName);

            for (int i = 0; Animations != null && i < Animations.Length; i++)
            {
                Animation anim = Animations[i];
                for (int j = 0; j < anim.KeyFrames.Length; j++)
                {
                    AnimationKeyFrame keyframe = anim.KeyFrames[j];
                    ResolveReferences(errorLogger, shapeNameForLogging, elementsByName, keyframe);

                    foreach (AnimationKeyFrameElement kelem in keyframe.Elements.Values)
                    {
                        kelem.Frame = keyframe.Frame;
                    }
                }

                if (anim.Code == null || anim.Code.Length == 0)
                {
                    anim.Code = anim.Name.ToLowerInvariant().Replace(" ", "");
                }

                AnimationsByCrc32[AnimationMetaData.GetCrc32(anim.Code)] = anim;
            }

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

                CollectAttachmentPoints(elem);
            }
        }
Example #24
0
        /// <summary>
        /// Resolves all joints and loads them.
        /// </summary>
        /// <param name="requireJointsForElements"></param>
        public void ResolveAndLoadJoints(params string[] requireJointsForElements)
        {
            if (Animations == null)
            {
                return;
            }

            Dictionary <string, ShapeElement> elementsByName = new Dictionary <string, ShapeElement>();

            CollectElements(Elements, elementsByName);

            ShapeElement[] allElements = elementsByName.Values.ToArray();

            int jointCount = 0;

            HashSet <string> AnimatedElements = new HashSet <string>();

            for (int i = 0; i < Animations.Length; i++)
            {
                Animation anim = Animations[i];

                for (int j = 0; j < anim.KeyFrames.Length; j++)
                {
                    AnimationKeyFrame kf = anim.KeyFrames[j];
                    AnimatedElements.AddRange(kf.Elements.Keys.ToArray());

                    kf.Resolve(anim, allElements);
                }
            }

            foreach (ShapeElement elem in elementsByName.Values)
            {
                elem.JointId = 0;
            }

            int maxDepth = 0;

            foreach (string code in AnimatedElements)
            {
                ShapeElement elem;
                elementsByName.TryGetValue(code, out elem);
                if (elem == null)
                {
                    continue;
                }
                AnimationJoint joint = new AnimationJoint()
                {
                    JointId = ++jointCount, Element = elem
                };
                JointsById[joint.JointId] = joint;

                maxDepth = Math.Max(maxDepth, elem.GetParentPath().Count);
            }

            // Currently used to require a joint for the head for head control, but not really used because
            // the player head also happens to be using in animations so it has a joint anyway
            foreach (string elemName in requireJointsForElements)
            {
                if (!AnimatedElements.Contains(elemName))
                {
                    ShapeElement elem = GetElementByName(elemName);
                    if (elem == null)
                    {
                        continue;
                    }

                    AnimationJoint joint = new AnimationJoint()
                    {
                        JointId = ++jointCount, Element = elem
                    };
                    JointsById[joint.JointId] = joint;
                    maxDepth = Math.Max(maxDepth, elem.GetParentPath().Count);
                }
            }



            // Iteratively and recursively assigns the lowest depth to highest depth joints to all elements
            // prevents that we overwrite a child joint id with a parent joint id
            for (int depth = 0; depth <= maxDepth; depth++)
            {
                foreach (AnimationJoint joint in JointsById.Values)
                {
                    if (joint.Element.GetParentPath().Count != depth)
                    {
                        continue;
                    }

                    joint.Element.SetJointId(joint.JointId);
                }
            }
        }
Example #25
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
                        );
                }
            }
        }
 /// <summary>
 /// Applies the transformation to the head element of the entity.
 /// </summary>
 /// <param name="matrix"></param>
 /// <param name="jointElement"></param>
 public virtual void ApplyTransformToElement(float[] matrix, float[] globMatrix, float[] globMatrixInverted, ShapeElement jointElement)
 {
     ApplyTransformToElements(matrix, globMatrix, globMatrixInverted, new ShapeElement[] { jointElement }, jointElement, jointElement.JointId);
 }