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); } }
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); } } } }
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); } } } }
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); }
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); }
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); } } } }
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); }
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; }
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; } }
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); } }
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); }
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(); }