protected void RenderHeldItem(float dt, bool isShadowPass, bool right) { IRenderAPI rapi = capi.Render; ItemSlot slot = right ? eagent?.RightHandItemSlot : eagent?.LeftHandItemSlot; ItemStack stack = slot?.Itemstack; AttachmentPointAndPose apap = entity.AnimManager.Animator.GetAttachmentPointPose(right ? "RightHand" : "LeftHand"); if (apap == null || stack == null) { return; } AttachmentPoint ap = apap.AttachPoint; ItemRenderInfo renderInfo = rapi.GetItemStackRenderInfo(slot, EnumItemRenderTarget.HandTp); IStandardShaderProgram prog = null; if (renderInfo?.Transform == null) { return; // Happens with unknown items/blocks } ItemModelMat .Set(ModelMat) .Mul(apap.AnimModelMatrix) .Translate(renderInfo.Transform.Origin.X, renderInfo.Transform.Origin.Y, renderInfo.Transform.Origin.Z) .Scale(renderInfo.Transform.ScaleXYZ.X, renderInfo.Transform.ScaleXYZ.Y, renderInfo.Transform.ScaleXYZ.Z) .Translate(ap.PosX / 16f + renderInfo.Transform.Translation.X, ap.PosY / 16f + renderInfo.Transform.Translation.Y, ap.PosZ / 16f + renderInfo.Transform.Translation.Z) .RotateX((float)(ap.RotationX + renderInfo.Transform.Rotation.X) * GameMath.DEG2RAD) .RotateY((float)(ap.RotationY + renderInfo.Transform.Rotation.Y) * GameMath.DEG2RAD) .RotateZ((float)(ap.RotationZ + renderInfo.Transform.Rotation.Z) * GameMath.DEG2RAD) .Translate(-(renderInfo.Transform.Origin.X), -(renderInfo.Transform.Origin.Y), -(renderInfo.Transform.Origin.Z)) ; if (isShadowPass) { rapi.CurrentActiveShader.BindTexture2D("tex2d", renderInfo.TextureId, 0); float[] mvpMat = Mat4f.Mul(ItemModelMat.Values, capi.Render.CurrentModelviewMatrix, ItemModelMat.Values); Mat4f.Mul(mvpMat, capi.Render.CurrentProjectionMatrix, mvpMat); capi.Render.CurrentActiveShader.UniformMatrix("mvpMatrix", mvpMat); capi.Render.CurrentActiveShader.Uniform("origin", new Vec3f()); } else { prog = rapi.StandardShader; prog.Use(); prog.DontWarpVertices = 0; prog.AddRenderFlags = 0; prog.NormalShaded = 1; prog.Tex2D = renderInfo.TextureId; prog.RgbaTint = ColorUtil.WhiteArgbVec; prog.OverlayOpacity = renderInfo.OverlayOpacity; if (renderInfo.OverlayTexture != null && renderInfo.OverlayOpacity > 0) { prog.Tex2dOverlay2D = renderInfo.OverlayTexture.TextureId; prog.OverlayTextureSize = new Vec2f(renderInfo.OverlayTexture.Width, renderInfo.OverlayTexture.Height); prog.BaseTextureSize = new Vec2f(renderInfo.TextureSize.Width, renderInfo.TextureSize.Height); TextureAtlasPosition texPos = rapi.GetTextureAtlasPosition(stack); prog.BaseUvOrigin = new Vec2f(texPos.x1, texPos.y1); } Vec4f lightrgbs = capi.World.BlockAccessor.GetLightRGBs((int)(entity.Pos.X + entity.CollisionBox.X1 - entity.OriginCollisionBox.X1), (int)entity.Pos.Y, (int)(entity.Pos.Z + entity.CollisionBox.Z1 - entity.OriginCollisionBox.Z1)); int temp = (int)stack.Collectible.GetTemperature(capi.World, stack); float[] glowColor = ColorUtil.GetIncandescenceColorAsColor4f(temp); lightrgbs[0] += glowColor[0]; lightrgbs[1] += glowColor[1]; lightrgbs[2] += glowColor[2]; prog.ExtraGlow = GameMath.Clamp((temp - 500) / 3, 0, 255); prog.RgbaAmbientIn = rapi.AmbientColor; prog.RgbaLightIn = lightrgbs; prog.RgbaBlockIn = ColorUtil.WhiteArgbVec; prog.RgbaFogIn = rapi.FogColor; prog.FogMinIn = rapi.FogMin; prog.FogDensityIn = rapi.FogDensity; prog.NormalShaded = renderInfo.NormalShaded ? 1 : 0; prog.ProjectionMatrix = rapi.CurrentProjectionMatrix; prog.ViewMatrix = rapi.CameraMatrixOriginf; prog.ModelMatrix = ItemModelMat.Values; } if (!renderInfo.CullFaces) { rapi.GlDisableCullFace(); } rapi.RenderMesh(renderInfo.ModelRef); if (!renderInfo.CullFaces) { rapi.GlEnableCullFace(); } if (!isShadowPass) { prog.Stop(); AdvancedParticleProperties[] ParticleProperties = stack.Block?.ParticleProperties; if (stack.Block != null && !capi.IsGamePaused) { Vec4f pos = ItemModelMat.TransformVector(new Vec4f(stack.Block.TopMiddlePos.X, stack.Block.TopMiddlePos.Y, stack.Block.TopMiddlePos.Z, 1)); EntityPlayer entityPlayer = capi.World.Player.Entity; accum += dt; if (ParticleProperties != null && ParticleProperties.Length > 0 && accum > 0.025f) { accum = accum % 0.025f; for (int i = 0; i < ParticleProperties.Length; i++) { AdvancedParticleProperties bps = ParticleProperties[i]; bps.basePos.X = pos.X + entity.Pos.X + -(entity.Pos.X - entityPlayer.CameraPos.X); bps.basePos.Y = pos.Y + entity.Pos.Y + -(entity.Pos.Y - entityPlayer.CameraPos.Y); bps.basePos.Z = pos.Z + entity.Pos.Z + -(entity.Pos.Z - entityPlayer.CameraPos.Z); eagent.World.SpawnParticles(bps); } } } } }
public void OnRenderFrame(float deltaTime, EnumRenderStage stage) { if (fallTime < -1) { capi.Event.UnregisterRenderer(this, stage); Dispose(); return; } float percent = fallTime / startFallTime; IRenderAPI rpi = capi.Render; Vec3d camPos = capi.World.Player.Entity.CameraPos; if (isLeaves) { rpi.GlDisableCullFace(); } rpi.GlToggleBlend(true); bool shadowPass = stage != EnumRenderStage.Opaque; IShaderProgram prevProg = rpi.CurrentActiveShader; prevProg?.Stop(); IShaderProgram sProg = shadowPass ? rpi.GetEngineShader(EnumShaderProgram.Shadowmapentityanimated) : rpi.PreparedStandardShader(pos.X, pos.Y, pos.Z); var mat = ModelMat .Identity() .Translate(pos.X - camPos.X, pos.Y - camPos.Y, pos.Z - camPos.Z) ; switch (fallDirection.Code) { case "north": mat.RotateXDeg(GameMath.Max(percent * 90.0f - 90.0f, -90.0f)); break; case "south": mat.Translate(0, 0, 1); mat.RotateXDeg(GameMath.Min(percent * -90.0f + 90.0f, 90.0f)); mat.Translate(0, 0, -1); break; case "east": mat.Translate(1, 0, 1); mat.RotateZDeg(GameMath.Max(percent * 90.0f - 90.0f, -90.0f)); mat.Translate(-1, 0, -1); break; case "west": mat.Translate(0, 0, 1); mat.RotateZDeg(GameMath.Min(percent * -90.0f + 90.0f, 90.0f)); mat.Translate(0, 0, -1); break; default: break; } var matVals = mat.Values; if (!shadowPass) { var prog = (IStandardShaderProgram)sProg; prog.Tex2D = capi.BlockTextureAtlas.AtlasTextureIds[0]; prog.ModelMatrix = matVals; prog.AlphaTest = 0.4f; prog.ViewMatrix = rpi.CameraMatrixOriginf; prog.ProjectionMatrix = rpi.CurrentProjectionMatrix; if (fallTime < 0) { prog.RgbaTint = new Vec4f(1, 1, 1, 1.0f - Math.Abs(fallTime)); } } else { sProg.Use(); sProg.BindTexture2D("entityTex", capi.BlockTextureAtlas.AtlasTextureIds[0], 1); sProg.UniformMatrix("projectionMatrix", rpi.CurrentProjectionMatrix); sProg.UniformMatrix("modelViewMatrix", Mat4f.Mul(new float[16], capi.Render.CurrentModelviewMatrix, matVals)); } rpi.RenderMesh(treeMesh); sProg.Stop(); prevProg?.Use(); fallTime -= deltaTime; }
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); }
// 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 ); } } }
public override void DoRender3DOpaque(float dt, bool isShadowPass) { IRenderAPI rapi = capi.Render; // the value 22 is just trial&error, should probably be something proportial to the // 13ms game ticks (which is the physics frame rate) lerpedPos.X += (entity.Pos.X - lerpedPos.X) * 22 * dt; lerpedPos.Y += (entity.Pos.Y - lerpedPos.Y) * 22 * dt; lerpedPos.Z += (entity.Pos.Z - lerpedPos.Z) * 22 * dt; ItemRenderInfo renderInfo = rapi.GetItemStackRenderInfo(inslot, EnumItemRenderTarget.Ground); if (renderInfo.ModelRef == null) { return; } inslot.Itemstack.Collectible.OnBeforeRender(capi, inslot.Itemstack, EnumItemRenderTarget.Ground, ref renderInfo); IStandardShaderProgram prog = null; LoadModelMatrix(renderInfo, isShadowPass, dt); if (isShadowPass) { rapi.CurrentActiveShader.BindTexture2D("tex2d", renderInfo.TextureId, 0); float[] mvpMat = Mat4f.Mul(ModelMat, capi.Render.CurrentModelviewMatrix, ModelMat); Mat4f.Mul(mvpMat, capi.Render.CurrentProjectionMatrix, mvpMat); capi.Render.CurrentActiveShader.UniformMatrix("mvpMatrix", mvpMat); capi.Render.CurrentActiveShader.Uniform("origin", new Vec3f()); } else { prog = rapi.StandardShader; prog.Use(); prog.Tex2D = renderInfo.TextureId; prog.RgbaTint = ColorUtil.WhiteArgbVec; prog.DontWarpVertices = 0; prog.NormalShaded = 1; if (entity.Swimming) { prog.AddRenderFlags = (entityitem.Itemstack.Collectible.MaterialDensity > 1000 ? 0 : 1) << 12; prog.WaterWaveCounter = capi.Render.ShaderUniforms.WaterWaveCounter; } else { prog.AddRenderFlags = 0; } prog.OverlayOpacity = renderInfo.OverlayOpacity; if (renderInfo.OverlayTexture != null && renderInfo.OverlayOpacity > 0) { prog.Tex2dOverlay2D = renderInfo.OverlayTexture.TextureId; prog.OverlayTextureSize = new Vec2f(renderInfo.OverlayTexture.Width, renderInfo.OverlayTexture.Height); prog.BaseTextureSize = new Vec2f(renderInfo.TextureSize.Width, renderInfo.TextureSize.Height); TextureAtlasPosition texPos = rapi.GetTextureAtlasPosition(entityitem.Itemstack); prog.BaseUvOrigin = new Vec2f(texPos.x1, texPos.y1); } BlockPos pos = entityitem.Pos.AsBlockPos; Vec4f lightrgbs = capi.World.BlockAccessor.GetLightRGBs(pos.X, pos.Y, pos.Z); int temp = (int)entityitem.Itemstack.Collectible.GetTemperature(capi.World, entityitem.Itemstack); float[] glowColor = ColorUtil.GetIncandescenceColorAsColor4f(temp); int extraGlow = GameMath.Clamp((temp - 550) / 2, 0, 255); glowRgb.R = glowColor[0]; glowRgb.G = glowColor[1]; glowRgb.B = glowColor[2]; glowRgb.A = extraGlow / 255f; prog.ExtraGlow = extraGlow; prog.RgbaAmbientIn = rapi.AmbientColor; prog.RgbaLightIn = lightrgbs; prog.RgbaGlowIn = glowRgb; prog.RgbaFogIn = rapi.FogColor; prog.FogMinIn = rapi.FogMin; prog.FogDensityIn = rapi.FogDensity; prog.ExtraGodray = 0; prog.NormalShaded = renderInfo.NormalShaded ? 1 : 0; prog.ProjectionMatrix = rapi.CurrentProjectionMatrix; prog.ViewMatrix = rapi.CameraMatrixOriginf; prog.ModelMatrix = ModelMat; ItemStack stack = entityitem.Itemstack; AdvancedParticleProperties[] ParticleProperties = stack.Block?.ParticleProperties; if (stack.Block != null && !capi.IsGamePaused) { Mat4f.MulWithVec4(ModelMat, new Vec4f(stack.Block.TopMiddlePos.X, stack.Block.TopMiddlePos.Y - 0.4f, stack.Block.TopMiddlePos.Z - 0.5f, 0), particleOutTransform); // No idea why the -0.5f and -0.4f accum += dt; if (ParticleProperties != null && ParticleProperties.Length > 0 && accum > 0.025f) { accum = accum % 0.025f; for (int i = 0; i < ParticleProperties.Length; i++) { AdvancedParticleProperties bps = ParticleProperties[i]; bps.basePos.X = particleOutTransform.X + entity.Pos.X; bps.basePos.Y = particleOutTransform.Y + entity.Pos.Y; bps.basePos.Z = particleOutTransform.Z + entity.Pos.Z; entityitem.World.SpawnParticles(bps); } } } } if (!renderInfo.CullFaces) { rapi.GlDisableCullFace(); } rapi.RenderMesh(renderInfo.ModelRef); if (!renderInfo.CullFaces) { rapi.GlEnableCullFace(); } if (!isShadowPass) { prog.Stop(); } }
/// <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[] 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.Scale(ModelMat, ModelMat, new float[] { scale, scale, scale }); Mat4f.Translate(ModelMat, ModelMat, -0.5f, -entity.CollisionBox.Y2 / 2, -0.5f); tmpModelMat .Set(ModelMat) .Mul(apap.AnimModelMatrix) .Translate(ap.PosX / 16f, ap.PosY / 16f, ap.PosZ / 16f) ; EntityPos epos = entity.LocalPos; 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; collisionTester.ApplyTerrainCollision(entity, posMoved, ref outposition, !(entity is EntityPlayer)); 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); }
private void RenderBackPack(EntityPlayer entity, EntityShapeRenderer rend, bool isShadowPass) { IRenderAPI rpi = api.Render; BlendEntityAnimator bea = rend.curAnimator as BlendEntityAnimator; AttachmentPointAndPose apap = null; bea.AttachmentPointByCode.TryGetValue("Back", out apap); if (apap == null || backPackMeshRef == null) { return; } for (int i = 0; i < 16; i++) { tmpMat[i] = rend.ModelMat[i]; } AttachmentPoint ap = apap.AttachPoint; float[] mat = apap.Pose.AnimModelMatrix; float[] orig = new float[16]; for (int i = 0; i < 16; i++) { orig[i] = (float)api.Render.CameraMatrixOrigin[i]; } if (!isShadowPass) { Mat4f.Mul(tmpMat, orig, tmpMat); } Mat4f.Mul(tmpMat, tmpMat, mat); IStandardShaderProgram prog = null; if (isShadowPass) { rpi.CurrentActiveShader.BindTexture2D("tex2d", backPackTextureId, 0); } else { prog = rpi.PreparedStandardShader((int)entity.Pos.X, (int)entity.Pos.Y, (int)entity.Pos.Z); prog.Tex2D = backPackTextureId; prog.AlphaTest = 0.01f; } Mat4f.Translate(tmpMat, tmpMat, backPackTransform.Origin.X, backPackTransform.Origin.Y, backPackTransform.Origin.Z); Mat4f.Scale(tmpMat, tmpMat, backPackTransform.Scale, backPackTransform.Scale, backPackTransform.Scale); Mat4f.Translate(tmpMat, tmpMat, (float)ap.PosX / 16f + backPackTransform.Translation.X, (float)ap.PosY / 16f + backPackTransform.Translation.Y, (float)ap.PosZ / 16f + backPackTransform.Translation.Z); Mat4f.RotateX(tmpMat, tmpMat, (float)(ap.RotationX + backPackTransform.Rotation.X) * GameMath.DEG2RAD); Mat4f.RotateY(tmpMat, tmpMat, (float)(ap.RotationY + backPackTransform.Rotation.Y) * GameMath.DEG2RAD); Mat4f.RotateZ(tmpMat, tmpMat, (float)(ap.RotationZ + backPackTransform.Rotation.Z) * GameMath.DEG2RAD); Mat4f.Translate(tmpMat, tmpMat, -(backPackTransform.Origin.X), -(backPackTransform.Origin.Y), -(backPackTransform.Origin.Z)); if (isShadowPass) { Mat4f.Mul(tmpMat, api.Render.CurrentShadowProjectionMatrix, tmpMat); api.Render.CurrentActiveShader.UniformMatrix("mvpMatrix", tmpMat); api.Render.CurrentActiveShader.Uniform("origin", rend.OriginPos); } else { prog.ModelViewMatrix = tmpMat; } api.Render.RenderMesh(backPackMeshRef); if (!isShadowPass) { prog.Stop(); } }
public void OnRenderFrame(float dt, EnumRenderStage stage) { if (!ShouldRender || meshref.Disposed || !meshref.Initialized) { 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(); }
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(); } }
void RenderHeldItem(bool isShadowPass) { IRenderAPI rapi = capi.Render; ItemStack stack = (entity as IEntityAgent).RightHandItemSlot?.Itemstack; BlendEntityAnimator bea = curAnimator as BlendEntityAnimator; AttachmentPointAndPose apap = null; bea.AttachmentPointByCode.TryGetValue("RightHand", out apap); if (apap == null || stack == null) { return; } AttachmentPoint ap = apap.AttachPoint; ItemRenderInfo renderInfo = rapi.GetItemStackRenderInfo(stack, EnumItemRenderTarget.HandTp); IStandardShaderProgram prog = null; EntityPlayer entityPlayer = capi.World.Player.Entity; ItemModelMat .Set(ModelMat) .Mul(apap.Pose.AnimModelMatrix) .Translate(renderInfo.Transform.Origin.X, renderInfo.Transform.Origin.Y, renderInfo.Transform.Origin.Z) .Scale(renderInfo.Transform.ScaleXYZ.X, renderInfo.Transform.ScaleXYZ.Y, renderInfo.Transform.ScaleXYZ.Z) .Translate(ap.PosX / 16f + renderInfo.Transform.Translation.X, ap.PosY / 16f + renderInfo.Transform.Translation.Y, ap.PosZ / 16f + renderInfo.Transform.Translation.Z) .RotateX((float)(ap.RotationX + renderInfo.Transform.Rotation.X) * GameMath.DEG2RAD) .RotateY((float)(ap.RotationY + renderInfo.Transform.Rotation.Y) * GameMath.DEG2RAD) .RotateZ((float)(ap.RotationZ + renderInfo.Transform.Rotation.Z) * GameMath.DEG2RAD) .Translate(-(renderInfo.Transform.Origin.X), -(renderInfo.Transform.Origin.Y), -(renderInfo.Transform.Origin.Z)) ; if (isShadowPass) { rapi.CurrentActiveShader.BindTexture2D("tex2d", renderInfo.TextureId, 0); float[] mvpMat = Mat4f.Mul(ItemModelMat.Values, capi.Render.CurrentModelviewMatrix, ItemModelMat.Values); Mat4f.Mul(mvpMat, capi.Render.CurrentProjectionMatrix, mvpMat); capi.Render.CurrentActiveShader.UniformMatrix("mvpMatrix", mvpMat); capi.Render.CurrentActiveShader.Uniform("origin", new Vec3f()); } else { prog = rapi.StandardShader; prog.Use(); prog.WaterWave = 0; prog.Tex2D = renderInfo.TextureId; prog.RgbaTint = ColorUtil.WhiteArgbVec; BlockPos pos = entity.Pos.AsBlockPos; Vec4f lightrgbs = capi.World.BlockAccessor.GetLightRGBs(pos.X, pos.Y, pos.Z); int temp = (int)stack.Collectible.GetTemperature(capi.World, stack); float[] glowColor = ColorUtil.GetIncandescenceColorAsColor4f(temp); lightrgbs[0] += 2 * glowColor[0]; lightrgbs[1] += 2 * glowColor[1]; lightrgbs[2] += 2 * glowColor[2]; prog.ExtraGlow = GameMath.Clamp((temp - 500) / 3, 0, 255); prog.RgbaAmbientIn = rapi.AmbientColor; prog.RgbaLightIn = lightrgbs; prog.RgbaBlockIn = ColorUtil.WhiteArgbVec; prog.RgbaFogIn = rapi.FogColor; prog.FogMinIn = rapi.FogMin; prog.FogDensityIn = rapi.FogDensity; prog.ProjectionMatrix = rapi.CurrentProjectionMatrix; prog.ViewMatrix = rapi.CameraMatrixOriginf; prog.ModelMatrix = ItemModelMat.Values; } if (!renderInfo.CullFaces) { rapi.GlDisableCullFace(); } rapi.RenderMesh(renderInfo.ModelRef); if (!renderInfo.CullFaces) { rapi.GlEnableCullFace(); } if (!isShadowPass) { prog.Stop(); } }