Пример #1
0
        void Update()
        {
            // Rotation
            if (Input.GetMouseButton(1))
            {
                rot = new Vector2(
                    rot.x + Input.GetAxis("Mouse X") * 3,
                    rot.y + Input.GetAxis("Mouse Y") * 3
                    );

                cam.transform.localRotation  = Quaternion.AngleAxis(rot.x, Vector3.up);
                cam.transform.localRotation *= Quaternion.AngleAxis(rot.y, Vector3.left);
            }

            //Movement
            bool turbo = Input.GetKeyDown(KeyCode.LeftShift) || Input.GetKeyDown(KeyCode.RightShift);

            cam.transform.position += cam.transform.forward * 40 * (turbo ? 3 : 1) * Input.GetAxis("Vertical") * Time.deltaTime;
            cam.transform.position += cam.transform.right * 40 * (turbo ? 3 : 1) * Input.GetAxis("Horizontal") * Time.deltaTime;

            if (objRenderer != null && txt != null)
            {
                Planes.CalculateFrustumPlanes(cam, planes);
                Bounds b = objRenderer.bounds;
                Planes.TestPlanesResult res = Planes.TestPlanesAABB2(planes, ref b);
                switch (res)
                {
                case Planes.TestPlanesResult.Outside:
                    txt.text = "Outside";
                    break;

                case Planes.TestPlanesResult.Inside:
                    txt.text = "Inside";
                    break;

                default:
                    txt.text = "PartialyInside";
                    break;
                }
            }
        }
Пример #2
0
        protected override void UpdateVisibility(int x, int y, int z, int rangeX, int rangeY, int rangeZ)
        {
            if (rangeX == 0 || rangeY == 0 || rangeZ == 0)
            {
                return;
            }

            Profiler.BeginSample("Cull");

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

            int wx = x * Env.CHUNK_SIZE;
            int wy = y * Env.CHUNK_SIZE;
            int wz = z * Env.CHUNK_SIZE;

            // Stop if there is no further subdivision possible
            if (isLast)
            {
                Profiler.BeginSample("CullLast");

                // Update chunk's visibility information
                Vector3Int chunkPos = new Vector3Int(wx, wy, wz);
                Chunk      chunk    = world.GetChunk(ref chunkPos);
                if (chunk != null)
                {
                    int tx = clipmap.TransformX(x);
                    int ty = clipmap.TransformY(y);
                    int tz = clipmap.TransformZ(z);

                    // Skip chunks which are too far away
                    if (clipmap.IsInsideBounds_Transformed(tx, ty, tz))
                    {
                        // Update visibility information
                        ClipmapItem item      = clipmap.Get_Transformed(tx, ty, tz);
                        bool        isVisible = Planes.TestPlanesAABB(cameraPlanes, ref chunk.worldBounds);

                        chunk.NeedsRenderGeometry = isVisible && item.isInVisibleRange;
                        chunk.PossiblyVisible     = isVisible;
                    }
                }

                Profiler.EndSample(); // CullLast
                Profiler.EndSample(); // Cull
                return;
            }

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

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

            Planes.TestPlanesResult res = Planes.TestPlanesAABB2(cameraPlanes, ref bounds2);

            #region Full invisibility

            // Everything is invisible by default
            if (res == Planes.TestPlanesResult.Outside)
            {
                Profiler.EndSample(); // Cull
                return;
            }

            #endregion

            #region Full visibility

            if (res == Planes.TestPlanesResult.Inside)
            {
                Profiler.BeginSample("CullFullInside");

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

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

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

                            chunk.NeedsRenderGeometry = item.isInVisibleRange;
                            chunk.PossiblyVisible     = true;
                        }
                    }
                }

                Profiler.EndSample(); // CullLast
                Profiler.EndSample(); // Cull
                return;
            }

            #endregion

            #region Partial visibility

            int offX = rangeX;
            if (rangeX > 1)
            {
                offX    = rangeX >> 1;
                rangeX -= offX;
            }
            int offY = rangeY;
            if (rangeY > 1)
            {
                offY    = rangeY >> 1;
                rangeY -= offY;
            }
            int offZ = rangeZ;
            if (rangeZ > 1)
            {
                offZ    = rangeZ >> 1;
                rangeZ -= offZ;
            }

            Profiler.EndSample();

            // 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
        }