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); } } }
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); }
/// <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); }
// 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 ); } } }