public void Swap()
        {
            if (PendingMeshes.Count > 0)
            {
                foreach (var mesh in CurrentMeshes)
                {
                    Object.DestroyImmediate(mesh);
                }

                CurrentMeshes.Clear();

                foreach (var mesh in PendingMeshes)
                {
                    CurrentMeshes.Add(mesh);
                }

                PendingMeshes.Clear();
            }

            if (PendingSplat != null)
            {
                if (CurrentSplat != null)
                {
                    Object.DestroyImmediate(CurrentSplat);
                }

                CurrentSplat = PendingSplat;
                PendingSplat = null;
            }

            CurrentOuter = PendingOuter;
            CurrentInner = PendingInner;
        }
Exemple #2
0
        private void UpdateColliders(int face, SgtLongBounds rect, long middle)
        {
            var cubeC   = SgtTerrainTopology.CubeC[face];
            var cubeH   = SgtTerrainTopology.CubeH[face];
            var cubeV   = SgtTerrainTopology.CubeV[face];
            var step    = 1.0 / resolution;
            var stepX   = cubeH * step;
            var stepY   = cubeV * step;
            var corner  = cubeC + stepX * middle + stepY * middle;
            var centerX = (rect.minX + rect.maxX) / 2;
            var centerY = (rect.minY + rect.maxY) / 2;

            if (rect.SizeZ > 0)
            {
                for (var y = rect.minY; y < rect.maxY; y++)
                {
                    for (var x = rect.minX; x < rect.maxX; x++)
                    {
                        var chunk = default(Chunk);
                        var coord = new Coord()
                        {
                            Face = face, X = x, Y = y
                        };

                        if (chunks.TryGetValue(coord, out chunk) == true)
                        {
                            chunk.Marked = false;
                        }
                        else
                        {
                            chunk = new Chunk()
                            {
                                Face = face, Coord = coord
                            };

                            var root = new GameObject("Collider");

                            root.transform.SetParent(transform, false);

                            root.transform.localPosition = Vector3.zero;
                            root.transform.localRotation = Quaternion.identity;
                            root.transform.localScale    = Vector3.one;

                            chunk.PointC = corner + x * stepX + y * stepY;
                            chunk.PointH = stepX;
                            chunk.PointV = stepY;

                            chunks.Add(coord, chunk);
                        }

                        var distX = math.abs(centerX - x);
                        var distY = math.abs(centerY - y);

                        chunk.Distance = distX * distX + distY * distY;
                    }
                }
            }
        }
Exemple #3
0
        public static SgtLongBounds GetQuadBounds(int index, SgtLongBounds bounds)
        {
            switch (index)
            {
            case 0: return(new SgtLongBounds(bounds.minZ, bounds.minY, bounds.minX, bounds.maxZ, bounds.maxY, bounds.maxX));

            case 1: return(new SgtLongBounds(bounds.minZ, -bounds.maxX, bounds.minY, bounds.maxZ, -bounds.minX, bounds.maxY));

            case 2: return(new SgtLongBounds(-bounds.maxX, bounds.minY, bounds.minZ, -bounds.minX, bounds.maxY, bounds.maxZ));

            case 3: return(new SgtLongBounds(-bounds.maxZ, bounds.minY, -bounds.maxX, -bounds.minZ, bounds.maxY, -bounds.minX));

            case 4: return(new SgtLongBounds(bounds.minZ, bounds.minX, -bounds.maxY, bounds.maxZ, bounds.maxX, -bounds.minY));

            case 5: return(new SgtLongBounds(bounds.minX, bounds.minY, -bounds.maxZ, bounds.maxX, bounds.maxY, -bounds.minZ));
            }

            return(bounds);
        }
Exemple #4
0
        private void UpdateRoot()
        {
            var point  = cachedTerrain.GetAboveGroundObserverCubePoint();
            var middle = resolution / 2;
            var center = middle * point;
            var bounds = new SgtLongBounds((long)center.x, (long)center.y, (long)center.z, radius);
            var outer  = new SgtLongBounds(-middle, -middle, middle - 1, middle, middle, middle);

            Mark();

            for (var i = 0; i < 6; i++)
            {
                var quadBounds = SgtTerrainTopology.GetQuadBounds(i, bounds);

                quadBounds.ClampTo(outer);

                UpdateColliders(i, quadBounds, middle);
            }

            Sweep();
        }
        public void UpdateDebris()
        {
            if (target != null && cellCount > 0.0f && prefabs != null && debrisCountTarget > 0)
            {
                var cellSize   = (long)System.Math.Ceiling(hideDistance / cellCount);
                var worldPoint = target.position - transform.position;
                var centerX    = (long)System.Math.Round(worldPoint.x / cellSize);
                var centerY    = (long)System.Math.Round(worldPoint.y / cellSize);
                var centerZ    = (long)System.Math.Round(worldPoint.z / cellSize);
                var newBounds  = new SgtLongBounds(centerX, centerY, centerZ, cellCount);

                if (newBounds != bounds)
                {
                    var probability = debrisCountTarget / (cellSize * cellSize * cellSize);
                    var cellMin     = cellSize * (0.5f - cellNoise);
                    var cellMax     = cellSize * (0.5f + cellNoise);

                    for (var z = newBounds.minZ; z <= newBounds.maxZ; z++)
                    {
                        for (var y = newBounds.minY; y <= newBounds.maxY; y++)
                        {
                            for (var x = newBounds.minX; x <= newBounds.maxX; x++)
                            {
                                if (bounds.Contains(x, y, z) == false)
                                {
                                    SgtHelper.BeginRandomSeed(seed, x, y, z);
                                    {
                                        // Can debris potentially spawn in this cell?
                                        if (Random.value < probability)
                                        {
                                            var debrisPoint = default(Vector3);

                                            debrisPoint.x = x * cellSize + Random.Range(cellMin, cellMax);
                                            debrisPoint.y = y * cellSize + Random.Range(cellMin, cellMax);
                                            debrisPoint.z = z * cellSize + Random.Range(cellMin, cellMax);

                                            // Spawn everywhere, or only inside specified shapes?
                                            if (spawnInside == null || Random.value < spawnInside.GetDensity(debrisPoint))
                                            {
                                                Spawn(x, y, z, debrisPoint);
                                            }
                                        }
                                    }
                                    SgtHelper.EndRandomSeed();
                                }
                            }
                        }
                    }

                    bounds = newBounds;

                    if (spawnedDebris != null)
                    {
                        for (var i = spawnedDebris.Count - 1; i >= 0; i--)
                        {
                            var debris = spawnedDebris[i];

                            if (debris == null)
                            {
                                spawnedDebris.RemoveAt(i);
                            }
                            else if (bounds.Contains(debris.Cell) == false)
                            {
                                Despawn(debris, i);
                            }
                        }
                    }
                }

                UpdateDebrisScale(target.position);
            }
            else
            {
                ClearDebris();
            }
        }
Exemple #6
0
        private void UpdateLod()
        {
            var spherePoint = GetSpherePoint();

            for (var i = 0; i < cubes.Count; i++)
            {
                var cube       = cubes[i];
                var cubeBounds = GetCubeBound(i, spherePoint, cube.Middle);
                var cubeLimits = new SgtLongBounds(0, 0, 0, cube.Middle);

                for (var j = 0; j < 6; j++)
                {
                    var quad       = cube.Quads[j];
                    var quadBounds = SgtTerrainTopology.GetQuadBounds(j, cubeBounds);

                    if (i == 0)
                    {
                        quad.PendingOuter = new SgtLongBounds(0, 0, 0, cube.Middle);
                        quad.VirtualOuter = new SgtLongBounds(0, 0, 0, cube.Middle * 2);
                    }
                    else
                    {
                        var prevCube       = cubes[i - 1];
                        var prevQuad       = prevCube.Quads[j];
                        var prevResolution = prevCube.Resolution;

                        quad.PendingOuter = prevQuad.PendingInner * 2;
                        quad.VirtualOuter = prevQuad.VirtualInner * 2;
                    }

                    if (quadBounds.minZ <= cube.Middle && quadBounds.maxZ >= cube.Middle)
                    {
                        quad.VirtualInner = quadBounds;
                    }
                    else
                    {
                        quad.VirtualInner = default(SgtLongBounds);
                    }

                    quad.PendingInner = quad.VirtualInner;
                    quad.PendingInner.ClampTo(cubeLimits);

                    if (quad.PendingOuter.SizeX < 0 || quad.PendingOuter.SizeY < 0 || quad.PendingOuter.SizeZ < 0)
                    {
                        quad.PendingOuter = default(SgtLongBounds);
                        quad.PendingInner = default(SgtLongBounds);
                    }

                    var forceUpdate = false;

                    if (dirty == true)
                    {
                        if (quad.CurrentOuter.Volume > 0 || quad.CurrentInner.Volume > 0)
                        {
                            forceUpdate = true;

                            quad.CurrentOuter.Clear();
                            quad.CurrentInner.Clear();
                        }
                    }

                    if (quad.CurrentOuter.Volume == 0)
                    {
                        quad.CurrentOuter = default(SgtLongBounds);
                    }
                    if (quad.PendingOuter.Volume == 0)
                    {
                        quad.PendingOuter = default(SgtLongBounds);
                    }
                    if (quad.CurrentInner.Volume == 0)
                    {
                        quad.CurrentInner = default(SgtLongBounds);
                    }
                    if (quad.PendingInner.Volume == 0)
                    {
                        quad.PendingInner = default(SgtLongBounds);
                    }

                    if (quad.CurrentOuter != quad.PendingOuter || quad.CurrentInner != quad.PendingInner || forceUpdate == true)
                    {
                        pendingQuads.Push(quad);
                    }
                }
            }

            dirty = false;
        }