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); } } }
/// <summary> Returns a model view matrix for rendering a carried block on the specified attachment point. </summary> private float[] GetAttachmentPointMatrix(EntityShapeRenderer renderer, AttachmentPointAndPose attachPointAndPose) { var modelMat = Mat4f.CloneIt(renderer.ModelMat); var animModelMat = attachPointAndPose.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); return(modelMat); }
/// <summary> /// Finalizes the matricies with joints assigned by their ID. /// </summary> /// <param name="jointsById"></param> public void FinalizeMatrices(Dictionary <int, AnimationJoint> jointsById) { int k = 0; for (int jointid = 0; jointid < GlobalConstants.MaxAnimatedElements; jointid++) { float[] animTransform = Mat4f.CloneIt(animTransforms[jointid]); if (jointsById.ContainsKey(jointid)) { Mat4f.Mul(animTransform, animTransform, jointsById[jointid].Element.inverseModelTransform); } for (int j = 0; j < 16; j++) { transformationMatrices[k++] = animTransform[j]; } } animTransforms = null; }
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(); } } } }
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!"); } // Don't render anything on the client player if they're in first person. if ((API.World.Player.CameraMode == EnumCameraMode.FirstPerson) && (player == API.World.Player)) { continue; } var entity = player.Entity; var carried = entity.GetCarried(); if (carried == null) { continue; } var renderInfo = GetRenderInfo(carried); 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 = (BlendEntityAnimator)renderer.curAnimator; if (animator == null) { throw new Exception("renderer.curAnimator is null!"); } if (!animator.AttachmentPointByCode.TryGetValue("Back", out var pose)) { return; } var renderApi = API.Render; var isShadowPass = (stage != EnumRenderStage.Opaque); var modelMat = Mat4f.CloneIt(renderer.ModelMat); var viewMat = Array.ConvertAll(API.Render.CameraMatrixOrigin, i => (float)i); var animModelMat = pose.Pose.AnimModelMatrix; Mat4f.Mul(modelMat, modelMat, animModelMat); IStandardShaderProgram prog = null; if (isShadowPass) { renderApi.CurrentActiveShader.BindTexture2D("tex2d", renderInfo.TextureId, 0); } else { prog = renderApi.PreparedStandardShader((int)entity.Pos.X, (int)entity.Pos.Y, (int)entity.Pos.Z); prog.Tex2D = renderInfo.TextureId; prog.AlphaTest = 0.01f; } // Apply attachment point transform. var attach = pose.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, _impliedOffset.X, _impliedOffset.Y, _impliedOffset.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) { Mat4f.Mul(modelMat, API.Render.CurrentShadowProjectionMatrix, modelMat); API.Render.CurrentActiveShader.UniformMatrix("mvpMatrix", modelMat); API.Render.CurrentActiveShader.Uniform("origin", renderer.OriginPos); } else { prog.ModelMatrix = modelMat; prog.ViewMatrix = viewMat; } API.Render.RenderMesh(renderInfo.ModelRef); prog?.Stop(); } }