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 UpdateLightAndTransformMatrix(float[] values, int index, Vec3f distToCamera, Vec4f lightRgba, float rotX, float rotY, float rotZ) { Mat4f.Identity(tmpMat); Mat4f.Translate(tmpMat, tmpMat, distToCamera.X, distToCamera.Y, distToCamera.Z); Mat4f.Translate(tmpMat, tmpMat, 0.5f, 0.5f, 0.5f); quat[0] = 0; quat[1] = 0; quat[2] = 0; quat[3] = 1; Quaterniond.RotateX(quat, quat, rotX); Quaterniond.RotateY(quat, quat, rotY); Quaterniond.RotateZ(quat, quat, rotZ); for (int i = 0; i < quat.Length; i++) { qf[i] = (float)quat[i]; } Mat4f.Mul(tmpMat, tmpMat, Mat4f.FromQuat(rotMat, qf)); Mat4f.Translate(tmpMat, tmpMat, -0.5f, -0.5f, -0.5f); values[index * 20] = lightRgba.R; values[index * 20 + 1] = lightRgba.G; values[index * 20 + 2] = lightRgba.B; values[index * 20 + 3] = lightRgba.A; for (int i = 0; i < 16; i++) { values[index * 20 + i + 4] = tmpMat[i]; } }
private void LoadModelMatrix(ItemRenderInfo renderInfo, bool isShadowPass) { IRenderAPI rapi = capi.Render; IEntityPlayer entityPlayer = capi.World.Player.Entity; Mat4f.Identity(ModelMat); Mat4f.Translate(ModelMat, ModelMat, (float)(entityitem.Pos.X - entityPlayer.CameraPos.X), (float)(entityitem.Pos.Y - entityPlayer.CameraPos.Y), (float)(entityitem.Pos.Z - entityPlayer.CameraPos.Z) ); float sizeX = 0.2f * renderInfo.Transform.ScaleXYZ.X; float sizeY = 0.2f * renderInfo.Transform.ScaleXYZ.Y; float sizeZ = 0.2f * renderInfo.Transform.ScaleXYZ.Z; long ellapseMs = capi.World.ElapsedMilliseconds; if (entity.Collided || entity.Swimming || capi.IsGamePaused) { touchGroundMS = ellapseMs; } float easeIn = Math.Min(1, (ellapseMs - touchGroundMS) / 200); float angleMs = Math.Max(ellapseMs - touchGroundMS, 0) * easeIn; float yangle = angleMs / 7f; float xangle = angleMs / 7f; float zangle = angleMs / 7f; float dx = 0, dz = 0; if (entity.Swimming) { float diff = 1; if (entityitem.Itemstack.Collectible.MaterialDensity > 1000) { dx = GameMath.Sin((float)(ellapseMs / 1000.0)) / 50; dz = -GameMath.Sin((float)(ellapseMs / 3000.0)) / 50; diff = 0.1f; } xangle = GameMath.Sin((float)(ellapseMs / 1000.0)) * 8 * diff; yangle = GameMath.Cos((float)(ellapseMs / 2000.0)) * 3 * diff; zangle = -GameMath.Sin((float)(ellapseMs / 3000.0)) * 8 * diff; } Mat4f.Translate(ModelMat, ModelMat, dx + renderInfo.Transform.Translation.X, renderInfo.Transform.Translation.Y, dz + renderInfo.Transform.Translation.Z); Mat4f.Scale(ModelMat, ModelMat, new float[] { sizeX + scaleRand, sizeY + scaleRand, sizeZ + scaleRand }); Mat4f.RotateY(ModelMat, ModelMat, GameMath.DEG2RAD * (renderInfo.Transform.Rotation.Y + yangle) + (renderInfo.Transform.Rotate ? yRotRand : 0)); Mat4f.RotateZ(ModelMat, ModelMat, GameMath.DEG2RAD * (renderInfo.Transform.Rotation.Z + zangle)); Mat4f.RotateX(ModelMat, ModelMat, GameMath.DEG2RAD * (renderInfo.Transform.Rotation.X + xangle)); Mat4f.Translate(ModelMat, ModelMat, -renderInfo.Transform.Origin.X, -renderInfo.Transform.Origin.Y, -renderInfo.Transform.Origin.Z); }
/// <summary> /// The event fired when the game ticks. /// </summary> /// <param name="dt"></param> public virtual void OnFrame(float dt) { if (entity.HeadYaw != 0 || entity.HeadPitch != 0) { Mat4f.Identity(HeadLocalMatrix); Mat4f.RotateY(HeadLocalMatrix, HeadLocalMatrix, entity.HeadYaw); Mat4f.RotateZ(HeadLocalMatrix, HeadLocalMatrix, entity.HeadPitch); ApplyTransformToElement(HeadLocalMatrix, HeadGlobalMatrix, HeadGlobalMatrixInverted, HeadElement); } }
protected float[] UpdateLightAndTransformMatrix(float[] values, int index, Vec3f distToCamera, Vec4f lightRgba, float rotX, float rotY, float rotZ, Vec3f axis, float[] xtraTransform) { if (xtraTransform == null) { Mat4f.Identity(tmpMat); Mat4f.Translate(tmpMat, tmpMat, distToCamera.X + axis.X, distToCamera.Y + axis.Y, distToCamera.Z + axis.Z); } else { Mat4f.Translate(tmpMat, tmpMat, axis.X, axis.Y, axis.Z); } quat[0] = 0; quat[1] = 0; quat[2] = 0; quat[3] = 1; if (rotX != 0f) { Quaterniond.RotateX(quat, quat, rotX); } if (rotY != 0f) { Quaterniond.RotateY(quat, quat, rotY); } if (rotZ != 0f) { Quaterniond.RotateZ(quat, quat, rotZ); } for (int i = 0; i < quat.Length; i++) { qf[i] = (float)quat[i]; } Mat4f.Mul(tmpMat, tmpMat, Mat4f.FromQuat(rotMat, qf)); Mat4f.Translate(tmpMat, tmpMat, -axis.X, -axis.Y, -axis.Z); //if (xtraTransform != null) Mat4f.Mul(tmpMat, tmpMat, xtraTransform); int j = index * 20; values[j] = lightRgba.R; values[++j] = lightRgba.G; values[++j] = lightRgba.B; values[++j] = lightRgba.A; for (int i = 0; i < 16; i++) { values[++j] = tmpMat[i]; } return(tmpMat); }
protected virtual void UpdateLightAndTransformMatrix(float[] values, int index, Vec3f distToCamera, Vec4f lightRgba, float rotX, float rotY, float rotZ) { // This commented-out code could allow individual fruits to change size as they grow, in future: But ... Saraty asked not to implement because the pixel density will change //float scale = 1f; //Mat4f.Identity_Scaled(tmpMat, scale); //Mat4f.Translate(tmpMat, tmpMat, distToCamera.X / scale, distToCamera.Y / scale, distToCamera.Z / scale); Mat4f.Identity(tmpMat); Mat4f.Translate(tmpMat, tmpMat, distToCamera.X, distToCamera.Y, distToCamera.Z); quat[0] = 0; quat[1] = 0; quat[2] = 0; quat[3] = 1; if (rotX != 0f) { Quaterniond.RotateX(quat, quat, rotX); } if (rotY != 0f) { Quaterniond.RotateY(quat, quat, rotY); } if (rotZ != 0f) { Quaterniond.RotateZ(quat, quat, rotZ); } for (int i = 0; i < quat.Length; i++) { qf[i] = (float)quat[i]; } Mat4f.Mul(tmpMat, tmpMat, Mat4f.FromQuat(rotMat, qf)); int j = index * 20; values[j] = lightRgba.R; values[++j] = lightRgba.G; values[++j] = lightRgba.B; values[++j] = lightRgba.A; for (int i = 0; i < 16; i++) { values[++j] = tmpMat[i]; } }
public void loadModelMatrix(Entity entity, float dt, bool isShadowPass) { prevYAccum += dt; if (prevYAccum > 1f / 5f) { prevYAccum = 0; prevY = entity.Pos.Y; } EntityPlayer entityPlayer = capi.World.Player.Entity; Mat4f.Identity(ModelMat); if (entity is IMountableSupplier ims && ims.IsMountedBy(entityPlayer)) { var mountoffset = ims.GetMountOffset(entityPlayer); Mat4f.Translate(ModelMat, ModelMat, -mountoffset.X, -mountoffset.Y, -mountoffset.Z); }
protected void loadModelMatrixForGui(Entity entity, double posX, double posY, double posZ, double yawDelta, float size) { Mat4f.Identity(ModelMat); Mat4f.Translate(ModelMat, ModelMat, (float)posX, (float)posY, (float)posZ); Mat4f.Translate(ModelMat, ModelMat, size, 2 * size, 0); 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.RotateX(ModelMat, ModelMat, GameMath.PI + rotX * GameMath.DEG2RAD); Mat4f.RotateY(ModelMat, ModelMat, (float)yawDelta + rotY * GameMath.DEG2RAD); Mat4f.RotateZ(ModelMat, ModelMat, rotZ * GameMath.DEG2RAD); float scale = entity.Properties.Client.Size * size; Mat4f.Scale(ModelMat, ModelMat, new float[] { scale, scale, scale }); Mat4f.Translate(ModelMat, ModelMat, -0.5f, 0f, -0.5f); }
public void loadModelMatrixForPlayer(Entity entity, bool isSelf, float dt) { EntityPlayer entityPlayer = capi.World.Player.Entity; EntityPlayer eplr = entity as EntityPlayer; Mat4f.Identity(ModelMat); if (!isSelf) { 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; float bodyYaw = 0; if (eagent != null) { float yawDist = GameMath.AngleRadDistance(bodyYawLerped, eagent.BodyYaw); bodyYawLerped += GameMath.Clamp(yawDist, -dt * 8, dt * 8); bodyYaw = bodyYawLerped; } float bodyPitch = eplr == null ? 0 : eplr.WalkPitch; Mat4f.RotateX(ModelMat, ModelMat, entity.Pos.Roll + rotX * GameMath.DEG2RAD); Mat4f.RotateY(ModelMat, ModelMat, bodyYaw + (180 + rotY) * GameMath.DEG2RAD); Mat4f.RotateZ(ModelMat, ModelMat, bodyPitch + rotZ * GameMath.DEG2RAD); //float str = (float)entity.Pos.Motion.Length(); //Mat4f.RotateX(ModelMat, ModelMat, eplr.Controls.Left ? str : -str); float scale = entity.Properties.Client.Size; Mat4f.Scale(ModelMat, ModelMat, new float[] { scale, scale, scale }); Mat4f.Translate(ModelMat, ModelMat, -0.5f, 0, -0.5f); }
public void loadModelMatrixForPlayer(Entity entity, bool isSelf) { EntityPlayer entityPlayer = capi.World.Player.Entity; Mat4f.Identity(ModelMat); if (!isSelf) { 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.RotateX(ModelMat, ModelMat, entity.Pos.Roll + rotX * GameMath.DEG2RAD); Mat4f.RotateY(ModelMat, ModelMat, bodyYaw + (180 + rotY) * GameMath.DEG2RAD); Mat4f.RotateZ(ModelMat, ModelMat, entityPlayer.WalkPitch + rotZ * GameMath.DEG2RAD); float scale = entity.Properties.Client.Size; Mat4f.Scale(ModelMat, ModelMat, new float[] { scale, scale, scale }); Mat4f.Translate(ModelMat, ModelMat, -0.5f, 0, -0.5f); }
/// <summary> /// Set up tmpMat - expected to be used with a later call to UpdateLightAndTransformMatrix passing in tmpMat as an initial matrix /// </summary> private void TransformMatrix(Vec3f distToCamera, float rotX, float rotZ, Vec3f axis) { Mat4f.Identity(tmpMat); Mat4f.Translate(tmpMat, tmpMat, distToCamera.X + axis.X, distToCamera.Y + axis.Y, distToCamera.Z + axis.Z); quat[0] = 0; quat[1] = 0; quat[2] = 0; quat[3] = 1; if (rotX != 0f) { Quaterniond.RotateX(quat, quat, rotX); } if (rotZ != 0f) { Quaterniond.RotateZ(quat, quat, rotZ); } for (int i = 0; i < quat.Length; i++) { qf[i] = (float)quat[i]; } Mat4f.Mul(tmpMat, tmpMat, Mat4f.FromQuat(rotMat, qf)); Mat4f.Translate(tmpMat, tmpMat, -axis.X, -axis.Y, -axis.Z); }
private void LoadModelMatrix(ItemRenderInfo renderInfo, bool isShadowPass, float dt) { EntityPlayer entityPlayer = capi.World.Player.Entity; Mat4f.Identity(ModelMat); Mat4f.Translate(ModelMat, ModelMat, (float)(lerpedPos.X - entityPlayer.CameraPos.X), (float)(lerpedPos.Y - entityPlayer.CameraPos.Y), (float)(lerpedPos.Z - entityPlayer.CameraPos.Z) ); float sizeX = 0.2f * renderInfo.Transform.ScaleXYZ.X; float sizeY = 0.2f * renderInfo.Transform.ScaleXYZ.Y; float sizeZ = 0.2f * renderInfo.Transform.ScaleXYZ.Z; float dx = 0, dz = 0; if (!isShadowPass) { long ellapseMs = capi.World.ElapsedMilliseconds; bool freefall = !(entity.Collided || entity.Swimming || capi.IsGamePaused); if (!freefall) { touchGroundMS = ellapseMs; } if (entity.Collided) { xangle *= 0.55f; yangle *= 0.55f; zangle *= 0.55f; } else if (rotateWhenFalling) { float easeIn = Math.Min(1, (ellapseMs - touchGroundMS) / 200); float angleGain = freefall ? 1000 * dt / 7 * easeIn : 0; yangle += angleGain; xangle += angleGain; zangle += angleGain; } if (entity.Swimming) { float diff = 1; if (entityitem.Itemstack.Collectible.MaterialDensity > 1000) { dx = GameMath.Sin((float)(ellapseMs / 1000.0)) / 50; dz = -GameMath.Sin((float)(ellapseMs / 3000.0)) / 50; diff = 0.1f; } xangle = GameMath.Sin((float)(ellapseMs / 1000.0)) * 8 * diff; yangle = GameMath.Cos((float)(ellapseMs / 2000.0)) * 3 * diff; zangle = -GameMath.Sin((float)(ellapseMs / 3000.0)) * 8 * diff; } } Mat4f.Translate(ModelMat, ModelMat, dx + renderInfo.Transform.Translation.X, renderInfo.Transform.Translation.Y, dz + renderInfo.Transform.Translation.Z); Mat4f.Scale(ModelMat, ModelMat, new float[] { sizeX + scaleRand, sizeY + scaleRand, sizeZ + scaleRand }); Mat4f.RotateY(ModelMat, ModelMat, GameMath.DEG2RAD * (renderInfo.Transform.Rotation.Y + yangle) + (renderInfo.Transform.Rotate ? yRotRand : 0)); Mat4f.RotateZ(ModelMat, ModelMat, GameMath.DEG2RAD * (renderInfo.Transform.Rotation.Z + zangle)); Mat4f.RotateX(ModelMat, ModelMat, GameMath.DEG2RAD * (renderInfo.Transform.Rotation.X + xangle)); Mat4f.Translate(ModelMat, ModelMat, -renderInfo.Transform.Origin.X, -renderInfo.Transform.Origin.Y, -renderInfo.Transform.Origin.Z); }
public void OnRenderFrame(float dt, EnumRenderStage stage) { if (!ShouldRender) { return; } animator.OnFrame(activeAnimationsByAnimCode, dt); EntityPlayer entityPlayer = capi.World.Player.Entity; Mat4f.Identity(ModelMat); Mat4f.Translate(ModelMat, ModelMat, (float)(pos.X - entityPlayer.CameraPos.X), (float)(pos.Y - entityPlayer.CameraPos.Y), (float)(pos.Z - entityPlayer.CameraPos.Z)); Mat4f.Translate(ModelMat, ModelMat, 0.5f, 0, 0.5f); Mat4f.RotateY(ModelMat, ModelMat, rotation.Y * GameMath.DEG2RAD); Mat4f.Translate(ModelMat, ModelMat, -0.5f, 0, -0.5f); IRenderAPI rpi = capi.Render; IShaderProgram prevProg = rpi.CurrentActiveShader; prevProg?.Stop(); IShaderProgram prog = rpi.GetEngineShader(EnumShaderProgram.Entityanimated); prog.Use(); prog.Uniform("rgbaAmbientIn", rpi.AmbientColor); prog.Uniform("rgbaFogIn", rpi.FogColor); prog.Uniform("fogMinIn", rpi.FogMin); prog.Uniform("fogDensityIn", rpi.FogDensity); prog.BindTexture2D("entityTex", textureId, 0); prog.Uniform("alphaTest", 0.1f); prog.UniformMatrix("projectionMatrix", rpi.CurrentProjectionMatrix); rpi.GlToggleBlend(true, EnumBlendMode.Standard); Vec4f lightrgbs = capi.World.BlockAccessor.GetLightRGBs((int)pos.X, (int)pos.Y, (int)pos.Z); prog.Uniform("rgbaLightIn", lightrgbs); //prog.Uniform("extraGlow", entity.Properties.Client.GlowLevel); prog.UniformMatrix("modelMatrix", ModelMat); prog.UniformMatrix("viewMatrix", rpi.CameraMatrixOriginf); prog.Uniform("addRenderFlags", 0); prog.Uniform("windWaveIntensity", (float)0); /*color[0] = (entity.RenderColor >> 16 & 0xff) / 255f; * color[1] = ((entity.RenderColor >> 8) & 0xff) / 255f; * color[2] = ((entity.RenderColor >> 0) & 0xff) / 255f; * color[3] = ((entity.RenderColor >> 24) & 0xff) / 255f; * * prog.Uniform("renderColor", color);*/ prog.Uniform("renderColor", ColorUtil.WhiteArgbVec); prog.UniformMatrices( "elementTransforms", GlobalConstants.MaxAnimatedElements, animator.Matrices ); capi.Render.RenderMesh(meshref); prog.Stop(); prevProg?.Use(); }
public void OnRenderFrame(float dt, EnumRenderStage stage) { if (!ShouldRender) { return; } bool shadowPass = stage != EnumRenderStage.Opaque; EntityPlayer entityPlayer = capi.World.Player.Entity; Mat4f.Identity(ModelMat); Mat4f.Translate(ModelMat, ModelMat, (float)(pos.X - entityPlayer.CameraPos.X), (float)(pos.Y - entityPlayer.CameraPos.Y), (float)(pos.Z - entityPlayer.CameraPos.Z)); Mat4f.Translate(ModelMat, ModelMat, 0.5f, 0, 0.5f); Mat4f.RotateY(ModelMat, ModelMat, rotation.Y * GameMath.DEG2RAD); Mat4f.Translate(ModelMat, ModelMat, -0.5f, 0, -0.5f); IRenderAPI rpi = capi.Render; IShaderProgram prevProg = rpi.CurrentActiveShader; prevProg?.Stop(); IShaderProgram prog = rpi.GetEngineShader(shadowPass ? EnumShaderProgram.Shadowmapentityanimated : EnumShaderProgram.Entityanimated); prog.Use(); Vec4f lightrgbs = capi.World.BlockAccessor.GetLightRGBs((int)pos.X, (int)pos.Y, (int)pos.Z); rpi.GlToggleBlend(true, EnumBlendMode.Standard); if (!shadowPass) { prog.Uniform("rgbaAmbientIn", rpi.AmbientColor); prog.Uniform("rgbaFogIn", rpi.FogColor); prog.Uniform("fogMinIn", rpi.FogMin); prog.Uniform("fogDensityIn", rpi.FogDensity); prog.Uniform("rgbaLightIn", lightrgbs); prog.Uniform("renderColor", ColorUtil.WhiteArgbVec); prog.Uniform("alphaTest", 0.1f); prog.UniformMatrix("modelMatrix", ModelMat); prog.UniformMatrix("viewMatrix", rpi.CameraMatrixOriginf); prog.Uniform("windWaveIntensity", (float)0); prog.Uniform("skipRenderJointId", -2); prog.Uniform("skipRenderJointId2", -2); prog.Uniform("glitchEffectStrength", 0f); } else { prog.UniformMatrix("modelViewMatrix", Mat4f.Mul(new float[16], capi.Render.CurrentModelviewMatrix, ModelMat)); } prog.BindTexture2D("entityTex", textureId, 0); prog.UniformMatrix("projectionMatrix", rpi.CurrentProjectionMatrix); prog.Uniform("addRenderFlags", 0); prog.UniformMatrices( "elementTransforms", GlobalConstants.MaxAnimatedElements, animator.Matrices ); capi.Render.RenderMesh(meshref); prog.Stop(); prevProg?.Use(); }
// 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> /// Generates a look-at matrix with the given eye position, focal point, and up axis /// </summary> /// <param name="output">{mat4} out mat4 frustum matrix will be written into</param> /// <param name="eye">{vec3} eye Position of the viewer</param> /// <param name="center">{vec3} center Point the viewer is looking at</param> /// <param name="up">{vec3} up vec3 pointing up</param> /// <returns>{mat4} out</returns> public static float[] LookAt(float[] output, float[] eye, float[] center, float[] up) { float x0; float x1; float x2; float y0; float y1; float y2; float z0; float z1; float z2; float len; float eyex = eye[0]; float eyey = eye[1]; float eyez = eye[2]; float upx = up[0]; float upy = up[1]; float upz = up[2]; float centerx = center[0]; float centery = center[1]; float centerz = center[2]; if (GlMatrixMathf.Abs(eyex - centerx) < GlMatrixMathf.GLMAT_EPSILON() && GlMatrixMathf.Abs(eyey - centery) < GlMatrixMathf.GLMAT_EPSILON() && GlMatrixMathf.Abs(eyez - centerz) < GlMatrixMathf.GLMAT_EPSILON()) { return(Mat4f.Identity(output)); } z0 = eyex - centerx; z1 = eyey - centery; z2 = eyez - centerz; len = 1 / GameMath.Sqrt(z0 * z0 + z1 * z1 + z2 * z2); z0 *= len; z1 *= len; z2 *= len; x0 = upy * z2 - upz * z1; x1 = upz * z0 - upx * z2; x2 = upx * z1 - upy * z0; len = GameMath.Sqrt(x0 * x0 + x1 * x1 + x2 * x2); if (len == 0) { x0 = 0; x1 = 0; x2 = 0; } else { len = 1 / len; x0 *= len; x1 *= len; x2 *= len; } y0 = z1 * x2 - z2 * x1; y1 = z2 * x0 - z0 * x2; y2 = z0 * x1 - z1 * x0; len = GameMath.Sqrt(y0 * y0 + y1 * y1 + y2 * y2); if (len == 0) { y0 = 0; y1 = 0; y2 = 0; } else { len = 1 / len; y0 *= len; y1 *= len; y2 *= len; } output[0] = x0; output[1] = y0; output[2] = z0; output[3] = 0; output[4] = x1; output[5] = y1; output[6] = z1; output[7] = 0; output[8] = x2; output[9] = y2; output[10] = z2; output[11] = 0; output[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); output[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); output[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); output[15] = 1; return(output); }
public Matrixf Identity() { Mat4f.Identity(Values); return(this); }
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); }
/// <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 int UpdateMesh(MeshData updateMesh, float dt) { var cfloats = updateMesh.CustomFloats; Vec3d campos = capi.World.Player.Entity.CameraPos; int basep = cfloats.Count; Vec4f lightRgba = api.World.BlockAccessor.GetLightRGBs(Constraints[Constraints.Count / 2].Point1.Pos.AsBlockPos); if (clothType == EnumClothType.Rope) { for (int i = 0; i < Constraints.Count; i++) { ClothConstraint cc = Constraints[i]; Vec3d start = cc.Point1.Pos; Vec3d end = cc.Point2.Pos; double dX = start.X - end.X; double dY = start.Y - end.Y; double dZ = start.Z - end.Z; float yaw = (float)Math.Atan2(dX, dZ) + GameMath.PIHALF; float pitch = (float)Math.Atan2(Math.Sqrt(dZ * dZ + dX * dX), dY) + GameMath.PIHALF; double nowx = start.X + (start.X - end.X) / 2; double nowy = start.Y + (start.Y - end.Y) / 2; double nowz = start.Z + (start.Z - end.Z) / 2; cc.renderCenterPos.X += (nowx - cc.renderCenterPos.X) * dt * 20; cc.renderCenterPos.Y += (nowy - cc.renderCenterPos.Y) * dt * 20; cc.renderCenterPos.Z += (nowz - cc.renderCenterPos.Z) * dt * 20; distToCam.Set( (float)(cc.renderCenterPos.X - campos.X), (float)(cc.renderCenterPos.Y - campos.Y), (float)(cc.renderCenterPos.Z - campos.Z) ); Mat4f.Identity(tmpMat); Mat4f.Translate(tmpMat, tmpMat, 0, 1 / 32f, 0); Mat4f.Translate(tmpMat, tmpMat, distToCam.X, distToCam.Y, distToCam.Z); Mat4f.RotateY(tmpMat, tmpMat, yaw); Mat4f.RotateZ(tmpMat, tmpMat, pitch); float roll = i / 5f; Mat4f.RotateX(tmpMat, tmpMat, roll); Mat4f.Scale(tmpMat, tmpMat, new float[] { (float)cc.SpringLength, 1, 1 }); // + (float)Math.Sin(api.World.ElapsedMilliseconds / 1000f) * 0.1f Mat4f.Translate(tmpMat, tmpMat, -1.5f, -1 / 32f, -0.5f); // not sure why the -1.5 here instead of -0.5 int j = basep + i * 20; cfloats.Values[j++] = lightRgba.R; cfloats.Values[j++] = lightRgba.G; cfloats.Values[j++] = lightRgba.B; cfloats.Values[j++] = lightRgba.A; for (int k = 0; k < 16; k++) { cfloats.Values[j + k] = tmpMat[k]; } } } return(Constraints.Count); }