Advertisement
Guest User

Untitled

a guest
Apr 28th, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 29.42 KB | None | 0 0
  1. // Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
  2. using System;
  3. using ClassicalSharp.GraphicsAPI;
  4. using ClassicalSharp.Map;
  5. using OpenTK;
  6.  
  7. #if USE16_BIT
  8. using BlockID = System.UInt16;
  9. #else
  10. using BlockID = System.Byte;
  11. #endif
  12.  
  13. namespace ClassicalSharp {
  14.  
  15.     public unsafe sealed class AdvLightingMeshBuilder : ChunkMeshBuilder {
  16.        
  17.         bool[] isOccluder = new bool[Block.Count];
  18.         FastColour sun, sunX, sunZ, sunYBottom;
  19.         FastColour dark, darkX, darkZ, darkYBottom;
  20.        
  21.         protected override void PostStretchTiles(int x1, int y1, int z1) {
  22.             base.PostStretchTiles(x1, y1, z1);
  23.             for (int i = 0; i < isOccluder.Length; i++) {
  24.                 isOccluder[i] =
  25.                     info.BlocksLight[i] &&
  26.                     info.MinBB[i] == Vector3.Zero &&
  27.                     info.MaxBB[i] == Vector3.One &&
  28.                     info.Draw[i] != DrawType.TransparentThick; // goodlyay, did you hack this for leaves?
  29.                     //(info.Draw[i] != DrawType.TransparentThick && info.Draw[i] != DrawType.Translucent); // goodlyay, did you hack this for leaves?
  30.             }
  31.            
  32.             sun = env.Sunlight;
  33.             sunX = FastColour.Unpack(env.SunXSide);
  34.             sunZ = FastColour.Unpack(env.SunZSide);
  35.             sunYBottom = FastColour.Unpack(env.SunYBottom);
  36.            
  37.             float darkness = 0.4f;
  38.            
  39.             dark = FastColour.Unpack(FastColour.ScalePacked(env.Shadow, darkness));
  40.             darkX = FastColour.Unpack(FastColour.ScalePacked(env.ShadowXSide, darkness));
  41.             darkZ = FastColour.Unpack(FastColour.ScalePacked(env.ShadowZSide, darkness));
  42.             darkYBottom = FastColour.Unpack(FastColour.ScalePacked(env.ShadowYBottom, darkness));
  43.         }
  44.        
  45.         Vector3 minBB, maxBB;
  46.         bool isTranslucent;
  47.         int initBitFlags, lightFlags;
  48.         float x1, y1, z1, x2, y2, z2;
  49.        
  50.         protected override int StretchXLiquid(int countIndex, int x, int y, int z, int chunkIndex, BlockID block) {
  51.             return 1;
  52.         }
  53.        
  54.         protected override int StretchX(int countIndex, int x, int y, int z, int chunkIndex, BlockID block, int face) {
  55.             return 1;
  56.         }
  57.        
  58.         protected override int StretchZ(int countIndex, int x, int y, int z, int chunkIndex, BlockID block, int face) {
  59.             return 1;
  60.         }
  61.        
  62.         bool CanStretch(BlockID initialTile, int chunkIndex, int x, int y, int z, int face) {
  63.             BlockID rawBlock = chunk[chunkIndex];
  64.             bitFlags[chunkIndex] = ComputeLightFlags(x, y, z, chunkIndex);
  65.             return rawBlock == initialTile
  66.                 && !info.IsFaceHidden(rawBlock, chunk[chunkIndex + offsets[face]], face)
  67.                 && (initBitFlags == bitFlags[chunkIndex]
  68.                     // Check that this face is either fully bright or fully in shadow
  69.                     && (initBitFlags == 0 || (initBitFlags & masks[face]) == masks[face]));
  70.         }
  71.        
  72.        
  73.         protected override void RenderTile(int index) {
  74.             if (info.Draw[curBlock] == DrawType.Sprite) {
  75.                 fullBright = info.FullBright[curBlock];
  76.                 tinted = info.Tinted[curBlock];
  77.                 int count = counts[index + Side.Top];
  78.                 if (count != 0) DrawSprite(count);
  79.                 return;
  80.             }
  81.            
  82.             int leftCount = counts[index++], rightCount = counts[index++],
  83.             frontCount = counts[index++], backCount = counts[index++],
  84.             bottomCount = counts[index++], topCount = counts[index++];
  85.             if (leftCount == 0 && rightCount == 0 && frontCount == 0 &&
  86.                 backCount == 0 && bottomCount == 0 && topCount == 0) return;
  87.            
  88.             fullBright = info.FullBright[curBlock];
  89.             isTranslucent = info.Draw[curBlock] == DrawType.Translucent;
  90.             lightFlags = info.LightOffset[curBlock];
  91.             tinted = info.Tinted[curBlock];
  92.            
  93.             Vector3 min = info.RenderMinBB[curBlock], max = info.RenderMaxBB[curBlock];
  94.             x1 = X + min.X; y1 = Y + min.Y; z1 = Z + min.Z;
  95.             x2 = X + max.X; y2 = Y + max.Y; z2 = Z + max.Z;
  96.            
  97.             this.minBB = info.MinBB[curBlock]; this.maxBB = info.MaxBB[curBlock];
  98.             minBB.Y = 1 - minBB.Y; maxBB.Y = 1 - maxBB.Y;
  99.            
  100.             if (leftCount != 0) DrawLeftFace(leftCount);
  101.             if (rightCount != 0) DrawRightFace(rightCount);
  102.             if (frontCount != 0) DrawFrontFace(frontCount);
  103.             if (backCount != 0) DrawBackFace(backCount);
  104.             if (bottomCount != 0) DrawBottomFace(bottomCount);
  105.             if (topCount != 0) DrawTopFace(topCount);
  106.         }
  107.        
  108.         void DrawLeftFace(int count) {
  109.             int texId = info.textures[curBlock * Side.Sides + Side.Left];
  110.             int i = texId / elementsPerAtlas1D;
  111.             float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
  112.             int offset = (lightFlags >> Side.Left) & 1;
  113.            
  114.             float u1 = minBB.Z, u2 = (count - 1) + maxBB.Z * 15.99f/16f;
  115.             float v1 = vOrigin + maxBB.Y * invVerElementSize;
  116.             float v2 = vOrigin + minBB.Y * invVerElementSize * 15.99f/16f;
  117.             DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
  118.            
  119.             int col0_0 = AverageColorsXSide(X-offset, Y, Z, -1, -1);
  120.             int col0_1 = AverageColorsXSide(X-offset, Y, Z, -1, +1);
  121.             int col1_1 = AverageColorsXSide(X-offset, Y, Z, +1, +1);
  122.             int col1_0 = AverageColorsXSide(X-offset, Y, Z, +1, -1);
  123.            
  124.             if (tinted) {
  125.                 col0_0 = TintBlock(curBlock, col0_0);
  126.                 col1_0 = TintBlock(curBlock, col1_0);
  127.                 col1_1 = TintBlock(curBlock, col1_1);
  128.                 col0_1 = TintBlock(curBlock, col0_1);
  129.             }
  130.            
  131.             part.vertices[part.vIndex[Side.Left]++] = new VertexP3fT2fC4b(x1, y2, z2 + (count - 1), u2, v1, col1_1);
  132.             part.vertices[part.vIndex[Side.Left]++] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_1);
  133.             part.vertices[part.vIndex[Side.Left]++] = new VertexP3fT2fC4b(x1, y1, z1, u1, v2, col0_0);
  134.             part.vertices[part.vIndex[Side.Left]++] = new VertexP3fT2fC4b(x1, y1, z2 + (count - 1), u2, v2, col1_0);
  135.         }
  136.  
  137.         void DrawRightFace(int count) {
  138.             int texId = info.textures[curBlock * Side.Sides + Side.Right];
  139.             int i = texId / elementsPerAtlas1D;
  140.             float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
  141.             int offset = (lightFlags >> Side.Right) & 1;
  142.            
  143.             float u1 = (count - minBB.Z), u2 = (1 - maxBB.Z) * 15.99f/16f;
  144.             float v1 = vOrigin + maxBB.Y * invVerElementSize;
  145.             float v2 = vOrigin + minBB.Y * invVerElementSize * 15.99f/16f;
  146.             DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
  147.            
  148.             int col0_0 = AverageColorsXSide(X+offset, Y, Z, -1, -1);
  149.             int col0_1 = AverageColorsXSide(X+offset, Y, Z, -1, +1);
  150.             int col1_1 = AverageColorsXSide(X+offset, Y, Z, +1, +1);
  151.             int col1_0 = AverageColorsXSide(X+offset, Y, Z, +1, -1);
  152.            
  153.             if (tinted) {
  154.                 col0_0 = TintBlock(curBlock, col0_0);
  155.                 col1_0 = TintBlock(curBlock, col1_0);
  156.                 col1_1 = TintBlock(curBlock, col1_1);
  157.                 col0_1 = TintBlock(curBlock, col0_1);
  158.             }
  159.            
  160.             part.vertices[part.vIndex[Side.Right]++] = new VertexP3fT2fC4b(x2, y2, z2 + (count - 1), u2, v1, col1_1);
  161.             part.vertices[part.vIndex[Side.Right]++] = new VertexP3fT2fC4b(x2, y1, z2 + (count - 1), u2, v2, col1_0);
  162.             part.vertices[part.vIndex[Side.Right]++] = new VertexP3fT2fC4b(x2, y1, z1, u1, v2, col0_0);
  163.             part.vertices[part.vIndex[Side.Right]++] = new VertexP3fT2fC4b(x2, y2, z1, u1, v1, col0_1);
  164.         }
  165.  
  166.         void DrawFrontFace(int count) {
  167.             int texId = info.textures[curBlock * Side.Sides + Side.Front];
  168.             int i = texId / elementsPerAtlas1D;
  169.             float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
  170.             int offset = (lightFlags >> Side.Front) & 1;
  171.            
  172.             float u1 = (count - minBB.X), u2 = (1 - maxBB.X) * 15.99f/16f;
  173.             float v1 = vOrigin + maxBB.Y * invVerElementSize;
  174.             float v2 = vOrigin + minBB.Y * invVerElementSize * 15.99f/16f;
  175.             DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
  176.            
  177.             int col0_0 = AverageColorsZSide(X, Y, Z-offset, -1, -1);
  178.             int col0_1 = AverageColorsZSide(X, Y, Z-offset, -1, +1);
  179.             int col1_1 = AverageColorsZSide(X, Y, Z-offset, +1, +1);
  180.             int col1_0 = AverageColorsZSide(X, Y, Z-offset, +1, -1);
  181.            
  182.             if (tinted) {
  183.                 col0_0 = TintBlock(curBlock, col0_0);
  184.                 col1_0 = TintBlock(curBlock, col1_0);
  185.                 col1_1 = TintBlock(curBlock, col1_1);
  186.                 col0_1 = TintBlock(curBlock, col0_1);
  187.             }
  188.            
  189.             part.vertices[part.vIndex[Side.Front]++] = new VertexP3fT2fC4b(x1, y1, z1, u1, v2, col0_0);
  190.             part.vertices[part.vIndex[Side.Front]++] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_1);
  191.             part.vertices[part.vIndex[Side.Front]++] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col1_1);
  192.             part.vertices[part.vIndex[Side.Front]++] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z1, u2, v2, col1_0);
  193.         }
  194.        
  195.         void DrawBackFace(int count) {
  196.             int texId = info.textures[curBlock * Side.Sides + Side.Back];
  197.             int i = texId / elementsPerAtlas1D;
  198.             float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
  199.             int offset = (lightFlags >> Side.Back) & 1;
  200.            
  201.             float u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f/16f;
  202.             float v1 = vOrigin + maxBB.Y * invVerElementSize;
  203.             float v2 = vOrigin + minBB.Y * invVerElementSize * 15.99f/16f;
  204.             DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
  205.            
  206.             int col0_0 = AverageColorsZSide(X, Y, Z+offset, -1, -1);
  207.             int col0_1 = AverageColorsZSide(X, Y, Z+offset, -1, +1);
  208.             int col1_1 = AverageColorsZSide(X, Y, Z+offset, +1, +1);
  209.             int col1_0 = AverageColorsZSide(X, Y, Z+offset, +1, -1);
  210.            
  211.             if (tinted) {
  212.                 col0_0 = TintBlock(curBlock, col0_0);
  213.                 col1_0 = TintBlock(curBlock, col1_0);
  214.                 col1_1 = TintBlock(curBlock, col1_1);
  215.                 col0_1 = TintBlock(curBlock, col0_1);
  216.             }
  217.            
  218.             part.vertices[part.vIndex[Side.Back]++] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z2, u2, v1, col1_1);
  219.             part.vertices[part.vIndex[Side.Back]++] = new VertexP3fT2fC4b(x1, y2, z2, u1, v1, col0_1);
  220.             part.vertices[part.vIndex[Side.Back]++] = new VertexP3fT2fC4b(x1, y1, z2, u1, v2, col0_0);
  221.             part.vertices[part.vIndex[Side.Back]++] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z2, u2, v2, col1_0);
  222.         }
  223.        
  224.         void DrawBottomFace(int count) {
  225.             int texId = info.textures[curBlock * Side.Sides + Side.Bottom];
  226.             int i = texId / elementsPerAtlas1D;
  227.             float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
  228.             int offset = (lightFlags >> Side.Bottom) & 1;
  229.            
  230.             float u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f/16f;
  231.             float v1 = vOrigin + minBB.Z * invVerElementSize;
  232.             float v2 = vOrigin + maxBB.Z * invVerElementSize * 15.99f/16f;
  233.             DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
  234.            
  235.             int col0_0 = AverageColorsBottom(X, Y-offset, Z, -1, -1);
  236.             int col0_1 = AverageColorsBottom(X, Y-offset, Z, -1, +1);
  237.             int col1_1 = AverageColorsBottom(X, Y-offset, Z, +1, +1);
  238.             int col1_0 = AverageColorsBottom(X, Y-offset, Z, +1, -1);
  239.  
  240.             if (tinted) {
  241.                 col0_0 = TintBlock(curBlock, col0_0);
  242.                 col1_0 = TintBlock(curBlock, col1_0);
  243.                 col1_1 = TintBlock(curBlock, col1_1);
  244.                 col0_1 = TintBlock(curBlock, col0_1);
  245.             }
  246.            
  247.             part.vertices[part.vIndex[Side.Bottom]++] = new VertexP3fT2fC4b(x1, y1, z2, u1, v2, col0_1);
  248.             part.vertices[part.vIndex[Side.Bottom]++] = new VertexP3fT2fC4b(x1, y1, z1, u1, v1, col0_0);
  249.             part.vertices[part.vIndex[Side.Bottom]++] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z1, u2, v1, col1_0);
  250.             part.vertices[part.vIndex[Side.Bottom]++] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z2, u2, v2, col1_1);
  251.         }
  252.  
  253.         void DrawTopFace(int count) {
  254.             int texId = info.textures[curBlock * Side.Sides + Side.Top];
  255.             int i = texId / elementsPerAtlas1D;
  256.             float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
  257.             int offset = (lightFlags >> Side.Top) & 1;
  258.  
  259.             float u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f/16f;
  260.             float v1 = vOrigin + minBB.Z * invVerElementSize;
  261.             float v2 = vOrigin + maxBB.Z * invVerElementSize * 15.99f/16f;
  262.             DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
  263.            
  264.            
  265.             if (info.MinBB[curBlock].Y > 0 && info.MaxBB[curBlock].Y == 1) { offset = 1; }
  266.             offset = 1;
  267.             int col0_0 = AverageColorsTop(X, Y+offset, Z, -1, -1);
  268.             int col0_1 = AverageColorsTop(X, Y+offset, Z, -1, +1);
  269.             int col1_1 = AverageColorsTop(X, Y+offset, Z, +1, +1);
  270.             int col1_0 = AverageColorsTop(X, Y+offset, Z, +1, -1);
  271.            
  272.             if (tinted) {
  273.                 col0_0 = TintBlock(curBlock, col0_0);
  274.                 col1_0 = TintBlock(curBlock, col1_0);
  275.                 col1_1 = TintBlock(curBlock, col1_1);
  276.                 col0_1 = TintBlock(curBlock, col0_1);
  277.             }
  278.            
  279.             part.vertices[part.vIndex[Side.Top]++] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_0);
  280.             part.vertices[part.vIndex[Side.Top]++] = new VertexP3fT2fC4b(x1, y2, z2, u1, v2, col0_1);
  281.             part.vertices[part.vIndex[Side.Top]++] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z2, u2, v2, col1_1);
  282.             part.vertices[part.vIndex[Side.Top]++] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col1_0);
  283.         }
  284.        
  285.         protected override void DrawSprite(int count) {
  286.             int texId = info.textures[curBlock * Side.Sides + Side.Right];
  287.             int i = texId / elementsPerAtlas1D;
  288.             float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
  289.             const float blockHeight = 1;
  290.            
  291.             const float u1 = 0, u2 = 15.99f/16f;
  292.             float v1 = vOrigin, v2 = vOrigin + invVerElementSize * 15.99f/16f;
  293.             DrawInfo part = normalParts[i];
  294.             int col = fullBright ? FastColour.WhitePacked : light.LightCol_Sprite_Fast(X, Y, Z);
  295.             if (tinted) col = TintBlock(curBlock, col);
  296.            
  297.             int col0_0 = AverageColorsTop(X, Y, Z, -1, -1);
  298.             int col0_1 = AverageColorsTop(X, Y, Z, -1, +1);
  299.             int col1_1 = AverageColorsTop(X, Y, Z, +1, +1);
  300.             int col1_0 = AverageColorsTop(X, Y, Z, +1, -1);
  301.            
  302.             int col0_0T = AverageColorsTop(X, Y+1, Z, -1, -1);
  303.             int col0_1T = AverageColorsTop(X, Y+1, Z, -1, +1);
  304.             int col1_1T = AverageColorsTop(X, Y+1, Z, +1, +1);
  305.             int col1_0T = AverageColorsTop(X, Y+1, Z, +1, -1);
  306.            
  307.             if (tinted) {
  308.                 col0_0 = TintBlock(curBlock, col0_0);
  309.                 col1_0 = TintBlock(curBlock, col1_0);
  310.                 col1_1 = TintBlock(curBlock, col1_1);
  311.                 col0_1 = TintBlock(curBlock, col0_1);
  312.                 col0_0T = TintBlock(curBlock, col0_0T);
  313.                 col1_0T = TintBlock(curBlock, col1_0T);
  314.                 col1_1T = TintBlock(curBlock, col1_1T);
  315.                 col0_1T = TintBlock(curBlock, col0_1T);
  316.             }
  317.            
  318.            
  319.             // Draw Z axis
  320.             part.vertices[part.sIndex[0]++] = new VertexP3fT2fC4b(X + 2.50f/16, Y, Z + 2.5f/16, u2, v2, col0_0);
  321.             part.vertices[part.sIndex[0]++] = new VertexP3fT2fC4b(X + 2.50f/16, Y + blockHeight, Z + 2.5f/16, u2, v1, col0_0T);
  322.             part.vertices[part.sIndex[0]++] = new VertexP3fT2fC4b(X + 13.5f/16, Y + blockHeight, Z + 13.5f/16, u1, v1, col1_1T);
  323.             part.vertices[part.sIndex[0]++] = new VertexP3fT2fC4b(X + 13.5f/16, Y, Z + 13.5f/16, u1, v2, col1_1);
  324.            
  325.             // Draw Z axis mirrored
  326.             part.vertices[part.sIndex[1]++] = new VertexP3fT2fC4b(X + 13.5f/16, Y, Z + 13.5f/16, u2, v2, col1_1);
  327.             part.vertices[part.sIndex[1]++] = new VertexP3fT2fC4b(X + 13.5f/16, Y + blockHeight, Z + 13.5f/16, u2, v1, col1_1T);
  328.             part.vertices[part.sIndex[1]++] = new VertexP3fT2fC4b(X + 2.50f/16, Y + blockHeight, Z + 2.5f/16, u1, v1, col0_0T);
  329.             part.vertices[part.sIndex[1]++] = new VertexP3fT2fC4b(X + 2.50f/16, Y, Z + 2.5f/16, u1, v2, col0_0);
  330.            
  331.             // Draw X axis
  332.             part.vertices[part.sIndex[2]++] = new VertexP3fT2fC4b(X + 2.50f/16, Y, Z + 13.5f/16, u2, v2, col0_1);
  333.             part.vertices[part.sIndex[2]++] = new VertexP3fT2fC4b(X + 2.50f/16, Y + blockHeight, Z + 13.5f/16, u2, v1, col0_1T);
  334.             part.vertices[part.sIndex[2]++] = new VertexP3fT2fC4b(X + 13.5f/16, Y + blockHeight, Z + 2.5f/16, u1, v1, col1_0T);
  335.             part.vertices[part.sIndex[2]++] = new VertexP3fT2fC4b(X + 13.5f/16, Y, Z + 2.5f/16, u1, v2, col1_0);
  336.            
  337.             // Draw X axis mirrored
  338.             part.vertices[part.sIndex[3]++] = new VertexP3fT2fC4b(X + 13.5f/16, Y, Z + 2.5f/16, u2, v2, col1_0);
  339.             part.vertices[part.sIndex[3]++] = new VertexP3fT2fC4b(X + 13.5f/16, Y + blockHeight, Z + 2.5f/16, u2, v1, col1_0T);
  340.             part.vertices[part.sIndex[3]++] = new VertexP3fT2fC4b(X + 2.50f/16, Y + blockHeight, Z + 13.5f/16, u1, v1, col0_1T);
  341.             part.vertices[part.sIndex[3]++] = new VertexP3fT2fC4b(X + 2.50f/16, Y, Z + 13.5f/16, u1, v2, col0_1);
  342.            
  343.         }
  344.        
  345.         int AverageColorsTop(int X, int Y, int Z, int dX, int dZ) {
  346.             if (fullBright) return FastColour.WhitePacked;
  347.             bool useDiagonal = true;
  348.             bool block1;
  349.             bool block2;
  350.             bool dummy;
  351.             int R;
  352.             int G;
  353.             int B;
  354.             FastColour col1 = GetBlockColorTop(X, Y, Z, out dummy);
  355.             FastColour col2 = GetBlockColorTop(X+dX, Y, Z, out block1);
  356.             FastColour col3 = GetBlockColorTop(X, Y, Z+dZ, out block2);
  357.             FastColour col4 = GetBlockColorTop(X+dX, Y, Z+dZ, out dummy);
  358.            
  359.             useDiagonal = !(block1 && block2);
  360.             if (useDiagonal) {
  361.                 R = (col1.R + col2.R + col3.R + col4.R) / 4;
  362.                 G = (col1.G + col2.G + col3.G + col4.G) / 4;
  363.                 B = (col1.B + col2.B + col3.B + col4.B) / 4;
  364.             } else {
  365.                 R = (col1.R + col2.R + col3.R) / 3;
  366.                 G = (col1.G + col2.G + col3.G) / 3;
  367.                 B = (col1.B + col2.B + col3.B) / 3;
  368.             }
  369.            
  370.             #if !USE_DX
  371.             return 255 << 24 | B << 16 | G << 8 | R;
  372.             #else
  373.             return 255 << 24 | R << 16 | G << 8 | B;
  374.             #endif
  375.         }
  376.        
  377.         FastColour GetBlockColorTop(int X, int Y, int Z, out bool blocksLight) {
  378.             blocksLight = false;
  379.             if (map.IsValidPos(X, Y, Z)) {
  380.                 BlockID thisBlock = map.GetBlock(X, Y, Z);
  381.                 if (isOccluder[thisBlock]) blocksLight = true;
  382.                
  383.                 FastColour col = blocksLight ? dark : FastColour.Unpack(light.LightCol(X, Y, Z));
  384.                 if (info.FullBright[thisBlock]) col = sun;
  385.                 return col;
  386.             }
  387.             return sun;
  388.         }
  389.        
  390.         int AverageColorsBottom(int X, int Y, int Z, int dX, int dZ) {
  391.             if (fullBright) return FastColour.WhitePacked;
  392.             bool useDiagonal = true;
  393.             bool block1;
  394.             bool block2;
  395.             bool dummy;
  396.             int R;
  397.             int G;
  398.             int B;
  399.             FastColour col1 = GetBlockColorBottom(X, Y, Z, out dummy);
  400.             FastColour col2 = GetBlockColorBottom(X+dX, Y, Z, out block1);
  401.             FastColour col3 = GetBlockColorBottom(X, Y, Z+dZ, out block2);
  402.             FastColour col4 = GetBlockColorBottom(X+dX, Y, Z+dZ, out dummy);
  403.            
  404.             useDiagonal = !(block1 && block2);
  405.             if (useDiagonal) {
  406.                 R = (col1.R + col2.R + col3.R + col4.R) / 4;
  407.                 G = (col1.G + col2.G + col3.G + col4.G) / 4;
  408.                 B = (col1.B + col2.B + col3.B + col4.B) / 4;
  409.             } else {
  410.                 R = (col1.R + col2.R + col3.R) / 3;
  411.                 G = (col1.G + col2.G + col3.G) / 3;
  412.                 B = (col1.B + col2.B + col3.B) / 3;
  413.             }
  414.            
  415.             #if !USE_DX
  416.             return 255 << 24 | B << 16 | G << 8 | R;
  417.             #else
  418.             return 255 << 24 | R << 16 | G << 8 | B;
  419.             #endif
  420.         }
  421.        
  422.         FastColour GetBlockColorBottom(int X, int Y, int Z, out bool blocksLight) {
  423.             blocksLight = false;
  424.             if (map.IsValidPos(X, Y, Z)) {
  425.                 BlockID thisBlock = map.GetBlock(X, Y, Z);
  426.                 if (isOccluder[thisBlock]) blocksLight = true;
  427.                
  428.                 FastColour col = blocksLight ? darkYBottom : FastColour.Unpack(light.LightCol_YBottom_Fast(X, Y, Z));
  429.                 if (info.FullBright[thisBlock]) col = sun;
  430.                 return col;
  431.             }
  432.             return sunYBottom;
  433.         }
  434.        
  435.        
  436.         int AverageColorsZSide(int X, int Y, int Z, int dX, int dY) {
  437.             if (fullBright) return FastColour.WhitePacked;
  438.             bool useDiagonal = true;
  439.             bool block1;
  440.             bool block2;
  441.             bool dummy;
  442.             int R;
  443.             int G;
  444.             int B;
  445.             FastColour col1 = GetBlockColorZSide(X, Y, Z, out dummy);
  446.             FastColour col2 = GetBlockColorZSide(X+dX, Y, Z, out block1);
  447.             FastColour col3 = GetBlockColorZSide(X, Y+dY, Z, out block2);
  448.             FastColour col4 = GetBlockColorZSide(X+dX, Y+dY, Z, out dummy);
  449.            
  450.             useDiagonal = !(block1 && block2);
  451.             if (useDiagonal) {
  452.                 R = (col1.R + col2.R + col3.R + col4.R) / 4;
  453.                 G = (col1.G + col2.G + col3.G + col4.G) / 4;
  454.                 B = (col1.B + col2.B + col3.B + col4.B) / 4;
  455.             } else {
  456.                 R = (col1.R + col2.R + col3.R) / 3;
  457.                 G = (col1.G + col2.G + col3.G) / 3;
  458.                 B = (col1.B + col2.B + col3.B) / 3;
  459.             }
  460.            
  461.             #if !USE_DX
  462.             return 255 << 24 | B << 16 | G << 8 | R;
  463.             #else
  464.             return 255 << 24 | R << 16 | G << 8 | B;
  465.             #endif
  466.         }
  467.        
  468.         FastColour GetBlockColorZSide(int X, int Y, int Z, out bool blocksLight) {
  469.             blocksLight = false;
  470.             if (map.IsValidPos(X, Y, Z)) {
  471.                 BlockID thisBlock = map.GetBlock(X, Y, Z);
  472.                 if (isOccluder[thisBlock]) blocksLight = true;
  473.                
  474.                 FastColour col = blocksLight ? darkZ : FastColour.Unpack(light.LightCol_ZSide_Fast(X, Y, Z));
  475.                 if (info.FullBright[thisBlock]) col = sun;
  476.                 return col;
  477.             }
  478.             return sunZ;
  479.         }
  480.        
  481.        
  482.         int AverageColorsXSide(int X, int Y, int Z, int dZ, int dY) {
  483.             if (fullBright) return FastColour.WhitePacked;
  484.             bool useDiagonal = true;
  485.             bool block1;
  486.             bool block2;
  487.             bool dummy;
  488.             int R;
  489.             int G;
  490.             int B;
  491.             FastColour col1 = GetBlockColorXSide(X, Y, Z, out dummy);
  492.             FastColour col2 = GetBlockColorXSide(X, Y, Z+dZ, out block1);
  493.             FastColour col3 = GetBlockColorXSide(X, Y+dY, Z, out block2);
  494.             FastColour col4 = GetBlockColorXSide(X, Y+dY, Z+dZ, out dummy);
  495.            
  496.             useDiagonal = !(block1 && block2);
  497.             if (useDiagonal) {
  498.                 R = (col1.R + col2.R + col3.R + col4.R) / 4;
  499.                 G = (col1.G + col2.G + col3.G + col4.G) / 4;
  500.                 B = (col1.B + col2.B + col3.B + col4.B) / 4;
  501.             } else {
  502.                 R = (col1.R + col2.R + col3.R) / 3;
  503.                 G = (col1.G + col2.G + col3.G) / 3;
  504.                 B = (col1.B + col2.B + col3.B) / 3;
  505.             }
  506.            
  507.             #if !USE_DX
  508.             return 255 << 24 | B << 16 | G << 8 | R;
  509.             #else
  510.             return 255 << 24 | R << 16 | G << 8 | B;
  511.             #endif
  512.         }
  513.        
  514.         FastColour GetBlockColorXSide(int X, int Y, int Z, out bool blocksLight) {
  515.             blocksLight = false;
  516.             if (map.IsValidPos(X, Y, Z)) {
  517.                 BlockID thisBlock = map.GetBlock(X, Y, Z);
  518.                 if (isOccluder[thisBlock]) blocksLight = true;
  519.                
  520.                 FastColour col = blocksLight ? darkX : FastColour.Unpack(light.LightCol_XSide_Fast(X, Y, Z));
  521.                 if (info.FullBright[thisBlock]) col = sun;
  522.                 return col;
  523.             }
  524.             return sunX;
  525.         }
  526.        
  527.        
  528.         #region Light computation
  529.        
  530.         int ComputeLightFlags(int x, int y, int z, int cIndex) {
  531.             if (fullBright) return (1 << xP1_yP1_zP1) - 1; // all faces fully bright
  532.  
  533.             return
  534.                 Lit(x - 1, y, z - 1, cIndex - 1 - 18) << xM1_yM1_zM1 |
  535.                 Lit(x - 1, y, z,     cIndex - 1)      << xM1_yM1_zCC |
  536.                 Lit(x - 1, y, z + 1, cIndex - 1 + 18) << xM1_yM1_zP1 |
  537.                 Lit(x, y, z - 1,     cIndex + 0 - 18) << xCC_yM1_zM1 |
  538.                 Lit(x, y, z,         cIndex + 0)      << xCC_yM1_zCC |
  539.                 Lit(x, y, z + 1 ,    cIndex + 0 + 18) << xCC_yM1_zP1 |
  540.                 Lit(x + 1, y, z - 1, cIndex + 1 - 18) << xP1_yM1_zM1 |
  541.                 Lit(x + 1, y, z,     cIndex + 1)      << xP1_yM1_zCC |
  542.                 Lit(x + 1, y, z + 1, cIndex + 1 + 18) << xP1_yM1_zP1 ;
  543.         }
  544.        
  545.         const int xM1_yM1_zM1 = 0,  xM1_yCC_zM1 = 1,  xM1_yP1_zM1 = 2;
  546.         const int xCC_yM1_zM1 = 3,  xCC_yCC_zM1 = 4,  xCC_yP1_zM1 = 5;
  547.         const int xP1_yM1_zM1 = 6,  xP1_yCC_zM1 = 7,  xP1_yP1_zM1 = 8;
  548.  
  549.         const int xM1_yM1_zCC = 9,  xM1_yCC_zCC = 10, xM1_yP1_zCC = 11;
  550.         const int xCC_yM1_zCC = 12, xCC_yCC_zCC = 13, xCC_yP1_zCC = 14;
  551.         const int xP1_yM1_zCC = 15, xP1_yCC_zCC = 16, xP1_yP1_zCC = 17;
  552.  
  553.         const int xM1_yM1_zP1 = 18, xM1_yCC_zP1 = 19, xM1_yP1_zP1 = 20;
  554.         const int xCC_yM1_zP1 = 21, xCC_yCC_zP1 = 22, xCC_yP1_zP1 = 23;
  555.         const int xP1_yM1_zP1 = 24, xP1_yCC_zP1 = 25, xP1_yP1_zP1 = 26;
  556.        
  557.         int Lit(int x, int y, int z, int cIndex) {
  558.             if (x < 0 || y < 0 || z < 0
  559.                 || x >= width || y >= height || z >= length) return 7;
  560.             int flags = 0;
  561.             BlockID block = chunk[cIndex];
  562.             int lightHeight = light.heightmap[(z * width) + x];
  563.             lightFlags = info.LightOffset[block];
  564.  
  565.             // Use fact Light(Y.Bottom) == Light((Y - 1).Top)
  566.             int offset = (lightFlags >> Side.Bottom) & 1;
  567.             flags |= ((y - offset) > lightHeight ? 1 : 0);
  568.             // Light is same for all the horizontal faces
  569.             flags |= (y > lightHeight ? 2 : 0);
  570.             // Use fact Light((Y + 1).Bottom) == Light(Y.Top)
  571.             offset = (lightFlags >> Side.Top) & 1;
  572.             flags |= ((y - offset) >= lightHeight ? 4 : 0);
  573.            
  574.             // Dynamic lighting
  575.             if (info.FullBright[block])               flags |= 5;
  576.             if (info.FullBright[chunk[cIndex + 324]]) flags |= 4;
  577.             if (info.FullBright[chunk[cIndex - 324]]) flags |= 1;
  578.             return flags;
  579.         }
  580.        
  581.         static int[] masks = {
  582.             // Left face
  583.             (1 << xM1_yM1_zM1) | (1 << xM1_yM1_zCC) | (1 << xM1_yM1_zP1) |
  584.                 (1 << xM1_yCC_zM1) | (1 << xM1_yCC_zCC) | (1 << xM1_yCC_zP1) |
  585.                 (1 << xM1_yP1_zM1) | (1 << xM1_yP1_zCC) | (1 << xM1_yP1_zP1),
  586.             // Right face
  587.             (1 << xP1_yM1_zM1) | (1 << xP1_yM1_zCC) | (1 << xP1_yM1_zP1) |
  588.                 (1 << xP1_yP1_zM1) | (1 << xP1_yP1_zCC) | (1 << xP1_yP1_zP1) |
  589.                 (1 << xP1_yCC_zM1) | (1 << xP1_yCC_zCC) | (1 << xP1_yCC_zP1),
  590.             // Front face
  591.             (1 << xM1_yM1_zM1) | (1 << xCC_yM1_zM1) | (1 << xP1_yM1_zM1) |
  592.                 (1 << xM1_yCC_zM1) | (1 << xCC_yCC_zM1) | (1 << xP1_yCC_zM1) |
  593.                 (1 << xM1_yP1_zM1) | (1 << xCC_yP1_zM1) | (1 << xP1_yP1_zM1),
  594.             // Back face
  595.             (1 << xM1_yM1_zP1) | (1 << xCC_yM1_zP1) | (1 << xP1_yM1_zP1) |
  596.                 (1 << xM1_yCC_zP1) | (1 << xCC_yCC_zP1) | (1 << xP1_yCC_zP1) |
  597.                 (1 << xM1_yP1_zP1) | (1 << xCC_yP1_zP1) | (1 << xP1_yP1_zP1),
  598.             // Bottom face
  599.             (1 << xM1_yM1_zM1) | (1 << xM1_yM1_zCC) | (1 << xM1_yM1_zP1) |
  600.                 (1 << xCC_yM1_zM1) | (1 << xCC_yM1_zCC) | (1 << xCC_yM1_zP1) |
  601.                 (1 << xP1_yM1_zM1) | (1 << xP1_yM1_zCC) | (1 << xP1_yM1_zP1),
  602.             // Top face
  603.             (1 << xM1_yP1_zM1) | (1 << xM1_yP1_zCC) | (1 << xM1_yP1_zP1) |
  604.                 (1 << xCC_yP1_zM1) | (1 << xCC_yP1_zCC) | (1 << xCC_yP1_zP1) |
  605.                 (1 << xP1_yP1_zM1) | (1 << xP1_yP1_zCC) | (1 << xP1_yP1_zP1),
  606.         };
  607.        
  608.         #endregion
  609.     }
  610. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement