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