Example #1
0
    private void AddObject(Face face, SgtTerrain.Ring ring, long x, long y)
    {
        if (Prefabs != null && Prefabs.Count > 0)
        {
            var index  = Random.Range(0, Prefabs.Count);
            var prefab = Prefabs[index];

            if (prefab != null)
            {
                var stepX  = ring.ExtentsX / ring.Detail;
                var stepY  = ring.ExtentsY / ring.Detail;
                var point  = ring.Center + x * stepX + y * stepY;
                var height = terrain.GetLocalHeight(point);

                if (height >= HeightMin && height < HeightMax)
                {
                    var clone = Spawn(prefab);

                    clone.Prefab = prefab;
                    clone.X      = x;
                    clone.Y      = y;

                    clone.Spawn(terrain, face.Level, point);

                    if (face.Clones == null)
                    {
                        face.Clones = new List <SgtTerrainObject>();
                    }

                    face.Clones.Add(clone);
                }
            }
        }
    }
Example #2
0
    private void CalculateLevel(SgtTerrainLevel level, SgtTerrain.Ring ring)
    {
        var face = GetFace(level);

        if (level.Index == Depth && ring != null)
        {
            if (face == null)
            {
                face = new Face();

                face.Level = level;

                faces.Add(face);
            }

            face.Clear(ring);

            for (var y = ring.Outer.minY; y <= ring.Outer.maxY; y++)
            {
                for (var x = ring.Outer.minX; x <= ring.Outer.maxX; x++)
                {
                    if (x >= face.Rect.minX && x < face.Rect.maxX && y >= face.Rect.minY && y < face.Rect.maxY)
                    {
                        continue;
                    }

                    if (Random.value < SpawnProbability)
                    {
                        AddObject(face, ring, x, y);
                    }
                }
            }

            face.Rect = ring.Outer;
        }
        else
        {
            if (face != null)
            {
                face.Clear();

                faces.Remove(face);
            }
        }
    }
Example #3
0
        public void Clear(SgtTerrain.Ring ring)
        {
            if (Clones != null)
            {
                for (var i = Clones.Count - 1; i >= 0; i--)
                {
                    var clone = Clones[i];

                    if (clone != null)
                    {
                        if (ring.Outer.Contains(clone.X, clone.Y) == false)
                        {
                            Despawn(clone);

                            Clones.RemoveAt(i);
                        }
                    }
                    else
                    {
                        Clones.RemoveAt(i);
                    }
                }
            }
        }
Example #4
0
    public void Write(SgtTerrain.Ring ring)
    {
        if (ring.Outer == outerRegion && ring.Inner == innerRegion)
        {
            return;
        }

        size = ring.Limit + 3;

        var terrain        = Face.Terrain;
        var total          = size * size;
        var newBasicRegion = ring.Outer.GetExpanded(1);

        if (positions == null || positions.Length != total)
        {
            basicRegion.Clear();
            outerRegion.Clear();

            positions = new Vector3[total];
            normals   = new Vector3[total];
            coords1   = new Vector2[total];
            coords2   = new Vector2[total];
        }

        // Write position & uv data
        var stepX = ring.ExtentsX / ring.Detail;
        var stepY = ring.ExtentsY / ring.Detail;

        for (var y = newBasicRegion.minY; y <= newBasicRegion.maxY; y++)
        {
            for (var x = newBasicRegion.minX; x <= newBasicRegion.maxX; x++)
            {
                if (basicRegion.Contains(x, y) == false)
                {
                    var index     = Wrap(x, y, size);
                    var point     = ring.Center + x * stepX + y * stepY;
                    var coord1U   = (x / (double)ring.Detail + 1.0) / 2.0;      // 0 .. 1
                    var coord1V   = (y / (double)ring.Detail + 1.0) / 2.0;      // 0 .. 1
                    var coord2U   = x / (double)ring.Limit;                     // -u .. u
                    var coord2V   = y / (double)ring.Limit;                     // -v .. v
                    var height    = terrain.GetLocalHeight(point);
                    var direction = point.normalized;
                    var position  = direction * height;

                    positions[index] = (Vector3)position;

                    coords1[index] = new Vector2((float)coord1U, (float)coord1V);
                    coords2[index] = new Vector2((float)coord2U, (float)coord2V);
                }
            }
        }

        var parent = Face.LastLevel;

        WriteNormals(ring.Outer, outerRegion);

        if (parent != null)
        {
            // Write edges from parent to avoid normal seams from resolution shift
            if (ring.Outer.minX > -ring.Detail)
            {
                WriteParentNormals(parent, ring.Outer.minX, ring.Outer.minY, ring.Outer.minX, ring.Outer.maxY);                                             // Left
            }
            if (ring.Outer.maxX < ring.Detail)
            {
                WriteParentNormals(parent, ring.Outer.maxX, ring.Outer.minY, ring.Outer.maxX, ring.Outer.maxY);                                             // Right
            }
            if (ring.Outer.minY > -ring.Detail)
            {
                WriteParentNormals(parent, ring.Outer.minX, ring.Outer.minY, ring.Outer.maxX, ring.Outer.minY);                                             // Bottom
            }
            if (ring.Outer.maxY < ring.Detail)
            {
                WriteParentNormals(parent, ring.Outer.minX, ring.Outer.maxY, ring.Outer.maxX, ring.Outer.maxY);                                             // Top
            }
        }

        // Write indices
        WriteIndices(ring.Outer, ring.Inner, ring.Detail, size);

        var mesh = GetMesh();

        mesh.Clear();
        mesh.vertices = positions;
        mesh.normals  = normals;
        mesh.uv       = coords1;
        mesh.uv2      = coords2;
        mesh.SetTriangles(indices, 0);

        mesh.bounds = terrain.GetBounds();

        if (terrain.MaxColliderDepth > Index)
        {
            if (meshCollider == null)
            {
                meshCollider = GetComponent <MeshCollider>();
            }
            if (meshCollider == null)
            {
                meshCollider = gameObject.AddComponent <MeshCollider>();
            }

            // Is this the last collider, but not the last LOD level?
            if (terrain.MaxColliderDepth == Index + 1 && ring.Inner.SizeX > 0 && ring.Inner.SizeY > 0)
            {
                var colliderMesh = GetColliderMesh();

                WriteIndices(ring.Outer, default(SgtRectL), ring.Detail, size);

                colliderMesh.Clear();
                colliderMesh.vertices = positions;
                colliderMesh.SetTriangles(indices, 0);

                meshCollider.sharedMesh = colliderMesh;
            }
            // If not, use the visual mesh
            else
            {
                PoolColliderMeshNow(false);

                meshCollider.sharedMesh = mesh;
            }
        }
        else
        {
            PoolColliderMeshNow();
        }

        basicRegion = newBasicRegion;
        outerRegion = ring.Outer;
        innerRegion = ring.Inner;

        Face.LastLevel = this;

        if (terrain.OnCalculateLevel != null)
        {
            terrain.OnCalculateLevel(this, ring);
        }
    }