示例#1
0
        public ClipmapItem Get_Transformed(int tx, int ty, int tz)
        {
            // Clamp coordinates to the array range
            int xx = tx.Clamp(0, m_axes[0].Map.Length - 1);
            int yy = ty.Clamp(0, m_axes[1].Map.Length - 1);
            int zz = tz.Clamp(0, m_axes[2].Map.Length - 1);

            // Pick the furthest one
            int absX = Helpers.Abs(xx);
            int absY = Helpers.Abs(yy);
            int absZ = Helpers.Abs(zz);

            if (absX > absZ)
            {
                return((absX > absY) ? m_axes[0].Map[xx] : m_axes[1].Map[yy]);
            }

            return(absZ > absY ? m_axes[2].Map[zz] : m_axes[1].Map[yy]);
        }
示例#2
0
        protected override void OnProcessChunk(Chunk chunk)
        {
            Profiler.BeginSample("ProcessChunk");

            int tx = m_clipmap.TransformX(chunk.Pos.x / Env.ChunkSize);
            int ty = m_clipmap.TransformY(chunk.Pos.y / Env.ChunkSize);
            int tz = m_clipmap.TransformZ(chunk.Pos.z / Env.ChunkSize);

            // Chunk is too far away. Remove it
            if (!m_clipmap.IsInsideBounds_Transformed(tx, ty, tz))
            {
                chunk.RequestRemoval();
            }
            else
            {
                // Dummy collider example - create a collider for chunks directly surrounding the viewer
                int xd = Helpers.Abs((m_viewerPos.x - chunk.Pos.x) / Env.ChunkSize);
                int yd = Helpers.Abs((m_viewerPos.y - chunk.Pos.y) / Env.ChunkSize);
                int zd = Helpers.Abs((m_viewerPos.z - chunk.Pos.z) / Env.ChunkSize);
                chunk.NeedsColliderGeometry = xd <= 1 && yd <= 1 && zd <= 1;

                if (!UseFrustumCulling)
                {
                    ClipmapItem item = m_clipmap.Get_Transformed(tx, ty, tz);

                    // Chunk is in visibilty range. Full update with geometry generation is possible
                    if (item.IsInVisibleRange)
                    {
                        //chunk.LOD = item.LOD;
                        chunk.PossiblyVisible     = true;
                        chunk.NeedsRenderGeometry = true;
                    }
                    // Chunk is in cached range. Full update except for geometry generation
                    else
                    {
                        //chunk.LOD = item.LOD;
                        chunk.PossiblyVisible     = true;
                        chunk.NeedsRenderGeometry = false;
                    }
                }
            }
        }
示例#3
0
        public static Vector3Int[] ChunkPositions(int chunkLoadRadius)
        {
            var chunkLoads = new List <Vector3Int>();

            for (int z = -chunkLoadRadius; z <= chunkLoadRadius; z++)
            {
                for (int x = -chunkLoadRadius; x <= chunkLoadRadius; x++)
                {
                    chunkLoads.Add(new Vector3Int(x, 0, z));
                }
            }

            //sort 2d vectors by closeness to center
            return(chunkLoads
                   .Where(pos => pos.x * pos.x + pos.z * pos.z <= chunkLoadRadius * chunkLoadRadius) // keep this a circle
                   .OrderBy(pos => Helpers.Abs(pos.x) + Helpers.Abs(pos.z))                          //smallest magnitude vectors first
                   .ThenBy(pos => Helpers.Abs(pos.x))                                                //make sure not to process e.g (-10,0) before (5,5)
                   .ThenBy(pos => Helpers.Abs(pos.z))
                   .ToArray());
        }
示例#4
0
        public static Vector3Int[] ChunkPositions(int chunkLoadRadius)
        {
            s_chunkLoads.Clear();

            for (int z = -chunkLoadRadius; z <= chunkLoadRadius; z++)
            {
                for (int x = -chunkLoadRadius; x <= chunkLoadRadius; x++)
                {
                    s_chunkLoads.Add(new Vector3Int(x, 0, z));
                }
            }

            // Sort 2D vectors by closeness to the center
            return(s_chunkLoads
                   .Where(pos => CheckXZ(pos.x, pos.z, chunkLoadRadius))
                   // Smallest magnitude vectors first
                   .OrderBy(pos => Helpers.Abs(pos.x) + Helpers.Abs(pos.z))
                   // Make sure not to process e.g (-10,0) before (5,5)
                   .ThenBy(pos => Helpers.Abs(pos.x))
                   .ThenBy(pos => Helpers.Abs(pos.z))
                   .ToArray());
        }
示例#5
0
        public static Vector3Int[] ChunkPositions(int chunkLoadRadius)
        {
            var chunkLoads = new List <Vector3Int>();

            for (int x = -chunkLoadRadius; x <= chunkLoadRadius; x++)
            {
                for (int z = -chunkLoadRadius; z <= chunkLoadRadius; z++)
                {
                    chunkLoads.Add(new Vector3Int(x, 0, z));
                }
            }

            // limit how far away the blocks can be to achieve a circular loading pattern
            float maxRadius = chunkLoadRadius * 1.55f;

            //sort 2d vectors by closeness to center
            return(chunkLoads
                   .Where(pos => Helpers.Abs(pos.x) + Helpers.Abs(pos.z) < maxRadius)
                   .OrderBy(pos => Helpers.Abs(pos.x) + Helpers.Abs(pos.z)) //smallest magnitude vectors first
                   .ThenBy(pos => Helpers.Abs(pos.x))                       //make sure not to process e.g (-10,0) before (5,5)
                   .ThenBy(pos => Helpers.Abs(pos.z))
                   .ToArray());
        }
示例#6
0
        public void ProcessChunk(Chunk chunk)
        {
            Profiler.BeginSample("ProcessChunk");

            ChunkStateManagerClient stateManager = chunk.stateManager;

            int xd = (m_viewerPos.x - chunk.pos.x) / Env.ChunkSize;
            int yd = (m_viewerPos.y - chunk.pos.y) / Env.ChunkSize;
            int zd = (m_viewerPos.z - chunk.pos.z) / Env.ChunkSize;

            int hRadius = HorizontalChunkLoadRadius;
            int vRadius = VerticalChunkLoadRadius;
            int xDist   = xd * xd + zd * zd;
            int yDist   = yd * yd;

            // Remove the chunk if it is too far away
            if (xDist > hRadius * hRadius || yDist > vRadius * vRadius)
            {
                stateManager.RequestState(ChunkState.Remove);
            }
            else
            {
                // Dummy collider example - create a collider for chunks directly surrounding the viewer
                chunk.NeedsCollider = Helpers.Abs(xd) <= 1 && Helpers.Abs(yd) <= 1 && Helpers.Abs(zd) <= 1;

                if (!UseFrustumCulling)
                {
                    // Update visibility information
                    stateManager.Visible = xDist <= HorizontalChunkLoadRadius * HorizontalChunkLoadRadius &&
                                           yDist <= VerticalChunkLoadRadius * VerticalChunkLoadRadius;
                    stateManager.PossiblyVisible = true;
                }
            }

            Profiler.EndSample();
        }
示例#7
0
        public void ProcessChunk(Chunk chunk)
        {
            int xd = Helpers.Abs((m_viewerPos.x - chunk.pos.x) >> Env.ChunkPower);
            int yd = Helpers.Abs((m_viewerPos.y - chunk.pos.y) >> Env.ChunkPower);
            int zd = Helpers.Abs((m_viewerPos.z - chunk.pos.z) >> Env.ChunkPower);

            int tx = m_clipmap.TransformX(chunk.pos.x >> Env.ChunkPower);
            int ty = m_clipmap.TransformY(chunk.pos.y >> Env.ChunkPower);
            int tz = m_clipmap.TransformZ(chunk.pos.z >> Env.ChunkPower);

            ChunkStateManagerClient stateManager = (ChunkStateManagerClient)chunk.stateManager;

            // Chunk is too far away. Remove it
            if (!m_clipmap.IsInsideBounds_Transformed(tx, ty, tz))
            {
                stateManager.RequestState(ChunkState.Remove);
            }
            else
            {
                // Dummy collider example - create a collider for chunks directly surrounding the viewer
                chunk.NeedsCollider = xd <= 1 && yd <= 1 && zd <= 1;

                // Chunk is within view frustum
                if (FullLoadOnStartUp || IsChunkInViewFrustum(chunk))
                {
                    ClipmapItem item = m_clipmap.Get_Transformed(tx, ty, tz);

                    // Chunk is within visibilty range. Full update with geometry generation is possible
                    if (item.IsWithinVisibleRange)
                    {
                        //chunk.LOD = item.LOD;
                        stateManager.PossiblyVisible = true;
                        stateManager.Visible         = true;
                    }
                    // Chunk is within cached range. Full update except for geometry generation
                    else // if (item.IsWithinCachedRange)
                    {
                        //chunk.LOD = item.LOD;
                        stateManager.PossiblyVisible = true;
                        stateManager.Visible         = false;
                    }
                }
                else
                {
                    ClipmapItem item = m_clipmap.Get_Transformed(tx, ty, tz);

                    // Chunk is not in the view frustum but still within cached range
                    if (item.IsWithinCachedRange)
                    {
                        //chunk.LOD = item.LOD;
                        stateManager.PossiblyVisible = false;
                        stateManager.Visible         = false;
                    }
                    else
                    // Weird state
                    {
                        Assert.IsFalse(true);
                        stateManager.RequestState(ChunkState.Remove);
                    }
                }
            }
        }
        void Benchmark_AbsValue()
        {
            Debug.Log("Bechmark - abs");
            using (StreamWriter writer = File.CreateText("perf_abs.txt"))
            {
                int[]  number = { 0 };
                double t      = Clock.BenchmarkTime(() =>
                {
                    ++number[0];
                    number[0] = Mathf.Abs(number[0]);
                }, 1000000
                                                    );
                Debug.LogFormat("Mathf.abs -> out:{0}, time:{1}", number[0], t.ToString(CultureInfo.InvariantCulture));
                writer.WriteLine("Mathf.abs -> out:{0}, time:{1}", number[0], t.ToString(CultureInfo.InvariantCulture));

                number[0] = 0;
                t         = Clock.BenchmarkTime(() =>
                {
                    ++number[0];
                    number[0] = Math.Abs(number[0]);
                }, 1000000
                                                );
                Debug.LogFormat("Math.abs -> out:{0}, time:{1}", number[0], t.ToString(CultureInfo.InvariantCulture));
                writer.WriteLine("Math.abs -> out:{0}, time:{1}", number[0], t.ToString(CultureInfo.InvariantCulture));

                number[0] = 0;
                t         = Clock.BenchmarkTime(() =>
                {
                    ++number[0];
                    number[0] = number[0] < 0 ? -number[0] : number[0];
                }, 1000000
                                                );
                Debug.LogFormat("i < 0 ? -i : i -> out:{0}, time:{1}", number[0], t.ToString(CultureInfo.InvariantCulture));
                writer.WriteLine("i < 0 ? -i : i -> out:{0}, time:{1}", number[0], t.ToString(CultureInfo.InvariantCulture));

                number[0] = 0;
                t         = Clock.BenchmarkTime(() =>
                {
                    ++number[0];
                    int mask  = number[0] >> 31;
                    number[0] = (number[0] + mask) ^ mask;
                }, 1000000
                                                );
                Debug.LogFormat("(i + mask) ^ mask -> out:{0}, time:{1}", number[0], t.ToString(CultureInfo.InvariantCulture));
                writer.WriteLine("(i + mask) ^ mask -> out:{0}, time:{1}", number[0], t.ToString(CultureInfo.InvariantCulture));

                number[0] = 0;
                t         = Clock.BenchmarkTime(() =>
                {
                    ++number[0];
                    number[0] = (number[0] + (number[0] >> 31)) ^ (number[0] >> 31);
                }, 1000000
                                                );
                Debug.LogFormat("(i + (i >> 31)) ^ (i >> 31) -> out:{0}, time:{1}", number[0], t.ToString(CultureInfo.InvariantCulture));
                writer.WriteLine("(i + (i >> 31)) ^ (i >> 31) -> out:{0}, time:{1}", number[0], t.ToString(CultureInfo.InvariantCulture));

                number[0] = 0;
                t         = Clock.BenchmarkTime(() =>
                {
                    ++number[0];
                    number[0] = Helpers.Abs(number[0]);
                }, 1000000
                                                );
                Debug.LogFormat("Helpers.abs -> out:{0}, time:{1}", number[0], t.ToString(CultureInfo.InvariantCulture));
                writer.WriteLine("Helpers.Abs -> out:{0}, time:{1}", number[0], t.ToString(CultureInfo.InvariantCulture));
            }
        }
        protected override void OnProcessChunk(Chunk chunk)
        {
            Profiler.BeginSample("ProcessChunk");

            int xd = (m_viewerPos.x - chunk.Pos.x) / Env.ChunkSize;
            int yd = (m_viewerPos.y - chunk.Pos.y) / Env.ChunkSize;
            int zd = (m_viewerPos.z - chunk.Pos.z) / Env.ChunkSize;

            // Remove the chunk if it is too far away
            if (
                !ChunkLoadOrder.CheckXZ(xd, zd, HorizontalChunkLoadRadius) ||
                !ChunkLoadOrder.CheckY(yd, VerticalChunkLoadRadius)
                )
            {
                chunk.RequestRemoval();
            }
            else
            {
                // Dummy collider example - create a collider for chunks directly surrounding the viewer
                chunk.NeedsColliderGeometry = Helpers.Abs(xd) <= 1 && Helpers.Abs(yd) <= 1 && Helpers.Abs(zd) <= 1;

                if (!UseFrustumCulling)
                {
                    // Update visibility information
                    chunk.NeedsRenderGeometry = true;
                    chunk.PossiblyVisible     = true;
                }
            }

            Profiler.EndSample();
        }
示例#10
0
        void Benchmark_AbsValue()
        {
            const int iters = 1000000;

            Debug.Log("Bechmark - abs");
            using (StreamWriter writer = File.CreateText("perf_abs.txt"))
            {
                int[]  number = { 0 };
                double t      = Clock.BenchmarkTime(
                    () =>
                {
                    ++number[0];
                    number[0] = Mathf.Abs(number[0]);
                }, iters
                    );
                t2     = t / iters;
                output = string.Format("Mathf.abs\nout:{0}\ntime:{1} | {2} ms",
                                       number[0], t.ToString(CultureInfo.InvariantCulture), t2.ToString(CultureInfo.InvariantCulture));
                Debug.Log(output);
                foreach (string s in output.Split('\n'))
                {
                    writer.WriteLine(s);
                }

                number[0] = 0;
                t         = Clock.BenchmarkTime(
                    () =>
                {
                    ++number[0];
                    number[0] = Math.Abs(number[0]);
                }, iters
                    );
                t2     = t / iters;
                output = string.Format("Math.abs\nout:{0}\ntime:{1} | {2} ms",
                                       number[0], t.ToString(CultureInfo.InvariantCulture), t2.ToString(CultureInfo.InvariantCulture));
                Debug.Log(output);
                foreach (string s in output.Split('\n'))
                {
                    writer.WriteLine(s);
                }

                number[0] = 0;
                t         = Clock.BenchmarkTime(
                    () =>
                {
                    ++number[0];
                    number[0] = Helpers.Abs(number[0]);
                }, iters
                    );
                t2     = t / iters;
                output = string.Format("Helpers.Abs\nout:{0}\ntime:{1} | {2} ms",
                                       number[0], t.ToString(CultureInfo.InvariantCulture), t2.ToString(CultureInfo.InvariantCulture));
                Debug.Log(output);
                foreach (string s in output.Split('\n'))
                {
                    writer.WriteLine(s);
                }

                number[0] = 0;
                t         = Clock.BenchmarkTime(
                    () =>
                {
                    ++number[0];
                    number[0] = number[0] < 0 ? -number[0] : number[0];
                }, iters
                    );
                t2     = t / iters;
                output = string.Format("i < 0 ? -i : i\nout:{0}\ntime:{1} | {2} ms",
                                       number[0], t.ToString(CultureInfo.InvariantCulture), t2.ToString(CultureInfo.InvariantCulture));
                Debug.Log(output);
                foreach (string s in output.Split('\n'))
                {
                    writer.WriteLine(s);
                }

                number[0] = 0;
                t         = Clock.BenchmarkTime(
                    () =>
                {
                    ++number[0];
                    int mask  = number[0] >> 31;
                    number[0] = (number[0] + mask) ^ mask;
                }, iters
                    );
                t2     = t / iters;
                output = string.Format("(i + mask) ^ mask\nout:{0}\ntime:{1} | {2} ms",
                                       number[0], t.ToString(CultureInfo.InvariantCulture), t2.ToString(CultureInfo.InvariantCulture));
                Debug.Log(output);
                foreach (string s in output.Split('\n'))
                {
                    writer.WriteLine(s);
                }

                number[0] = 0;
                t         = Clock.BenchmarkTime(
                    () =>
                {
                    ++number[0];
                    number[0] = (number[0] + (number[0] >> 31)) ^ (number[0] >> 31);
                }, iters
                    );
                t2     = t / iters;
                output = string.Format("(i + (i >> 31)) ^ (i >> 31)\nout:{0}\ntime:{1} | {2} ms",
                                       number[0], t.ToString(CultureInfo.InvariantCulture), t2.ToString(CultureInfo.InvariantCulture));
                Debug.Log(output);
                foreach (string s in output.Split('\n'))
                {
                    writer.WriteLine(s);
                }
            }
        }
示例#11
0
        private void OnDrawGizmosSelected()
        {
            if (!enabled)
            {
                return;
            }

            float size      = Env.ChunkSize * Env.BlockSize;
            float halfSize  = size * 0.5f;
            float smallSize = size * 0.25f;

            if (world != null && world.chunks != null && (Diag_DrawWorldBounds || Diag_DrawLoadRange))
            {
                foreach (Chunk chunk in world.chunks.chunkCollection)
                {
                    if (Diag_DrawWorldBounds)
                    {
                        // Make central chunks more apparent by using yellow color
                        bool isCentral = chunk.pos.x == m_viewerPos.x || chunk.pos.y == m_viewerPos.y || chunk.pos.z == m_viewerPos.z;
                        Gizmos.color = isCentral ? Color.yellow : Color.blue;
                        Vector3 chunkCenter = new Vector3(
                            chunk.pos.x + (Env.ChunkSize >> 1),
                            chunk.pos.y + (Env.ChunkSize >> 1),
                            chunk.pos.z + (Env.ChunkSize >> 1)
                            );
                        Vector3 chunkSize = new Vector3(Env.ChunkSize, Env.ChunkSize, Env.ChunkSize);
                        Gizmos.DrawWireCube(chunkCenter, chunkSize);
                    }

                    if (Diag_DrawLoadRange)
                    {
                        Vector3Int pos  = chunk.pos;
                        int        xd   = Helpers.Abs((m_viewerPos.x - pos.x) / Env.ChunkSize);
                        int        zd   = Helpers.Abs((m_viewerPos.z - pos.z) / Env.ChunkSize);
                        int        dist = xd * xd + zd * zd;
                        if (dist <= HorizontalChunkLoadRadius * HorizontalChunkLoadRadius)
                        {
                            Gizmos.color = Color.green;
                            Gizmos.DrawWireCube(
                                new Vector3(chunk.pos.x + halfSize, 0, chunk.pos.z + halfSize),
                                new Vector3(size - 1f, 0, size - 1f)
                                );
                        }
                        else
                        {
                            Gizmos.color = Color.red;
                            Gizmos.DrawWireCube(
                                new Vector3(chunk.pos.x + halfSize, 0, chunk.pos.z + halfSize),
                                new Vector3(size - 1f, 0, size - 1f)
                                );
                        }

                        // Show generated chunks
                        ChunkStateManagerClient stateManager = chunk.stateManager;
                        if (stateManager.IsStateCompleted(ChunkState.Generate))
                        {
                            Gizmos.color = Color.magenta;
                            Gizmos.DrawWireCube(
                                new Vector3(chunk.pos.x + halfSize, 0, chunk.pos.z + halfSize),
                                new Vector3(smallSize - 0.05f, 0, smallSize - 0.05f)
                                );
                        }
                    }
                }
            }
        }
示例#12
0
 public static bool CheckY(int y, int dist)
 {
     return(Helpers.Abs(y) <= dist); // square
 }