示例#1
0
        public unsafe override void LightHint(int startX, int startZ, BlockRaw *mapPtr)
        {
            int  x1 = Math.Max(startX, 0), x2 = Math.Min(width, startX + 18);
            int  z1 = Math.Max(startZ, 0), z2 = Math.Min(length, startZ + 18);
            int  xCount = x2 - x1, zCount = z2 - z1;
            int *skip = stackalloc int[xCount * zCount];

            int elemsLeft = InitialHeightmapCoverage(x1, z1, xCount, zCount, skip);

                        #if !ONLY_8BIT
            if (BlockInfo.MaxUsed >= 256)
            {
                fixed(BlockRaw *mapPtr2 = game.World.blocks2)
                {
                    if (!CalculateHeightmapCoverage_16Bit(x1, z1, xCount, zCount, elemsLeft, skip, mapPtr, mapPtr2))
                    {
                        FinishHeightmapCoverage(x1, z1, xCount, zCount, skip);
                    }
                }

                return;
            }
                        #endif
            if (!CalculateHeightmapCoverage_8Bit(x1, z1, xCount, zCount, elemsLeft, skip, mapPtr))
            {
                FinishHeightmapCoverage(x1, z1, xCount, zCount, skip);
            }
        }
示例#2
0
        void ReadChunkData_16Bit(int x1, int y1, int z1, BlockRaw *mapPtr, ref bool outAllAir, ref bool outAllSolid)           // only assign this variable once
        {
            bool allAir = true, allSolid = true;

            fixed(BlockRaw *mapPtr2 = map.blocks2)
            {
                for (int yy = -1; yy < 17; yy++)
                {
                    int y = yy + y1;
                    if (y < 0)
                    {
                        continue;
                    }
                    if (y >= height)
                    {
                        break;
                    }
                    for (int zz = -1; zz < 17; zz++)
                    {
                        int z = zz + z1;
                        if (z < 0)
                        {
                            continue;
                        }
                        if (z >= length)
                        {
                            break;
                        }

                        int index      = (y * length + z) * width + (x1 - 1 - 1);
                        int chunkIndex = (yy + 1) * extChunkSize2 + (zz + 1) * extChunkSize + (-1 + 1) - 1;

                        for (int xx = -1; xx < 17; xx++)
                        {
                            int x = xx + x1;
                            index++;
                            chunkIndex++;
                            if (x < 0)
                            {
                                continue;
                            }
                            if (x >= width)
                            {
                                break;
                            }
                            BlockID rawBlock = (BlockID)(mapPtr[index] | (mapPtr2[index] << 8));

                            allAir            = allAir && BlockInfo.Draw[rawBlock] == DrawType.Gas;
                            allSolid          = allSolid && BlockInfo.FullOpaque[rawBlock];
                            chunk[chunkIndex] = rawBlock;
                        }
                    }
                }
                outAllAir = allAir; outAllSolid = allSolid;
            }
        }
示例#3
0
        unsafe void MapSet(BlockRaw *ptr, int yStart, int yEnd, BlockRaw block)
        {
            yStart = Math.Max(yStart, 0); yEnd = Math.Max(yEnd, 0);
            int oneY = Width * Length, yHeight = (yEnd - yStart) + 1;

            CurrentProgress = 0;
            for (int y = yStart; y <= yEnd; y++)
            {
                MemUtils.memset((IntPtr)ptr, block, y * oneY, oneY);
                CurrentProgress = (float)(y - yStart) / yHeight;
            }
        }
        unsafe void MapSet(BlockRaw *ptr, int yStart, int yEnd, BlockRaw block)
        {
            yStart = Math.Max(yStart, 0); yEnd = Math.Max(yEnd, 0);
            int startIndex = yStart * Length * Width;
            int endIndex = (yEnd * Length + (Length - 1)) * Width + (Width - 1);
            int count = (endIndex - startIndex) + 1, offset = 0;

            while (offset < count)
            {
                int bytes = Math.Min(count - offset, Width * Length);
                MemUtils.memset((IntPtr)ptr, block, startIndex + offset, bytes);
                offset         += bytes;
                CurrentProgress = (float)offset / count;
            }
        }
        unsafe bool CalculateHeightmapCoverage(int x1, int z1, int xCount, int zCount, int elemsLeft, int *skip, BlockRaw *mapPtr)
        {
            int prevRunCount = 0;

            for (int y = height - 1; y >= 0; y--)
            {
                if (elemsLeft <= 0)
                {
                    return(true);
                }
                int mapIndex       = x1 + width * (z1 + y * length);
                int heightmapIndex = x1 + z1 * width;

                for (int z = 0; z < zCount; z++)
                {
                    int baseIndex = mapIndex;
                    int index     = z * xCount;
                    for (int x = 0; x < xCount;)
                    {
                        int curRunCount = skip[index];
                        x += curRunCount; mapIndex += curRunCount; index += curRunCount;

                        if (x < xCount && BlockInfo.BlocksLight[mapPtr[mapIndex]])
                        {
                            int lightOffset = (BlockInfo.LightOffset[mapPtr[mapIndex]] >> Side.Top) & 1;
                            heightmap[heightmapIndex + x] = (short)(y - lightOffset);
                            elemsLeft--;
                            skip[index] = 0;
                            int offset      = prevRunCount + curRunCount;
                            int newRunCount = skip[index - offset] + 1;

                            // consider case 1 0 1 0, where we are at 0
                            // we need to make this 3 0 0 0 and advance by 1
                            int oldRunCount = (x - offset + newRunCount) < xCount ? skip[index - offset + newRunCount] : 0;
                            if (oldRunCount != 0)
                            {
                                skip[index - offset + newRunCount] = 0;
                                newRunCount += oldRunCount;
                            }
                            skip[index - offset] = newRunCount;
                            x           += oldRunCount; index += oldRunCount; mapIndex += oldRunCount;
                            prevRunCount = newRunCount;
                        }
                        else
                        {
                            prevRunCount = 0;
                        }
                        x++; mapIndex++; index++;
                    }
                    prevRunCount    = 0;
                    heightmapIndex += width;
                    mapIndex        = baseIndex + width;              // advance one Z
                }
            }
            return(false);
        }
 // Equivalent to
 // for x = startX; x < startX + 18; x++
 //    for z = startZ; z < startZ + 18; z++
 //       CalcHeightAt(x, maxY, z) if height == short.MaxValue
 // Except this function is a lot more optimised and minimises cache misses.
 public unsafe abstract void LightHint(int startX, int startZ, BlockRaw *mapPtr);