public AnimationFrame() { for (int i = 0; i < animTransforms.Length; i++) { animTransforms[i] = Mat4f.Create(); } }
public AnimatorBase(WalkSpeedSupplierDelegate WalkSpeedSupplier, Animation[] Animations, Action <string> onAnimationStoppedListener = null) { this.WalkSpeedSupplier = WalkSpeedSupplier; this.onAnimationStoppedListener = onAnimationStoppedListener; anims = new RunningAnimation[Animations == null ? 0 : Animations.Length]; for (int i = 0; i < anims.Length; i++) { Animations[i].Code = Animations[i].Code.ToLower(); anims[i] = new RunningAnimation() { Active = false, Running = false, Animation = Animations[i], CurrentFrame = 0 }; } float[] identMat = Mat4f.Create(); for (int i = 0; i < TransformationMatricesDefaultPose.Length; i++) { TransformationMatricesDefaultPose[i] = identMat[i % 16]; } }
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); }
public void loadModelMatrix(Entity entity) { IEntityPlayer entityPlayer = capi.World.Player.Entity; Mat4f.Identity(ModelMat); Mat4f.Translate(ModelMat, ModelMat, (float)(entity.Pos.X - entityPlayer.CameraPos.X), (float)(entity.Pos.Y - entityPlayer.CameraPos.Y), (float)(entity.Pos.Z - entityPlayer.CameraPos.Z)); float rotX = entity.Properties.Client.Shape != null ? entity.Properties.Client.Shape.rotateX : 0; float rotY = entity.Properties.Client.Shape != null ? entity.Properties.Client.Shape.rotateY : 0; float rotZ = entity.Properties.Client.Shape != null ? entity.Properties.Client.Shape.rotateZ : 0; Mat4f.Translate(ModelMat, ModelMat, 0, entity.CollisionBox.Y2 / 2, 0); double[] quat = Quaterniond.Create(); Quaterniond.RotateX(quat, quat, entity.Pos.Pitch + rotX * GameMath.DEG2RAD); Quaterniond.RotateY(quat, quat, entity.Pos.Yaw + (rotY + 90) * GameMath.DEG2RAD); Quaterniond.RotateZ(quat, quat, entity.Pos.Roll + rotZ * GameMath.DEG2RAD); float[] qf = new float[quat.Length]; for (int i = 0; i < quat.Length; i++) { qf[i] = (float)quat[i]; } Mat4f.Mul(ModelMat, ModelMat, Mat4f.FromQuat(Mat4f.Create(), qf)); float scale = entity.Properties.Client.Size; Mat4f.Scale(ModelMat, ModelMat, new float[] { scale, scale, scale }); Mat4f.Translate(ModelMat, ModelMat, -0.5f, -entity.CollisionBox.Y2 / 2, -0.5f); }
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); } } }
private float[] GetFirstPersonHandsMatrix(EntityAgent entity, float[] viewMat, float deltaTime) { var modelMat = Mat4f.Invert(Mat4f.Create(), viewMat); // If the hands haven't been rendered in the last 10 render ticks, reset wobble and such. if (_renderTick - _lastTickHandsRendered > 10) { _moveWobble = 0; _lastYaw = entity.Pos.Yaw;; _yawDifference = 0; } _lastTickHandsRendered = _renderTick; if (entity.Controls.TriesToMove) { var moveSpeed = entity.Controls.MovespeedMultiplier * (float)entity.GetWalkSpeedMultiplier(); _moveWobble += moveSpeed * deltaTime * 5.0F; } else { var target = (float)(Math.Round(_moveWobble / Math.PI) * Math.PI); var speed = deltaTime * (0.2F + Math.Abs(target - _moveWobble) * 4); if (Math.Abs(target - _moveWobble) < speed) { _moveWobble = target; } else { _moveWobble += Math.Sign(target - _moveWobble) * speed; } } _moveWobble = _moveWobble % (GameMath.PI * 2); var moveWobbleOffsetX = GameMath.Sin((_moveWobble + GameMath.PI)) * 0.03F; var moveWobbleOffsetY = GameMath.Sin(_moveWobble * 2) * 0.02F; _yawDifference += GameMath.AngleRadDistance(_lastYaw, entity.Pos.Yaw); _yawDifference *= (1 - 0.075F); _lastYaw = entity.Pos.Yaw; var yawRotation = -_yawDifference / 2; var pitchRotation = (entity.Pos.Pitch - GameMath.PI) / 4; Mat4f.RotateY(modelMat, modelMat, yawRotation); Mat4f.Translate(modelMat, modelMat, 0.0F, -0.35F, -0.20F); Mat4f.RotateY(modelMat, modelMat, -yawRotation); Mat4f.RotateX(modelMat, modelMat, pitchRotation / 2); Mat4f.Translate(modelMat, modelMat, 0.0F, 0.0F, -0.20F); Mat4f.RotateX(modelMat, modelMat, pitchRotation); Mat4f.RotateY(modelMat, modelMat, yawRotation); Mat4f.Translate(modelMat, modelMat, moveWobbleOffsetX, moveWobbleOffsetY, 0.0F); Mat4f.RotateY(modelMat, modelMat, 90.0F * GameMath.DEG2RAD); return(modelMat); }
void updateLocalEyePosImmersiveFpMode() { AttachmentPointAndPose apap = AnimManager.Animator.GetAttachmentPointPose("Eyes"); AttachmentPoint ap = apap.AttachPoint; float[] ModelMat = Mat4f.Create(); Matrixf tmpModelMat = new Matrixf(); float bodyYaw = BodyYaw; float rotX = Properties.Client.Shape != null ? Properties.Client.Shape.rotateX : 0; float rotY = Properties.Client.Shape != null ? Properties.Client.Shape.rotateY : 0; float rotZ = Properties.Client.Shape != null ? Properties.Client.Shape.rotateZ : 0; float bodyPitch = WalkPitch; float lookOffset = (SidedPos.Pitch - GameMath.PI) / 9f; bool wasHoldPos = holdPosition; holdPosition = false; for (int i = 0; i < AnimManager.Animator.RunningAnimations.Length; i++) { RunningAnimation anim = AnimManager.Animator.RunningAnimations[i]; if (anim.Running && anim.EasingFactor > anim.meta.HoldEyePosAfterEasein) { if (!wasHoldPos) { prevAnimModelMatrix = (float[])apap.AnimModelMatrix.Clone(); } holdPosition = true; break; } } tmpModelMat .Set(ModelMat) .RotateX(SidedPos.Roll + rotX * GameMath.DEG2RAD) .RotateY(bodyYaw + (180 + rotY) * GameMath.DEG2RAD) .RotateZ(bodyPitch + rotZ * GameMath.DEG2RAD) .Mul(holdPosition ? prevAnimModelMatrix : apap.AnimModelMatrix) .Scale(Properties.Client.Size, Properties.Client.Size, Properties.Client.Size) .Translate(-0.5f, 0, -0.5f) .Translate(ap.PosX / 16f - lookOffset, ap.PosY / 16f - lookOffset / 1.3f, ap.PosZ / 16f) ; float[] pos = new float[4] { 0, 0, 0, 1 }; float[] endVec = Mat4f.MulWithVec4(tmpModelMat.Values, pos); LocalEyePos.Set(endVec[0], endVec[1], endVec[2]); }
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); }
static BEBehaviorFruiting() { randomRotMatrices = new float[randomRotations.Length][]; for (int i = 0; i < randomRotations.Length; i++) { float[] matrix = Mat4f.Create(); Mat4f.Translate(matrix, matrix, 0.5f, 0.5f, 0.5f); Mat4f.RotateY(matrix, matrix, randomRotations[i] * GameMath.DEG2RAD); Mat4f.Translate(matrix, matrix, -0.5f, -0.5f, -0.5f); randomRotMatrices[i] = matrix; } }
/// <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); }
/// <summary> /// Compiles the animation into a bunch of matrices, 31 matrices per frame. /// </summary> /// <param name="rootElements"></param> /// <param name="jointsById"></param> /// <param name="recursive">When false, will only do root elements</param> public void GenerateAllFrames(ShapeElement[] rootElements, Dictionary <int, AnimationJoint> jointsById, bool recursive = true) { AnimationFrame[] resolvedKeyFrames = new AnimationFrame[KeyFrames.Length]; for (int i = 0; i < resolvedKeyFrames.Length; i++) { resolvedKeyFrames[i] = new AnimationFrame() { FrameNumber = KeyFrames[i].Frame }; } if (KeyFrames.Length == 0) { return; } if (jointsById.Count > GlobalConstants.MaxAnimatedElements) { throw new Exception("Max joint cap of " + GlobalConstants.MaxAnimatedElements + " reached. Sorry, you'll have to simplify your model if you want it to be animated. (until some programmer finds another solution to pass on more joint data through shader uniforms)"); } for (int i = 0; i < resolvedKeyFrames.Length; i++) { jointsDone.Clear(); GenerateFrame(i, resolvedKeyFrames, rootElements, jointsById, Mat4f.Create(), resolvedKeyFrames[i].RootElementTransforms, recursive); } for (int i = 0; i < resolvedKeyFrames.Length; i++) { resolvedKeyFrames[i].FinalizeMatrices(jointsById); } PrevNextKeyFrameByFrame = new AnimationFrame[QuantityFrames][]; for (int i = 0; i < QuantityFrames; i++) { AnimationFrame left, right; getLeftRightResolvedFrame(i, resolvedKeyFrames, out left, out right); PrevNextKeyFrameByFrame[i] = new AnimationFrame[] { left, right }; } }
public static void RotateVector(ref Vec3f vector, float degX, float degY, float degZ, Vec3f origin) { float radX = degX * GameMath.DEG2RAD; float radY = degY * GameMath.DEG2RAD; float radZ = degZ * GameMath.DEG2RAD; float[] matrix = Mat4f.Create(); Mat4f.RotateX(matrix, matrix, radX); Mat4f.RotateY(matrix, matrix, radY); Mat4f.RotateZ(matrix, matrix, radZ); float[] pos = new float[] { 0, 0, 0, 1 }; float[] vec = new float[] { vector.X - (float)origin.X, vector.Y - (float)origin.Y, vector.Z - (float)origin.Z, 1 }; vec = Mat4f.MulWithVec4(matrix, vec); vector.X = vec[0] + origin.X; vector.Y = vec[1] + origin.Y; vector.Z = vec[2] + origin.Z; }
public AttachmentPointAndPose() { AnimModelMatrix = Mat4f.Create(); }
/// <summary> /// If an attachment point called "Center" exists, then this method /// offsets the creatures collision box so that the Center attachment point is the center of the collision box. /// </summary> public void AdjustCollisionBoxToAnimation(float dtFac) { float[] hitboxOff = new float[4] { 0, 0, 0, 1 }; AttachmentPointAndPose apap = entity.AnimManager.Animator.GetAttachmentPointPose("Center"); if (apap == null) { return; } AttachmentPoint ap = apap.AttachPoint; float rotX = entity.Properties.Client.Shape != null ? entity.Properties.Client.Shape.rotateX : 0; float rotY = entity.Properties.Client.Shape != null ? entity.Properties.Client.Shape.rotateY : 0; float rotZ = entity.Properties.Client.Shape != null ? entity.Properties.Client.Shape.rotateZ : 0; float[] ModelMat = Mat4f.Create(); Mat4f.Identity(ModelMat); Mat4f.Translate(ModelMat, ModelMat, 0, entity.CollisionBox.Y2 / 2, 0); double[] quat = Quaterniond.Create(); Quaterniond.RotateX(quat, quat, entity.Pos.Pitch + rotX * GameMath.DEG2RAD); Quaterniond.RotateY(quat, quat, entity.Pos.Yaw + (rotY + 90) * GameMath.DEG2RAD); Quaterniond.RotateZ(quat, quat, entity.Pos.Roll + rotZ * GameMath.DEG2RAD); float[] qf = new float[quat.Length]; for (int k = 0; k < quat.Length; k++) { qf[k] = (float)quat[k]; } Mat4f.Mul(ModelMat, ModelMat, Mat4f.FromQuat(Mat4f.Create(), qf)); float scale = entity.Properties.Client.Size; Mat4f.Translate(ModelMat, ModelMat, 0, -entity.CollisionBox.Y2 / 2, 0f); Mat4f.Scale(ModelMat, ModelMat, new float[] { scale, scale, scale }); Mat4f.Translate(ModelMat, ModelMat, -0.5f, 0, -0.5f); tmpModelMat .Set(ModelMat) .Mul(apap.AnimModelMatrix) .Translate(ap.PosX / 16f, ap.PosY / 16f, ap.PosZ / 16f) ; EntityPos epos = entity.SidedPos; float[] endVec = Mat4f.MulWithVec4(tmpModelMat.Values, hitboxOff); float motionX = endVec[0] - (entity.CollisionBox.X1 - entity.OriginCollisionBox.X1); float motionZ = endVec[2] - (entity.CollisionBox.Z1 - entity.OriginCollisionBox.Z1); if (Math.Abs(motionX) > 0.00001 || Math.Abs(motionZ) > 0.00001) { EntityPos posMoved = epos.Copy(); posMoved.Motion.X = motionX; posMoved.Motion.Z = motionZ; moveDelta.Set(posMoved.Motion.X, posMoved.Motion.Y, posMoved.Motion.Z); collisionTester.ApplyTerrainCollision(entity, posMoved, dtFac, ref outposition); double reflectX = outposition.X - epos.X - motionX; double reflectZ = outposition.Z - epos.Z - motionZ; epos.Motion.X = reflectX; epos.Motion.Z = reflectZ; entity.CollisionBox.Set(entity.OriginCollisionBox); entity.CollisionBox.Translate(endVec[0], 0, endVec[2]); } //Console.WriteLine("{0}/{1}", reflectX, reflectZ); }
public Matrixf() { Values = Mat4f.Create(); }
public void OnRenderFrame(float deltaTime, EnumRenderStage stage) { foreach (var player in API.World.AllPlayers) { // Leaving the additional, more detailed exceptions in just in case other things end up breaking. if (player == null) { throw new Exception("null player in API.World.AllPlayers!"); } // Player entity may be null in some circumstances. // Maybe the other player is too far away, so there's // no entity spawned for them on the client's side? if (player.Entity == null) { continue; } if (API.World == null) { throw new Exception("API.World is null!"); } if (API.World.Player == null) { throw new Exception("API.World.Player is null!"); } var entity = player.Entity; var allCarried = entity.GetCarried().ToList(); if (allCarried.Count == 0) { continue; // Entity is not carrying anything. } var renderApi = API.Render; var isShadowPass = (stage != EnumRenderStage.Opaque); var isFirstPerson = (player == API.World.Player) && (API.World.Player.CameraMode == EnumCameraMode.FirstPerson); var renderer = (EntityShapeRenderer)entity.Properties.Client.Renderer; if (renderer == null) { continue; // Apparently this can end up being null? } // Reported to Tyron, so it might be fixed. Leaving it in for now just in case. var animator = entity.AnimManager.Animator; if (animator == null) { throw new Exception("entity.AnimManager.Animator is null!"); } foreach (var carried in allCarried) { var inHands = (carried.Slot == CarrySlot.Hands); if (!inHands && isFirstPerson && !isShadowPass) { continue; } var renderSettings = _renderSettings[carried.Slot]; var renderInfo = GetRenderInfo(carried); var viewMat = Array.ConvertAll(API.Render.CameraMatrixOrigin, i => (float)i); float[] modelMat; if (inHands && isFirstPerson && !isShadowPass) { modelMat = Mat4f.Invert(Mat4f.Create(), viewMat); if (entity.Controls.TriesToMove) { var moveSpeed = entity.Controls.MovespeedMultiplier * (float)entity.GetWalkSpeedMultiplier(); moveWobble += moveSpeed * deltaTime * 5.0F; } else { var target = (float)(Math.Round(moveWobble / Math.PI) * Math.PI); var speed = deltaTime * (0.2F + Math.Abs(target - moveWobble) * 4); if (Math.Abs(target - moveWobble) < speed) { moveWobble = target; } else { moveWobble += Math.Sign(target - moveWobble) * speed; } } moveWobble = moveWobble % (GameMath.PI * 2); var moveWobbleOffsetX = GameMath.Sin((moveWobble + GameMath.PI)) * 0.03F; var moveWobbleOffsetY = GameMath.Sin(moveWobble * 2) * 0.02F; Mat4f.Translate(modelMat, modelMat, moveWobbleOffsetX, moveWobbleOffsetY - 0.25F, -0.25F); Mat4f.RotateY(modelMat, modelMat, 90.0F * GameMath.DEG2RAD); } else { modelMat = Mat4f.CloneIt(renderer.ModelMat); var attachPointAndPose = animator.GetAttachmentPointPose(renderSettings.AttachmentPoint); if (attachPointAndPose == null) { continue; } var animModelMat = attachPointAndPose.CachedPose.AnimModelMatrix; Mat4f.Mul(modelMat, modelMat, animModelMat); // Apply attachment point transform. var attach = attachPointAndPose.AttachPoint; Mat4f.Translate(modelMat, modelMat, (float)(attach.PosX / 16), (float)(attach.PosY / 16), (float)(attach.PosZ / 16)); Mat4f.RotateX(modelMat, modelMat, (float)attach.RotationX * GameMath.DEG2RAD); Mat4f.RotateY(modelMat, modelMat, (float)attach.RotationY * GameMath.DEG2RAD); Mat4f.RotateZ(modelMat, modelMat, (float)attach.RotationZ * GameMath.DEG2RAD); } // Apply carried block's behavior transform. var t = renderInfo.Transform; Mat4f.Scale(modelMat, modelMat, t.ScaleXYZ.X, t.ScaleXYZ.Y, t.ScaleXYZ.Z); Mat4f.Translate(modelMat, modelMat, renderSettings.Offset.X, renderSettings.Offset.Y, renderSettings.Offset.Z); Mat4f.Translate(modelMat, modelMat, t.Origin.X, t.Origin.Y, t.Origin.Z); Mat4f.RotateX(modelMat, modelMat, t.Rotation.X * GameMath.DEG2RAD); Mat4f.RotateY(modelMat, modelMat, t.Rotation.Y * GameMath.DEG2RAD); Mat4f.RotateZ(modelMat, modelMat, t.Rotation.Z * GameMath.DEG2RAD); Mat4f.Translate(modelMat, modelMat, -t.Origin.X, -t.Origin.Y, -t.Origin.Z); Mat4f.Translate(modelMat, modelMat, t.Translation.X, t.Translation.Y, t.Translation.Z); if (isShadowPass) { var prog = renderApi.CurrentActiveShader; Mat4f.Mul(modelMat, API.Render.CurrentShadowProjectionMatrix, modelMat); prog.BindTexture2D("tex2d", renderInfo.TextureId, 0); prog.UniformMatrix("mvpMatrix", modelMat); prog.Uniform("origin", renderer.OriginPos); API.Render.RenderMesh(renderInfo.ModelRef); } else { var prog = renderApi.PreparedStandardShader((int)entity.Pos.X, (int)entity.Pos.Y, (int)entity.Pos.Z); prog.Tex2D = renderInfo.TextureId; prog.AlphaTest = 0.01f; prog.ViewMatrix = viewMat; prog.ModelMatrix = modelMat; prog.DontWarpVertices = 1; API.Render.RenderMesh(renderInfo.ModelRef); prog.Stop(); } } } }
protected override void calculateMatrices(float dt) { if (!CalculateMatrices) { return; } try { jointsDone.Clear(); for (int j = 0; j < curAnimCount; j++) { RunningAnimation anim = CurAnims[j]; weightsByAnimationAndElement[0][j] = anim.ElementWeights; AnimationFrame[] prevNextFrame = anim.Animation.PrevNextKeyFrameByFrame[(int)anim.CurrentFrame % anim.Animation.QuantityFrames]; transformsByAnimation[0][j] = prevNextFrame[0].RootElementTransforms; prevFrame[j] = prevNextFrame[0].FrameNumber; if (anim.Animation.OnAnimationEnd == EnumEntityAnimationEndHandling.Hold && (int)anim.CurrentFrame + 1 == anim.Animation.QuantityFrames) { nextFrameTransformsByAnimation[0][j] = prevNextFrame[0].RootElementTransforms; nextFrame[j] = prevNextFrame[0].FrameNumber; } else { nextFrameTransformsByAnimation[0][j] = prevNextFrame[1].RootElementTransforms; nextFrame[j] = prevNextFrame[1].FrameNumber; } } calculateMatrices( dt, RootPoses, weightsByAnimationAndElement[0], Mat4f.Create(), transformsByAnimation[0], nextFrameTransformsByAnimation[0], 0 ); for (int jointid = 0; jointid < GlobalConstants.MaxAnimatedElements; jointid++) { if (jointsById.ContainsKey(jointid)) { continue; } for (int j = 0; j < 16; j++) { TransformationMatrices[jointid * 16 + j] = identMat[j]; } } foreach (var val in AttachmentPointByCode) { for (int i = 0; i < 16; i++) { val.Value.AnimModelMatrix[i] = val.Value.CachedPose.AnimModelMatrix[i]; } } } catch (Exception) { //entity.World.Logger.Fatal("Animation system crash. Please report this bug. curanimcount: {3}, tm-l:{0}, jbi-c: {1}, abc-c: {2}\nException: {4}", TransformationMatrices.Length, jointsById.Count, AttachmentPointByCode.Count, curAnimCount, e); } }
public void loadModelMatrix(Entity entity, float dt, bool isShadowPass) { EntityPlayer entityPlayer = capi.World.Player.Entity; Mat4f.Identity(ModelMat); Mat4f.Translate(ModelMat, ModelMat, (float)(entity.Pos.X - entityPlayer.CameraPos.X), (float)(entity.Pos.Y - entityPlayer.CameraPos.Y), (float)(entity.Pos.Z - entityPlayer.CameraPos.Z)); float rotX = entity.Properties.Client.Shape != null ? entity.Properties.Client.Shape.rotateX : 0; float rotY = entity.Properties.Client.Shape != null ? entity.Properties.Client.Shape.rotateY : 0; float rotZ = entity.Properties.Client.Shape != null ? entity.Properties.Client.Shape.rotateZ : 0; Mat4f.Translate(ModelMat, ModelMat, 0, entity.CollisionBox.Y2 / 2, 0); // Some weird quick random hack to make creatures rotate their bodies up/down when stepping up stuff or falling down if (eagent != null && !entity.Properties.CanClimbAnywhere && !isShadowPass) { if (entity.Properties.Habitat != EnumHabitat.Air && entity.Alive) { if (entity.ServerPos.Y > entity.Pos.Y + 0.04 && !eagent.Controls.IsClimbing && !entity.FeetInLiquid && !entity.Swimming) { stepPitch = Math.Max(-0.5, stepPitch - 3 * dt); } else { if (stepPitch < 0) { stepPitch = Math.Min(0, stepPitch + 3 * dt); } else { if (!entity.OnGround && !entity.FeetInLiquid && !entity.Swimming) { stepPitch = Math.Min(0.5, stepPitch + 4.5f * dt); } else { stepPitch = Math.Max(0, stepPitch - 3 * dt); } } } } else { stepPitch = GameMath.Clamp(entity.Pos.Y - entity.ServerPos.Y + 0.1, 0, 0.3) - GameMath.Clamp(entity.ServerPos.Y - entity.Pos.Y - 0.1, 0, 0.3); } } double[] quat = Quaterniond.Create(); float bodyPitch = entity is EntityPlayer ? 0 : entity.Pos.Pitch; float yaw = entity.Pos.Yaw + (rotY + 90) * GameMath.DEG2RAD; BlockFacing climbonfacing = entity.ClimbingOnFace; // To fix climbing locust rotation weirdnes on east and west faces. Brute forced fix. There's probably a correct solution to this. bool fuglyHack = (entity as EntityAgent)?.Controls.IsClimbing == true && entity.ClimbingOnFace?.Axis == EnumAxis.X; Quaterniond.RotateX(quat, quat, bodyPitch + rotX * GameMath.DEG2RAD + (fuglyHack ? yaw : 0)); Quaterniond.RotateY(quat, quat, fuglyHack ? 0 : yaw); Quaterniond.RotateZ(quat, quat, entity.Pos.Roll + stepPitch + rotZ * GameMath.DEG2RAD + (fuglyHack ? GameMath.PIHALF * (climbonfacing == BlockFacing.WEST ? -1 : 1) : 0)); float[] qf = new float[quat.Length]; for (int i = 0; i < quat.Length; i++) { qf[i] = (float)quat[i]; } Mat4f.Mul(ModelMat, ModelMat, Mat4f.FromQuat(Mat4f.Create(), qf)); float scale = entity.Properties.Client.Size; Mat4f.Scale(ModelMat, ModelMat, new float[] { scale, scale, scale }); Mat4f.Translate(ModelMat, ModelMat, -0.5f, -entity.CollisionBox.Y2 / 2, -0.5f); }