protected override void DrawModel(Player p) { // TODO: using 'is' is ugly, but means we can avoid creating // a string every single time held block changes. if (p is FakePlayer) { Player realP = game.LocalPlayer; col = game.World.IsLit(realP.EyePosition) ? game.World.Env.Sunlight : game.World.Env.Shadowlight; // Adjust pitch so angle when looking straight down is 0. float adjPitch = realP.PitchDegrees - 90; if (adjPitch < 0) { adjPitch += 360; } // Adjust colour so held block is brighter when looking straght up float t = Math.Abs(adjPitch - 180) / 180; float colScale = Utils.Lerp(0.9f, 0.7f, t); col = FastColour.Scale(col, colScale); block = ((FakePlayer)p).Block; } else { block = Utils.FastByte(p.ModelName); } CalcState(block); colPacked = col.Pack(); if (game.BlockInfo.IsAir[block]) { return; } lastTexId = -1; atlas = game.TerrainAtlas1D; bool sprite = game.BlockInfo.IsSprite[block]; DrawParts(sprite); if (index == 0) { return; } IGraphicsApi api = game.Graphics; api.BindTexture(lastTexId); TransformVertices(); if (sprite) { api.FaceCulling = true; } UpdateVB(); if (sprite) { api.FaceCulling = false; } }
void CalculateCaretData() { if (caretPos >= buffer.Length) { caretPos = -1; } buffer.MakeCoords(caretPos, partLens, out indexX, out indexY); DrawTextArgs args = new DrawTextArgs(null, font, true); if (indexX == LineLength) { caretTex.X1 = 10 + sizes[indexY].Width; caretCol = FastColour.Yellow; caretTex.Width = defaultCaretWidth; } else { args.Text = parts[indexY].Substring(0, indexX); Size trimmedSize = game.Drawer2D.MeasureChatSize(ref args); if (indexY == 0) { trimmedSize.Width += defaultWidth; } caretTex.X1 = 10 + trimmedSize.Width; caretCol = FastColour.Scale(FastColour.White, 0.8f); string line = parts[indexY]; args.Text = indexX < line.Length ? new String(line[indexX], 1) : ""; caretTex.Width = indexX < line.Length ? game.Drawer2D.MeasureChatSize(ref args).Width : defaultCaretWidth; } caretTex.Y1 = sizes[0].Height * indexY + Y; CalcCaretColour(); }
protected void DrawPart(ModelPart part) { VertexP3fT2fC4b vertex = default(VertexP3fT2fC4b); for (int i = 0; i < part.Count; i++) { ModelVertex v = vertices[part.Offset + i]; float t = cosYaw * v.X - sinYaw * v.Z; v.Z = sinYaw * v.X + cosYaw * v.Z; v.X = t; // Inlined RotY v.X *= scale; v.Y *= scale; v.Z *= scale; v.X += pos.X; v.Y += pos.Y; v.Z += pos.Z; FastColour col = part.Count == boxVertices ? cols[i >> 2] : FastColour.Scale(this.col, 0.7f); vertex.X = v.X; vertex.Y = v.Y; vertex.Z = v.Z; vertex.R = col.R; vertex.G = col.G; vertex.B = col.B; vertex.A = 255; vertex.U = v.U * uScale; vertex.V = v.V * vScale; int quadI = i & 3; if (quadI == 0 || quadI == 3) { vertex.V -= 0.01f * vScale; } if (quadI == 2 || quadI == 3) { vertex.U -= 0.01f * uScale; } cache.vertices[index++] = vertex; } }
/// <summary> Renders the model based on the given entity's position and orientation. </summary> public void Render(Player p) { index = 0; pos = p.Position; if (Bobbing) { pos.Y += p.anim.bobYOffset; } World map = game.World; col = game.World.IsLit(p.EyePosition) ? map.Env.Sunlight : map.Env.Shadowlight; uScale = 1 / 64f; vScale = 1 / 32f; scale = p.ModelScale; cols[0] = col; cols[1] = FastColour.Scale(col, FastColour.ShadeYBottom); cols[2] = FastColour.Scale(col, FastColour.ShadeZ); cols[3] = cols[2]; cols[4] = FastColour.Scale(col, FastColour.ShadeX); cols[5] = cols[4]; cosYaw = (float)Math.Cos(p.YawDegrees * Utils.Deg2Rad); sinYaw = (float)Math.Sin(p.YawDegrees * Utils.Deg2Rad); cosHead = (float)Math.Cos(p.HeadYawDegrees * Utils.Deg2Rad); sinHead = (float)Math.Sin(p.HeadYawDegrees * Utils.Deg2Rad); graphics.SetBatchFormat(VertexFormat.P3fT2fC4b); DrawModel(p); }
/// <summary> Calculates the location and size of the caret character </summary> public void UpdateCaret() { int maxChars = UsedLines * MaxCharsPerLine; if (caret >= maxChars) { caret = -1; } Text.GetCoords(caret, lines, out caretX, out caretY); DrawTextArgs args = new DrawTextArgs(null, font, false); IDrawer2D drawer = game.Drawer2D; caretAccumulator = 0; if (caretX == MaxCharsPerLine) { caretTex.X1 = X + Padding + lineSizes[caretY].Width; caretColour = FastColour.Yellow; caretTex.Width = (ushort)caretWidth; } else { args.Text = lines[caretY].Substring(0, caretX); Size trimmedSize = drawer.MeasureSize(ref args); if (caretY == 0) { trimmedSize.Width += prefixWidth; } caretTex.X1 = X + Padding + trimmedSize.Width; caretColour = FastColour.Scale(FastColour.White, 0.8f); string line = lines[caretY]; if (caretX < line.Length) { args.Text = new String(line[caretX], 1); args.UseShadow = true; caretTex.Width = (ushort)drawer.MeasureSize(ref args).Width; } else { caretTex.Width = (ushort)caretWidth; } } caretTex.Y1 = lineSizes[0].Height * caretY + inputTex.Y1 + 2; // Update the colour of the caret char code = GetLastColour(caretX, caretY); if (code != '\0') { caretColour = IDrawer2D.GetCol(code); } }
unsafe void CalculatePalette(int *palette) { for (int i = 0; i < Palette.Length; i++) { FastColour col = Palette[i]; if (!Active) { col = FastColour.Scale(col, 0.7f); } palette[i] = col.ToArgb(); } }
protected override void DrawModel(Player p) { // TODO: using 'is' is ugly, but means we can avoid creating // a string every single time held block changes. if (p is FakePlayer) { Vector3I eyePos = Vector3I.Floor(game.LocalPlayer.EyePosition); FastColour baseCol = game.Map.IsLit(eyePos) ? game.Map.Sunlight : game.Map.Shadowlight; col = FastColour.Scale(baseCol, 0.8f); block = ((FakePlayer)p).Block; } else { block = Byte.Parse(p.ModelName); } CalcState(block); if (game.BlockInfo.IsAir[block]) { return; } lastTexId = -1; atlas = game.TerrainAtlas1D; if (game.BlockInfo.IsSprite[block]) { SpriteXQuad(TileSide.Right, false); SpriteZQuad(TileSide.Back, false); SpriteZQuad(TileSide.Back, true); SpriteXQuad(TileSide.Right, true); } else { YQuad(0, TileSide.Bottom, FastColour.ShadeYBottom); XQuad(maxBB.X - 0.5f, TileSide.Right, true, FastColour.ShadeX); ZQuad(minBB.Z - 0.5f, TileSide.Front, true, FastColour.ShadeZ); ZQuad(maxBB.Z - 0.5f, TileSide.Back, false, FastColour.ShadeZ); YQuad(height, TileSide.Top, 1.0f); XQuad(minBB.X - 0.5f, TileSide.Left, false, FastColour.ShadeX); } if (index == 0) { return; } graphics.BindTexture(lastTexId); TransformVertices(); graphics.UpdateDynamicIndexedVb(DrawMode.Triangles, cache.vb, cache.vertices, index, index * 6 / 4); }
void YQuad(float y, int side, float shade) { int texId = game.BlockInfo.GetTextureLoc(block, side), texIndex = 0; TextureRec rec = atlas.GetTexRec(texId, 1, out texIndex); FlushIfNotSame(texIndex); FastColour col = bright ? FastColour.White : FastColour.Scale(this.col, shade); float vOrigin = (texId % atlas.elementsPerAtlas1D) * atlas.invElementSize; rec.U1 = minBB.X; rec.U2 = maxBB.X; rec.V1 = vOrigin + minBB.Z * atlas.invElementSize; rec.V2 = vOrigin + maxBB.Z * atlas.invElementSize * 15.99f / 16f; cache.vertices[index++] = new VertexP3fT2fC4b(minBB.X - 0.5f, y, minBB.Z - 0.5f, rec.U1, rec.V1, col); cache.vertices[index++] = new VertexP3fT2fC4b(maxBB.X - 0.5f, y, minBB.Z - 0.5f, rec.U2, rec.V1, col); cache.vertices[index++] = new VertexP3fT2fC4b(maxBB.X - 0.5f, y, maxBB.Z - 0.5f, rec.U2, rec.V2, col); cache.vertices[index++] = new VertexP3fT2fC4b(minBB.X - 0.5f, y, maxBB.Z - 0.5f, rec.U1, rec.V2, col); }
FastColour GetCol(int i, int count) { if (count != boxVertices) { return(FastColour.Scale(col, 0.7f)); } if (i >= 4 && i < 8) { return(FastColour.Scale(col, FastColour.ShadeYBottom)); } if (i >= 8 && i < 16) { return(FastColour.Scale(col, FastColour.ShadeZ)); } if (i >= 16 && i < 24) { return(FastColour.Scale(col, FastColour.ShadeX)); } return(col); }
void XQuad(float x, int side, bool swapU, float shade) { int texId = game.BlockInfo.GetTextureLoc(block, side), texIndex = 0; TextureRec rec = atlas.GetTexRec(texId, 1, out texIndex); FlushIfNotSame(texIndex); FastColour col = bright ? FastColour.White : FastColour.Scale(this.col, shade); float vOrigin = (texId % atlas.elementsPerAtlas1D) * atlas.invElementSize; rec.U1 = minBB.Z; rec.U2 = maxBB.Z; rec.V1 = vOrigin + (1 - minBB.Y) * atlas.invElementSize; rec.V2 = vOrigin + (1 - maxBB.Y) * atlas.invElementSize * 15.99f / 16f; if (swapU) { rec.SwapU(); } cache.vertices[index++] = new VertexP3fT2fC4b(x, 0, minBB.Z - 0.5f, rec.U1, rec.V1, col); cache.vertices[index++] = new VertexP3fT2fC4b(x, height, minBB.Z - 0.5f, rec.U1, rec.V2, col); cache.vertices[index++] = new VertexP3fT2fC4b(x, height, maxBB.Z - 0.5f, rec.U2, rec.V2, col); cache.vertices[index++] = new VertexP3fT2fC4b(x, 0, maxBB.Z - 0.5f, rec.U2, rec.V1, col); }
void ZQuad(float z, int side, bool swapU, float shade) { int texId = game.BlockInfo.GetTextureLoc(block, side), texIndex = 0; TextureRec rec = atlas.GetTexRec(texId, 1, out texIndex); FlushIfNotSame(texIndex); FastColour col = bright ? FastColour.White : FastColour.Scale(this.col, shade); float vOrigin = rec.V1; rec.U1 = minBB.X; rec.U2 = maxBB.X; rec.V1 = vOrigin + minBB.Y * atlas.invElementSize; rec.V2 = vOrigin + maxBB.Y * atlas.invElementSize * 15.99f / 16f; if (swapU) { rec.SwapU(); } cache.vertices[index++] = new VertexPos3fTex2fCol4b(minBB.X - 0.5f, 0, z, rec.U1, rec.V2, col); cache.vertices[index++] = new VertexPos3fTex2fCol4b(minBB.X - 0.5f, height, z, rec.U1, rec.V1, col); cache.vertices[index++] = new VertexPos3fTex2fCol4b(maxBB.X - 0.5f, height, z, rec.U2, rec.V1, col); cache.vertices[index++] = new VertexPos3fTex2fCol4b(maxBB.X - 0.5f, 0, z, rec.U2, rec.V2, col); }
public static void GetShadedAngleShadow(FastColour normal, out int xSide, out int zSide, out int yBottom) { xSide = FastColour.Scale(normal, ShadeAHX).Pack(); zSide = FastColour.Scale(normal, ShadeAHZ).Pack(); yBottom = FastColour.Scale(normal, ShadeAHYBottom).Pack(); }
protected void DrawRotated(float angleX, float angleY, float angleZ, ModelPart part, bool head) { float cosX = (float)Math.Cos(-angleX), sinX = (float)Math.Sin(-angleX); float cosY = (float)Math.Cos(-angleY), sinY = (float)Math.Sin(-angleY); float cosZ = (float)Math.Cos(-angleZ), sinZ = (float)Math.Sin(-angleZ); float x = part.RotX, y = part.RotY, z = part.RotZ; VertexP3fT2fC4b vertex = default(VertexP3fT2fC4b); for (int i = 0; i < part.Count; i++) { ModelVertex v = vertices[part.Offset + i]; v.X -= x; v.Y -= y; v.Z -= z; float t = 0; // Rotate locally if (Rotate == RotateOrder.ZYX) { t = cosZ * v.X + sinZ * v.Y; v.Y = -sinZ * v.X + cosZ * v.Y; v.X = t; // Inlined RotZ t = cosY * v.X - sinY * v.Z; v.Z = sinY * v.X + cosY * v.Z; v.X = t; // Inlined RotY t = cosX * v.Y + sinX * v.Z; v.Z = -sinX * v.Y + cosX * v.Z; v.Y = t; // Inlined RotX } else if (Rotate == RotateOrder.XZY) { t = cosX * v.Y + sinX * v.Z; v.Z = -sinX * v.Y + cosX * v.Z; v.Y = t; // Inlined RotX t = cosZ * v.X + sinZ * v.Y; v.Y = -sinZ * v.X + cosZ * v.Y; v.X = t; // Inlined RotZ t = cosY * v.X - sinY * v.Z; v.Z = sinY * v.X + cosY * v.Z; v.X = t; // Inlined RotY } // Rotate globally if (!head) { v.X += x; v.Y += y; v.Z += z; t = cosYaw * v.X - sinYaw * v.Z; v.Z = sinYaw * v.X + cosYaw * v.Z; v.X = t; // Inlined RotY } else { t = cosHead * v.X - sinHead * v.Z; v.Z = sinHead * v.X + cosHead * v.Z; v.X = t; // Inlined RotY float tX = x, tZ = z; t = cosYaw * tX - sinYaw * tZ; tZ = sinYaw * tX + cosYaw * tZ; tX = t; // Inlined RotY v.X += tX; v.Y += y; v.Z += tZ; } v.X *= scale; v.Y *= scale; v.Z *= scale; v.X += pos.X; v.Y += pos.Y; v.Z += pos.Z; FastColour col = part.Count == boxVertices ? cols[i >> 2] : FastColour.Scale(this.col, 0.7f); vertex.X = v.X; vertex.Y = v.Y; vertex.Z = v.Z; vertex.R = col.R; vertex.G = col.G; vertex.B = col.B; vertex.A = 255; vertex.U = v.U * uScale; vertex.V = v.V * vScale; int quadI = i & 3; if (quadI == 0 || quadI == 3) { vertex.V -= 0.01f * vScale; } if (quadI == 2 || quadI == 3) { vertex.U -= 0.01f * vScale; } cache.vertices[index++] = vertex; } }