public void PositionChanged(Transform parent, SgtTerrainFace face)
        {
            if (Point != null)
            {
                var center = (Vector3)face.Bounds.Center;

                face.transform.parent     = SgtFloatingRoot.GetRoot();
                face.transform.position   = transform.position + transform.rotation * center * transform.lossyScale.x;
                face.transform.rotation   = transform.rotation;
                face.transform.localScale = transform.lossyScale;
            }
            else
            {
                face.transform.parent        = parent;
                face.transform.localPosition = Vector3.zero;
                face.transform.localRotation = Quaternion.identity;
                face.transform.localScale    = Vector3.one;
            }

            if (face.Split == true)
            {
                PositionChanged(face.transform, face.ChildBL);
                PositionChanged(face.transform, face.ChildBR);
                PositionChanged(face.transform, face.ChildTL);
                PositionChanged(face.transform, face.ChildTR);
            }
        }
Example #2
0
        public void Spawn(SgtTerrain terrain, SgtTerrainFace face, SgtTerrainCompute.Output output)
        {
            if (OnSpawn != null)
            {
                OnSpawn();
            }

            transform.localScale = Prefab.transform.localScale * Random.Range(ScaleMin, ScaleMax);
            transform.SetParent(face.transform, true);

            var normal = Vector3.Lerp(output.Vertex, output.Normal, AlignToNormal);

            // Spawn on surface
            var twist = Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f);

            transform.localPosition = output.Vertex;
            transform.localRotation = Quaternion.FromToRotation(Vector3.up, normal) * twist;

            //transform.rotation   = Quaternion.FromToRotation(up, terrain.transform.TransformDirection(localPosition));

            sharedMaterial = terrain.SharedMaterial;

            if (Renderers != null && sharedMaterial != null)
            {
                for (var i = Renderers.Count - 1; i >= 0; i--)
                {
                    var renderer = Renderers[i];

                    if (renderer != null)
                    {
                        sharedMaterial.AddRenderer(renderer);
                    }
                }
            }
        }
Example #3
0
        private void AddObject(Surface surface, SgtTerrainFace face)
        {
            if (Prefabs != null && Prefabs.Count > 0)
            {
                var index  = Random.Range(0, Prefabs.Count);
                var prefab = Prefabs[index];

                if (prefab != null)
                {
                    var x      = Random.value;
                    var y      = Random.value;
                    var h      = face.CornerBR - face.CornerBL;
                    var v      = face.CornerTL - face.CornerBL;
                    var cube   = face.CornerBL + h * x + v * y;
                    var height = terrain.GetLocalHeight(cube);

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

                        clone.Prefab = prefab;

                        clone.Spawn(terrain, face, cube.normalized * height);

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

                        surface.Clones.Add(clone);
                    }
                }
            }
        }
Example #4
0
        public void Spawn(SgtTerrain terrain, SgtTerrainFace face, SgtVector3D localPoint)
        {
            if (OnSpawn != null)
            {
                OnSpawn();
            }

            transform.SetParent(face.transform, false);

            // Snap to surface
            localPoint = terrain.GetLocalPoint(localPoint);

            // Rotate up
            var up = Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f) * Vector3.up;

            // Spawn on surface
            var twist = Quaternion.Euler(0.0f, Random.Range(0.0f, 360.0f), 0.0f);

            transform.localPosition = (Vector3)localPoint;
            transform.localRotation = Quaternion.FromToRotation(up, terrain.transform.TransformDirection(transform.localPosition)) * twist;
            transform.localScale    = Prefab.transform.localScale * Random.Range(ScaleMin, ScaleMax);
            //transform.rotation   = Quaternion.FromToRotation(up, terrain.transform.TransformDirection(localPosition));

            if (AlignToNormal != 0.0f)
            {
                var localRight   = transform.right * AlignToNormal;
                var localForward = transform.forward * AlignToNormal;
                var localNormal  = terrain.GetLocalNormal(localPoint, new SgtVector3D(localRight), new SgtVector3D(localForward));

                transform.rotation = Quaternion.FromToRotation(up, (Vector3)localNormal) * twist;
            }
        }
 protected virtual void OnDestroy()
 {
     SgtTerrainFace.MarkForDestruction(NegativeX);
     SgtTerrainFace.MarkForDestruction(NegativeY);
     SgtTerrainFace.MarkForDestruction(NegativeZ);
     SgtTerrainFace.MarkForDestruction(PositiveX);
     SgtTerrainFace.MarkForDestruction(PositiveY);
     SgtTerrainFace.MarkForDestruction(PositiveZ);
 }
        public void ValidateFaces()
        {
            if (NegativeX == null)
            {
                NegativeX = CreateFace(CubemapFace.NegativeX, new Vector3(-1.0f, -1.0f, 1.0f), new Vector3(-1.0f, -1.0f, -1.0f), new Vector3(-1.0f, 1.0f, 1.0f), new Vector3(-1.0f, 1.0f, -1.0f));
            }
            if (NegativeY == null)
            {
                NegativeY = CreateFace(CubemapFace.NegativeY, new Vector3(1.0f, -1.0f, -1.0f), new Vector3(-1.0f, -1.0f, -1.0f), new Vector3(1.0f, -1.0f, 1.0f), new Vector3(-1.0f, -1.0f, 1.0f));
            }
            if (NegativeZ == null)
            {
                NegativeZ = CreateFace(CubemapFace.NegativeZ, new Vector3(-1.0f, -1.0f, -1.0f), new Vector3(1.0f, -1.0f, -1.0f), new Vector3(-1.0f, 1.0f, -1.0f), new Vector3(1.0f, 1.0f, -1.0f));
            }
            if (PositiveX == null)
            {
                PositiveX = CreateFace(CubemapFace.PositiveX, new Vector3(1.0f, -1.0f, -1.0f), new Vector3(1.0f, -1.0f, 1.0f), new Vector3(1.0f, 1.0f, -1.0f), new Vector3(1.0f, 1.0f, 1.0f));
            }
            if (PositiveY == null)
            {
                PositiveY = CreateFace(CubemapFace.PositiveY, new Vector3(1.0f, 1.0f, 1.0f), new Vector3(-1.0f, 1.0f, 1.0f), new Vector3(1.0f, 1.0f, -1.0f), new Vector3(-1.0f, 1.0f, -1.0f));
            }
            if (PositiveZ == null)
            {
                PositiveZ = CreateFace(CubemapFace.PositiveZ, new Vector3(1.0f, -1.0f, 1.0f), new Vector3(-1.0f, -1.0f, 1.0f), new Vector3(1.0f, 1.0f, 1.0f), new Vector3(-1.0f, 1.0f, 1.0f));
            }

            NegativeX.NeighbourL.Set(PositiveZ, 0, 0, 2, 1, 1, 3, 1);
            NegativeX.NeighbourR.Set(NegativeZ, 1, 1, 3, 0, 0, 2, 0);
            NegativeX.NeighbourB.Set(NegativeY, 2, 0, 1, 1, 3, 1, 5);
            NegativeX.NeighbourT.Set(PositiveY, 3, 2, 3, 1, 1, 3, 1);

            NegativeY.NeighbourL.Set(PositiveX, 0, 0, 2, 2, 0, 1, 2);
            NegativeY.NeighbourR.Set(NegativeX, 1, 1, 3, 2, 1, 0, 6);
            NegativeY.NeighbourB.Set(NegativeZ, 2, 0, 1, 2, 1, 0, 6);
            NegativeY.NeighbourT.Set(PositiveZ, 3, 2, 3, 2, 0, 1, 2);

            NegativeZ.NeighbourL.Set(NegativeX, 0, 0, 2, 1, 1, 3, 1);
            NegativeZ.NeighbourR.Set(PositiveX, 1, 1, 3, 0, 0, 2, 0);
            NegativeZ.NeighbourB.Set(NegativeY, 2, 0, 1, 2, 1, 0, 6);
            NegativeZ.NeighbourT.Set(PositiveY, 3, 2, 3, 3, 3, 2, 7);

            PositiveX.NeighbourL.Set(NegativeZ, 0, 0, 2, 1, 1, 3, 1);
            PositiveX.NeighbourR.Set(PositiveZ, 1, 1, 3, 0, 0, 2, 0);
            PositiveX.NeighbourB.Set(NegativeY, 2, 0, 1, 0, 0, 2, 0);
            PositiveX.NeighbourT.Set(PositiveY, 3, 2, 3, 0, 2, 0, 4);

            PositiveY.NeighbourL.Set(PositiveX, 0, 0, 2, 3, 3, 2, 7);
            PositiveY.NeighbourR.Set(NegativeX, 1, 1, 3, 3, 2, 3, 3);
            PositiveY.NeighbourB.Set(PositiveZ, 2, 0, 1, 3, 2, 3, 3);
            PositiveY.NeighbourT.Set(NegativeZ, 3, 2, 3, 3, 3, 2, 7);

            PositiveZ.NeighbourL.Set(PositiveX, 0, 0, 2, 1, 1, 3, 1);
            PositiveZ.NeighbourR.Set(NegativeX, 1, 1, 3, 0, 0, 2, 0);
            PositiveZ.NeighbourB.Set(NegativeY, 2, 0, 1, 3, 2, 3, 3);
            PositiveZ.NeighbourT.Set(PositiveY, 3, 2, 3, 2, 0, 1, 2);
        }
Example #7
0
 private void CalculateMaterial(SgtTerrainFace face, ref Material material)
 {
     if (face.Depth >= LevelMin && face.Depth <= LevelMax)
     {
         if (AllSides == true || face.Side == RequiredSide)
         {
             material = Material;
         }
     }
 }
        public static SgtTerrainFace MarkForDestruction(SgtTerrainFace face)
        {
            if (face != null)
            {
                face.Terrain = null;

                face.gameObject.SetActive(true);
            }

            return(null);
        }
        private void UpdateNeighbourData(SgtTerrainFace face, ref SgtTerrainNeighbour neighbour)
        {
            if (face.Split == true)
            {
                var childC = face.GetChild(neighbour.C);
                var childD = face.GetChild(neighbour.D);

                childC.BuildIndices();
                childD.BuildIndices();

                UpdateNeighbourData(childC, ref neighbour);
                UpdateNeighbourData(childD, ref neighbour);
            }
        }
        public void RunFaces(SgtTerrainFace face, CalculateFaceDelegate method)
        {
            if (face != null)
            {
                method(face);

                if (face.Split == true)
                {
                    RunFaces(face.ChildBL, method);
                    RunFaces(face.ChildBR, method);
                    RunFaces(face.ChildTL, method);
                    RunFaces(face.ChildTR, method);
                }
            }
        }
        private SgtTerrainFace CreateFace(CubemapFace side, Vector3 cornerBL, Vector3 cornerBR, Vector3 cornerTL, Vector3 cornerTR)
        {
            var face     = SgtTerrainFace.Create(side.ToString(), gameObject.layer, transform);
            var z        = Mathf.Atan(Mathf.Sqrt(0.5f)) * Mathf.Rad2Deg;
            var rotation = Quaternion.Euler(-z, 0.0f, 45.0f);

            face.Terrain  = this;
            face.Side     = side;
            face.Depth    = 0;
            face.CornerBL = new SgtVector3D(rotation * cornerBL);
            face.CornerBR = new SgtVector3D(rotation * cornerBR);
            face.CornerTL = new SgtVector3D(rotation * cornerTL);
            face.CornerTR = new SgtVector3D(rotation * cornerTR);

            return(face);
        }
Example #12
0
        private void DespawnFace(SgtTerrainFace face)
        {
            if (surfaces != null)
            {
                for (var i = surfaces.Count - 1; i >= 0; i--)
                {
                    var surface = surfaces[i];

                    if (surface.Face == face)
                    {
                        surface.Clear();

                        surfaces.RemoveAt(i);
                    }
                }
            }
        }
Example #13
0
        private Surface FindSurface(SgtTerrainFace face)
        {
            if (surfaces != null)
            {
                for (var i = surfaces.Count - 1; i >= 0; i--)
                {
                    var surface = surfaces[i];

                    if (surface.Face == face)
                    {
                        return(surface);
                    }
                }
            }

            return(null);
        }
Example #14
0
        private void SplitNow()
        {
            var cornerLL = (CornerBL + CornerTL) * 0.5f;
            var cornerRR = (CornerBR + CornerTR) * 0.5f;
            var cornerTT = (CornerTL + CornerTR) * 0.5f;
            var cornerBB = (CornerBL + CornerBR) * 0.5f;
            var cornerMM = (CornerBL + CornerTR) * 0.5f;
            var coordLL  = (CoordBL + CoordTL) * 0.5f;
            var coordRR  = (CoordBR + CoordTR) * 0.5f;
            var coordTT  = (CoordTL + CoordTR) * 0.5f;
            var coordBB  = (CoordBL + CoordBR) * 0.5f;
            var coordMM  = (CoordBL + CoordTR) * 0.5f;

            Split   = true;
            ChildBL = Create("ChildBL", CornerBL, cornerBB, cornerLL, cornerMM, CoordBL, coordBB, coordLL, coordMM);
            ChildBR = Create("ChildBR", cornerBB, CornerBR, cornerMM, cornerRR, coordBB, CoordBR, coordMM, coordRR);
            ChildTL = Create("ChildTL", cornerLL, cornerMM, CornerTL, cornerTT, coordLL, coordMM, CoordTL, coordTT);
            ChildTR = Create("ChildTR", cornerMM, cornerRR, cornerTT, CornerTR, coordMM, coordRR, coordTT, CoordTR);

            CopyVertiesToChildren();

            // Link children
            ChildBL.NeighbourR.Set(ChildBR, 1, 1, 3, 0, 0, 2, 0);
            ChildBL.NeighbourT.Set(ChildTL, 3, 2, 3, 2, 0, 1, 2);
            ChildBR.NeighbourL.Set(ChildBL, 0, 0, 2, 1, 1, 3, 1);
            ChildBR.NeighbourT.Set(ChildTR, 3, 2, 3, 2, 0, 1, 2);
            ChildTL.NeighbourR.Set(ChildTR, 1, 1, 3, 0, 0, 2, 0);
            ChildTL.NeighbourB.Set(ChildBL, 2, 0, 1, 3, 2, 3, 3);
            ChildTR.NeighbourL.Set(ChildTL, 0, 0, 2, 1, 1, 3, 1);
            ChildTR.NeighbourB.Set(ChildBR, 2, 0, 1, 3, 2, 3, 3);

            // Link to neighbours
            LinkNeighbours(ChildBL, ChildTL, ref ChildBL.NeighbourL, ref ChildTL.NeighbourL, ref NeighbourL);
            LinkNeighbours(ChildBR, ChildTR, ref ChildBR.NeighbourR, ref ChildTR.NeighbourR, ref NeighbourR);
            LinkNeighbours(ChildBL, ChildBR, ref ChildBL.NeighbourB, ref ChildBR.NeighbourB, ref NeighbourB);
            LinkNeighbours(ChildTL, ChildTR, ref ChildTL.NeighbourT, ref ChildTR.NeighbourT, ref NeighbourT);

            UpdateInvalidChildren();

            UpdateNeighbourData(NeighbourL.Face, ref NeighbourL);
            UpdateNeighbourData(NeighbourR.Face, ref NeighbourR);
            UpdateNeighbourData(NeighbourB.Face, ref NeighbourB);
            UpdateNeighbourData(NeighbourT.Face, ref NeighbourT);

            cachedMeshRenderer.enabled = false;
        }
Example #15
0
        private void CalculateMaterial(SgtTerrainFace face, ref Material material)
        {
            switch (face.Side)
            {
            case CubemapFace.NegativeX: material = NegativeX; break;

            case CubemapFace.NegativeY: material = NegativeY; break;

            case CubemapFace.NegativeZ: material = NegativeZ; break;

            case CubemapFace.PositiveX: material = PositiveX; break;

            case CubemapFace.PositiveY: material = PositiveY; break;

            case CubemapFace.PositiveZ: material = PositiveZ; break;
            }
        }
Example #16
0
        private SgtTerrainFace CreateFace(CubemapFace side, SgtVector3D cornerBL, SgtVector3D cornerBR, SgtVector3D cornerTL, SgtVector3D cornerTR)
        {
            var face = SgtTerrainFace.Create(side.ToString(), gameObject.layer, transform);

            face.Terrain  = this;
            face.Side     = side;
            face.Depth    = 0;
            face.CornerBL = cornerBL;
            face.CornerBR = cornerBR;
            face.CornerTL = cornerTL;
            face.CornerTR = cornerTR;
            face.CoordBL  = new SgtVector2D(0.0, 0.0);
            face.CoordBR  = new SgtVector2D(1.0, 0.0);
            face.CoordTL  = new SgtVector2D(0.0, 1.0);
            face.CoordTR  = new SgtVector2D(1.0, 1.0);

            return(face);
        }
        private void LinkNeighbours(SgtTerrainFace childA, SgtTerrainFace childB, ref SgtTerrainNeighbour childNeighbourA, ref SgtTerrainNeighbour childNeighbourB, ref SgtTerrainNeighbour neighbour)
        {
            if (neighbour.Face.Split == true)
            {
                var neighbourChildC = neighbour.Face.GetChild(neighbour.C);
                var neighbourChildD = neighbour.Face.GetChild(neighbour.D);

                neighbourChildC.SetNeighbour(neighbour.O, childA);
                neighbourChildD.SetNeighbour(neighbour.O, childB);

                childNeighbourA.Set(neighbourChildC, neighbour.I, neighbour.A, neighbour.B, neighbour.O, neighbour.C, neighbour.D, neighbour.Z);
                childNeighbourB.Set(neighbourChildD, neighbour.I, neighbour.A, neighbour.B, neighbour.O, neighbour.C, neighbour.D, neighbour.Z);
            }
            else
            {
                childNeighbourA.Set(neighbour.Face, neighbour.I, neighbour.A, neighbour.B, neighbour.O, neighbour.C, neighbour.D, neighbour.Z);
                childNeighbourB.Set(neighbour.Face, neighbour.I, neighbour.A, neighbour.B, neighbour.O, neighbour.C, neighbour.D, neighbour.Z);
            }
        }
Example #18
0
        private void CopyVertiesToChildren(SgtTerrainFace child, int verts, int minX, int maxX, int minY, int maxY, int offX, int offY)
        {
            for (var y = minY; y < maxY; y++)
            {
                for (var x = minX; x < maxX; x++)
                {
                    var x2  = (x - offX) * 2;
                    var y2  = (y - offY) * 2;
                    var src = x + y * verts;
                    var dst = x2 + y2 * verts;

                    child.vertices[dst] = vertices[src];
                    child.coords1[dst]  = coords1[src];
                    child.coords2[dst]  = coords2[src];
                    //child.normals[dst] = normals[src];
                    //child.tangents[dst] = tangents[src];
                }
            }
        }
 public void SetNeighbour(int index, SgtTerrainFace face)
 {
     if (index == 0)
     {
         NeighbourL.Face = face;
     }
     else if (index == 1)
     {
         NeighbourR.Face = face;
     }
     else if (index == 2)
     {
         NeighbourB.Face = face;
     }
     else
     {
         NeighbourT.Face = face;
     }
 }
        private void UnsplitNow()
        {
            if (ChildBL.Split == true)
            {
                ChildBL.UnsplitNow();
            }
            if (ChildBR.Split == true)
            {
                ChildBR.UnsplitNow();
            }
            if (ChildTL.Split == true)
            {
                ChildTL.UnsplitNow();
            }
            if (ChildTR.Split == true)
            {
                ChildTR.UnsplitNow();
            }

            if (Terrain.OnDespawnFace != null)
            {
                Terrain.OnDespawnFace.Invoke(ChildBL);
                Terrain.OnDespawnFace.Invoke(ChildBR);
                Terrain.OnDespawnFace.Invoke(ChildTL);
                Terrain.OnDespawnFace.Invoke(ChildTR);
            }

            Split   = false;
            ChildBL = Pool(ChildBL);
            ChildBR = Pool(ChildBR);
            ChildTL = Pool(ChildTL);
            ChildTR = Pool(ChildTR);

            BuildIndices();

            UnlinkNeighbours(ref NeighbourL);
            UnlinkNeighbours(ref NeighbourR);
            UnlinkNeighbours(ref NeighbourB);
            UnlinkNeighbours(ref NeighbourT);

            cachedMeshRenderer.enabled = true;
        }
        public static SgtTerrainFace Pool(SgtTerrainFace face)
        {
            if (face != null)
            {
                face.Terrain = null;

                if (face.Split == true)
                {
                    face.Split   = false;
                    face.ChildBL = Pool(face.ChildBL);
                    face.ChildBR = Pool(face.ChildBR);
                    face.ChildTL = Pool(face.ChildTL);
                    face.ChildTR = Pool(face.ChildTR);
                }

                SgtComponentPool <SgtTerrainFace> .Add(face);
            }

            return(null);
        }
Example #22
0
        private void SpawnFace(SgtTerrainFace face)
        {
            var surface = FindSurface(face);

            if (surface != null)
            {
                surface.Clear();
            }
            else
            {
                if (surfaces == null)
                {
                    surfaces = new List <Surface>();
                }

                surface = new Surface();

                surface.Face = face;

                surfaces.Add(surface);
            }

            SgtHelper.BeginRandomSeed(face.GetHashCode());
            {
                if (SpawnProbability > 0.0f && Depth == face.Depth)
                {
                    for (var i = 0; i < SpawnCountMax; i++)
                    {
                        if (Random.value <= SpawnProbability)
                        {
                            AddObject(surface, face);
                        }
                    }
                }
            }
            SgtHelper.EndRandomSeed();
        }