Ejemplo n.º 1
0
 private static void AssertContainingChunkCoordinates(Vector3Int pos)
 {
     Assert.AreEqual(
         ExpContainingChunkCoordinates(pos),
         Helpers.ContainingChunkPos(ref pos), pos.ToString()
         );
 }
Ejemplo n.º 2
0
    //returns the position of the chunk containing this block
    private static Vector3Int ExpContainingChunkCoordinates(Vector3Int pos)
    {
        int chunkSize = Env.ChunkSize;

        int cx = Mathf.FloorToInt(pos.x / (float)chunkSize) * chunkSize;
        int cy = Mathf.FloorToInt(pos.y / (float)chunkSize) * chunkSize;
        int cz = Mathf.FloorToInt(pos.z / (float)chunkSize) * chunkSize;

        return(new Vector3Int(cx, cy, cz));
    }
Ejemplo n.º 3
0
    public override void GenerateStructures(Chunk chunk, int layerIndex)
    {
        //if (chunk.pos.x!=-30 || chunk.pos.y!=30 || chunk.pos.z!=0) return;

        int minX = chunk.Pos.x;
        int maxX = chunk.Pos.x + Env.ChunkSize1;
        int minZ = chunk.Pos.z;
        int maxZ = chunk.Pos.z + Env.ChunkSize1;

        int structureID = 0;

        for (int x = minX; x <= maxX; x++)
        {
            for (int z = minZ; z <= maxZ; z++)
            {
                Vector3Int pos         = new Vector3Int(x, 0, z);
                float      chanceAtPos = Randomization.RandomPrecise(pos.GetHashCode(), 44);

                if (chance > chanceAtPos)
                {
                    if (Randomization.RandomPrecise(pos.Add(1, 0, 0).GetHashCode(), 44) > chanceAtPos &&
                        Randomization.RandomPrecise(pos.Add(-1, 0, 0).GetHashCode(), 44) > chanceAtPos &&
                        Randomization.RandomPrecise(pos.Add(0, 0, 1).GetHashCode(), 44) > chanceAtPos &&
                        Randomization.RandomPrecise(pos.Add(0, 0, -1).GetHashCode(), 44) > chanceAtPos)
                    {
                        int xx     = Helpers.Mod(x, Env.ChunkSize);
                        int zz     = Helpers.Mod(z, Env.ChunkSize);
                        int height = Helpers.FastFloor(terrainGen.GetTerrainHeightForChunk(chunk, xx, zz));

                        if (chunk.Pos.y <= height && chunk.Pos.y + Env.ChunkSize1 >= height)
                        {
                            Vector3Int worldPos = new Vector3Int(x, height, z);
                            structure.Build(chunk, structureID++, ref worldPos, this);
                        }
                    }
                }
            }
        }
    }
Ejemplo n.º 4
0
 public bool RaycastHit(ref Vector3 pos, ref Vector3 dir, ref Vector3Int bPos, bool removalRequested)
 {
     return(removalRequested ? Config.raycastHitOnRemoval : Config.raycastHit);
 }
Ejemplo n.º 5
0
 public virtual void ScheduledUpdate(Chunk chunk, ref Vector3Int localPos)
 {
 }
Ejemplo n.º 6
0
 public virtual void RandomUpdate(Chunk chunk, ref Vector3Int localPos)
 {
 }
Ejemplo n.º 7
0
 public virtual void OnDestroy(Chunk chunk, ref Vector3Int localPos)
 {
 }
Ejemplo n.º 8
0
 public virtual void OnCreate(Chunk chunk, ref Vector3Int localPos)
 {
 }
Ejemplo n.º 9
0
 public virtual void BuildBlock(Chunk chunk, ref Vector3Int localpos, int materialID)
 {
 }
Ejemplo n.º 10
0
        public void PostProcessChunks()
        {
            int minX = m_viewerPos.x - (HorizontalChunkLoadRadius * Env.ChunkSize);
            int maxX = m_viewerPos.x + (HorizontalChunkLoadRadius * Env.ChunkSize);
            int minY = m_viewerPos.y - (VerticalChunkLoadRadius * Env.ChunkSize);
            int maxY = m_viewerPos.y + (VerticalChunkLoadRadius * Env.ChunkSize);
            int minZ = m_viewerPos.z - (HorizontalChunkLoadRadius * Env.ChunkSize);
            int maxZ = m_viewerPos.z + (HorizontalChunkLoadRadius * Env.ChunkSize);

            world.CapCoordXInsideWorld(ref minX, ref maxX);
            world.CapCoordYInsideWorld(ref minY, ref maxY);
            world.CapCoordZInsideWorld(ref minZ, ref maxZ);

            world.Bounds = new AABBInt(minX, minY, minZ, maxX, maxY, maxZ);

            int expectedChunks = m_chunkPositions.Length * ((maxY - minY + Env.ChunkSize) / Env.ChunkSize);

            if (// No update necessary if there was no movement
                m_viewerPos == m_viewerPosPrev &&
                // However, we need to make sure that we have enough chunks loaded
                world.chunks.Count >= expectedChunks)
            {
                return;
            }

            // Unregister any non-necessary pending structures
            Profiler.BeginSample("UnregisterStructures");
            {
                world.UnregisterPendingStructures();
            }
            Profiler.EndSample();

            // Cycle through the array of positions
            Profiler.BeginSample("PostProcessChunks");
            {
                WorldChunks chunks = world.chunks;

                // Cycle through the array of positions
                for (int y = maxY; y >= minY; y -= Env.ChunkSize)
                {
                    for (int i = 0; i < m_chunkPositions.Length; i++)
                    {
                        // Skip loading chunks which are off limits
                        int cx = (m_chunkPositions[i].x * Env.ChunkSize) + m_viewerPos.x;
                        if (cx > maxX || cx < minX)
                        {
                            continue;
                        }
                        int cy = (m_chunkPositions[i].y * Env.ChunkSize) + y;
                        if (cy > maxY || cy < minY)
                        {
                            continue;
                        }
                        int cz = (m_chunkPositions[i].z * Env.ChunkSize) + m_viewerPos.z;
                        if (cz > maxZ || cz < minZ)
                        {
                            continue;
                        }

                        // Create a new chunk if possible
                        Vector3Int newChunkPos = new Vector3Int(cx, cy, cz);
                        Chunk      chunk;
                        if (!chunks.CreateOrGetChunk(ref newChunkPos, out chunk))
                        {
                            continue;
                        }

                        if (FullLoadOnStartUp)
                        {
                            ChunkStateManagerClient stateManager = chunk.stateManager;
                            stateManager.PossiblyVisible = true;
                            stateManager.Visible         = false;
                        }

                        m_updateRequests.Add(chunk);
                    }
                }
            }
            Profiler.EndSample();
        }
Ejemplo n.º 11
0
        private void UpdateVisibility(int x, int y, int z, int rangeX, int rangeY, int rangeZ)
        {
            if (rangeX == 0 || rangeY == 0 || rangeZ == 0)
            {
                return;
            }

            bool isLast = rangeX == 1 && rangeY == 1 && rangeZ == 1;

            int wx = m_viewerPos.x + (x * Env.ChunkSize);
            int wy = m_viewerPos.y + (y * Env.ChunkSize);
            int wz = m_viewerPos.z + (z * Env.ChunkSize);

            int rx = rangeX * Env.ChunkSize;
            int ry = rangeY * Env.ChunkSize;
            int rz = rangeZ * Env.ChunkSize;

            // Stop if there is no further subdivision possible
            if (isLast)
            {
                // Update chunk's visibility information
                Vector3Int chunkPos = new Vector3Int(wx, wy, wz);
                Chunk      chunk    = world.chunks.Get(ref chunkPos);
                if (chunk == null)
                {
                    return;
                }

                ChunkStateManagerClient stateManager = chunk.stateManager;

                int tx = m_clipmap.TransformX(x);
                int ty = m_clipmap.TransformY(y);
                int tz = m_clipmap.TransformZ(z);

                // Skip chunks which are too far away
                if (!m_clipmap.IsInsideBounds_Transformed(tx, ty, tz))
                {
                    return;
                }

                // Update visibility information
                ClipmapItem item      = m_clipmap.Get_Transformed(tx, ty, tz);
                bool        isVisible = Planes.TestPlanesAABB(m_cameraPlanes, chunk.WorldBounds);

                stateManager.Visible         = isVisible && item.IsInVisibleRange;
                stateManager.PossiblyVisible = isVisible || FullLoadOnStartUp;

                return;
            }

            // Check whether the bouding box lies inside the camera's frustum
            AABB bounds2 = new AABB(wx, wy, wz, wx + rx, wy + ry, wz + rz);
            int  inside  = Planes.TestPlanesAABB2(m_cameraPlanes, bounds2);

            #region Full invisibility

            if (inside == 0)
            {
                // Full invisibility. All chunks in this area need to be made invisible
                for (int cy = wy; cy < wy + ry; cy += Env.ChunkSize)
                {
                    for (int cz = wz; cz < wz + rz; cz += Env.ChunkSize)
                    {
                        for (int cx = wx; cx < wx + rx; cx += Env.ChunkSize)
                        {
                            // Update chunk's visibility information
                            Vector3Int chunkPos = new Vector3Int(cx, cy, cz);
                            Chunk      chunk    = world.chunks.Get(ref chunkPos);
                            if (chunk == null)
                            {
                                continue;
                            }

                            ChunkStateManagerClient stateManager = chunk.stateManager;

                            // Update visibility information
                            stateManager.PossiblyVisible = FullLoadOnStartUp;
                            stateManager.Visible         = false;
                        }
                    }
                }

                return;
            }

            #endregion

            #region Full visibility

            if (inside == 6)
            {
                // Full visibility. All chunks in this area need to be made visible
                for (int cy = wy; cy < wy + ry; cy += Env.ChunkSize)
                {
                    for (int cz = wz; cz < wz + rz; cz += Env.ChunkSize)
                    {
                        for (int cx = wx; cx < wx + rx; cx += Env.ChunkSize)
                        {
                            // Update chunk's visibility information
                            Vector3Int chunkPos = new Vector3Int(cx, cy, cz);
                            Chunk      chunk    = world.chunks.Get(ref chunkPos);
                            if (chunk == null)
                            {
                                continue;
                            }

                            ChunkStateManagerClient stateManager = chunk.stateManager;

                            int tx = m_clipmap.TransformX(x);
                            int ty = m_clipmap.TransformY(y);
                            int tz = m_clipmap.TransformZ(z);

                            // Update visibility information
                            ClipmapItem item = m_clipmap.Get_Transformed(tx, ty, tz);

                            stateManager.Visible         = item.IsInVisibleRange;
                            stateManager.PossiblyVisible = true;
                        }
                    }
                }

                return;
            }

            #endregion

            #region Partial visibility

            int offX = rangeX;
            if (rangeX > 1)
            {
                offX   = rangeX >> 1;
                rangeX = (rangeX + 1) >> 1; // ceil the number
            }
            int offY = rangeY;
            if (rangeY > 1)
            {
                offY   = rangeY >> 1;
                rangeY = (rangeY + 1) >> 1; // ceil the number
            }
            int offZ = rangeZ;
            if (rangeZ > 1)
            {
                offZ   = rangeZ >> 1;
                rangeZ = (rangeZ + 1) >> 1; // ceil the number
            }

            // Subdivide if possible
            // TODO: Avoid the recursion
            UpdateVisibility(x, y, z, offX, offY, offZ);
            UpdateVisibility(x + offX, y, z, rangeX, offY, offZ);
            UpdateVisibility(x, y, z + offZ, offX, offY, rangeZ);
            UpdateVisibility(x + offX, y, z + offZ, rangeX, offY, rangeZ);
            UpdateVisibility(x, y + offY, z, offX, rangeY, offZ);
            UpdateVisibility(x + offX, y + offY, z, rangeX, rangeY, offZ);
            UpdateVisibility(x, y + offY, z + offZ, offX, rangeY, rangeZ);
            UpdateVisibility(x + offX, y + offY, z + offZ, rangeX, rangeY, rangeZ);

            #endregion
        }