public static void Split(int verticesStep, HideFlags hideFlags) { if (positions.Count > 0) { var stepCount = positions.Count / verticesStep; var stepsPerMesh = 65000 / verticesStep; var verticesPerMesh = stepsPerMesh * verticesStep; var meshCount = (positions.Count + verticesPerMesh - 1) / verticesPerMesh; for (var i = 0; i < meshCount; i++) { var stepA = i * stepsPerMesh; var stepB = Mathf.Min(stepA + stepsPerMesh, stepCount); var stepC = stepB - stepA; var vertA = stepA * verticesStep; var vertC = stepC * verticesStep; var mesh = SgtObjectPool <Mesh> .Pop() ?? new Mesh(); meshes.Add(mesh); mesh.Clear(false); mesh.hideFlags = hideFlags; mesh.vertices = GetRange(positions, vertA, vertC); if (colors.Count > 0) { mesh.colors = GetRange(colors, vertA, vertC); } if (color32s.Count > 0) { mesh.colors32 = GetRange(color32s, vertA, vertC); } if (coords1.Count > 0) { mesh.uv = GetRange(coords1, vertA, vertC); } if (coords2.Count > 0) { mesh.uv2 = GetRange(coords2, vertA, vertC); } if (normals.Count > 0) { mesh.normals = GetRange(normals, vertA, vertC); } if (tangents.Count > 0) { mesh.tangents = GetRange(tangents, vertA, vertC); } } } }
public static Mesh CreateTempMesh(string meshName) { var mesh = SgtObjectPool <Mesh> .Pop() ?? new Mesh(); mesh.name = meshName; #if UNITY_EDITOR mesh.hideFlags = HideFlags.DontSave; #endif return(mesh); }
public Mesh GetColliderMesh() { if (colliderMesh == null) { colliderMesh = SgtObjectPool <Mesh> .Pop() ?? new Mesh(); #if UNITY_EDITOR colliderMesh.hideFlags = HideFlags.DontSave; #endif colliderMesh.name = "Terrain (Capped)"; } return(colliderMesh); }
public Mesh GetMesh() { if (mesh == null) { mesh = SgtObjectPool <Mesh> .Pop() ?? new Mesh(); #if UNITY_EDITOR mesh.hideFlags = HideFlags.DontSave; #endif mesh.name = "Terrain"; } if (meshFilter == null) { meshFilter = GetComponent <MeshFilter>(); } meshFilter.sharedMesh = mesh; return(mesh); }
public void RebuildPatch(SgtPatch patch) { if (Resolution > 0) { var resAdd1 = Resolution + 1; var resAdd2 = Resolution + 2; var resAdd3 = Resolution + 3; var resRecip = SgtHelper.Reciprocal(Resolution); var mainVerts = resAdd1 * resAdd1; var skirtVerts = resAdd1 * 4; var mainIndices = Resolution * Resolution * 6; var skirtIndices = Resolution * 24; var mesh = patch.Mesh; var vertex = default(int); var vertex2 = default(int); var index = default(int); if (positions == null || positions.Length != mainVerts + skirtVerts) { positions = new Vector3[mainVerts + skirtVerts]; } if (coords1 == null || coords1.Length != mainVerts + skirtVerts) { coords1 = new Vector2[mainVerts + skirtVerts]; } if (coords2 == null || coords2.Length != mainVerts + skirtVerts) { coords2 = new Vector2[mainVerts + skirtVerts]; } if (normals == null || normals.Length != mainVerts + skirtVerts) { normals = new Vector3[mainVerts + skirtVerts]; } if (tangents == null || tangents.Length != mainVerts + skirtVerts) { tangents = new Vector4[mainVerts + skirtVerts]; } if (quadPoints == null || quadPoints.Length != resAdd3 * resAdd3) { quadPoints = new Vector3[resAdd3 * resAdd3]; } if (quadNormals == null || quadNormals.Length != resAdd2 * resAdd2) { quadNormals = new Vector3[resAdd2 * resAdd2]; } if (quadTangents == null || quadTangents.Length != resAdd2 * resAdd2) { quadTangents = new Vector3[resAdd2 * resAdd2]; } // Go through all vertices, but extend the borders by one for (var y = -1; y < resAdd2; y++) { for (var x = -1; x < resAdd2; x++) { var u = x * resRecip; var v = y * resRecip; var pointB = Lerp3(patch.PointBL, patch.PointBR, u); var pointT = Lerp3(patch.PointTL, patch.PointTR, u); var point = GetSurfacePositionLocal(Lerp3(pointB, pointT, v)); index = x + 1 + (y + 1) * resAdd3; quadPoints[index] = point; // Is this a main vertex? if (x >= 0 && x < resAdd1 && y >= 0 && y < resAdd1) { var coordB = Lerp2(patch.CoordBL, patch.CoordBR, u); var coordT = Lerp2(patch.CoordTL, patch.CoordTR, u); var coord1 = Lerp2(coordB, coordT, v); var coord2 = new Vector2(u, v); var center = (patch.PointBL + patch.PointBR + patch.PointTL + patch.PointTR) * 0.25f; if (OnCalculateCoord1 != null) { OnCalculateCoord1(point, center, ref coord1); } if (OnCalculateCoord2 != null) { OnCalculateCoord2(point, center, ref coord2); } vertex = x + y * resAdd1; positions[vertex] = point; coords1[vertex] = coord1; coords2[vertex] = coord2; } } } // Quad normals & tangents for (var y = 0; y < resAdd2; y++) { for (var x = 0; x < resAdd2; x++) { var bl = x + y * resAdd3; var br = x + 1 + y * resAdd3; var tl = x + (y + 1) * resAdd3; var tr = x + 1 + (y + 1) * resAdd3; var b = quadPoints[bl] - quadPoints[br]; var t = quadPoints[tl] - quadPoints[tr]; var l = quadPoints[bl] - quadPoints[tl]; var r = quadPoints[br] - quadPoints[tr]; var h = (b + t).normalized; var v = (l + r).normalized; var i = x + y * resAdd2; quadNormals[i] = Vector3.Cross(h, v); quadTangents[i] = v; } } // Normals & Tangents for (var y = 0; y < resAdd1; y++) { for (var x = 0; x < resAdd1; x++) { var bl = x + y * resAdd2; var br = x + 1 + y * resAdd2; var tl = x + (y + 1) * resAdd2; var tr = x + 1 + (y + 1) * resAdd2; var n = quadNormals[bl] + quadNormals[br] + quadNormals[tl] + quadNormals[tr]; var t = quadTangents[bl] + quadTangents[br] + quadTangents[tl] + quadTangents[tr]; var i = x + y * resAdd1; normals[i] = n.normalized; //normals[i] = positions[i].normalized; tangents[i] = SgtHelper.NewVector4(t.normalized, 1.0f); } } // Skirt vertices var scale = 1.0f - SgtHelper.Divide(SkirtThickness * Mathf.Pow(0.5f, patch.Depth), 1.0f); for (var i = 0; i < resAdd1; i++) { // Bottom vertex = mainVerts + i; vertex2 = i; positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2]; // Top vertex = mainVerts + i + resAdd1; vertex2 = resAdd1 * Resolution + i; positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2]; // Left vertex = mainVerts + i + resAdd1 + resAdd1; vertex2 = resAdd1 * i; positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2]; // Right vertex = mainVerts + i + resAdd1 + resAdd1 + resAdd1; vertex2 = resAdd1 * i + Resolution; positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2]; } // Indices if (indices == null || indices.Length != mainIndices + skirtIndices) { indices = new int[mainIndices + skirtIndices]; // Main for (var y = 0; y < Resolution; y++) { for (var x = 0; x < Resolution; x++) { index = (x + y * Resolution) * 6; vertex = x + y * resAdd1; indices[index + 0] = vertex; indices[index + 1] = vertex + 1; indices[index + 2] = vertex + resAdd1; indices[index + 3] = vertex + resAdd1 + 1; indices[index + 4] = vertex + resAdd1; indices[index + 5] = vertex + 1; } } // Skirt for (var i = 0; i < Resolution; i++) { // Bottom index = mainIndices + (Resolution * 0 + i) * 6; vertex = mainVerts + i; vertex2 = i; indices[index + 0] = vertex; indices[index + 1] = vertex + 1; indices[index + 2] = vertex2; indices[index + 3] = vertex2 + 1; indices[index + 4] = vertex2; indices[index + 5] = vertex + 1; // Top index = mainIndices + (Resolution * 1 + i) * 6; vertex = mainVerts + i + resAdd1; vertex2 = Resolution * resAdd1 + i; indices[index + 0] = vertex2; indices[index + 1] = vertex2 + 1; indices[index + 2] = vertex; indices[index + 3] = vertex + 1; indices[index + 4] = vertex; indices[index + 5] = vertex2 + 1; // Left index = mainIndices + (Resolution * 2 + i) * 6; vertex = mainVerts + i + resAdd1 + resAdd1; vertex2 = i * resAdd1; indices[index + 0] = vertex; indices[index + 1] = vertex2; indices[index + 2] = vertex + 1; indices[index + 3] = vertex2 + resAdd1; indices[index + 4] = vertex + 1; indices[index + 5] = vertex2; // Right index = mainIndices + (Resolution * 3 + i) * 6; vertex = mainVerts + i + resAdd1 + resAdd1 + resAdd1; vertex2 = i * resAdd1 + Resolution; indices[index + 0] = vertex2; indices[index + 1] = vertex; indices[index + 2] = vertex2 + resAdd1; indices[index + 3] = vertex + 1; indices[index + 4] = vertex2 + resAdd1; indices[index + 5] = vertex; } } if (mesh != null) { mesh.Clear(); } else { mesh = patch.Mesh = SgtObjectPool <Mesh> .Pop() ?? new Mesh(); mesh.name = "Patch"; mesh.hideFlags = HideFlags.DontSave; } mesh.vertices = positions; mesh.uv = coords1; mesh.uv2 = coords2; mesh.normals = normals; mesh.tangents = tangents; mesh.triangles = indices; mesh.RecalculateBounds(); patch.MeshCenter = mesh.bounds.center; } }
private void Build(SgtTerrain terrain, Vector3 bestPoint) { if (meshCollider == null) { var gameObject = new GameObject("Plane"); #if UNITY_EDITOR gameObject.hideFlags = HideFlags.DontSave; #endif meshCollider = gameObject.AddComponent <MeshCollider>(); } if (mesh == null) { mesh = SgtObjectPool <Mesh> .Pop() ?? new Mesh(); #if UNITY_EDITOR mesh.hideFlags = HideFlags.DontSave; #endif mesh.name = "Plane"; } var sideE = Detail; var sideP = Detail + 1; var vertexCount = sideP * sideP; var indexCount = sideE * sideE * 6; var rotation = Quaternion.Inverse(terrain.transform.rotation) * Quaternion.LookRotation(bestPoint); var distance = bestPoint.magnitude; var uniformScale = SgtHelper.UniformScale(terrain.transform.lossyScale); var size = Size * SgtHelper.Reciprocal(uniformScale); var step = (size * 2.0f) / Detail; if (positions == null || positions.Length != vertexCount) { positions = new Vector3[vertexCount]; } for (var y = 0; y <= Detail; y++) { for (var x = 0; x <= Detail; x++) { var index = x + y * sideP; var point = rotation * new Vector3(x * step - size, y * step - size, distance); positions[index] = terrain.GetLocalPoint(point); } } // Regen indices? if (indices == null || indices.Length != indexCount) { indices = new int[indexCount]; for (var y = 0; y < sideE; y++) { for (var x = 0; x < sideE; x++) { var index = (x + y * sideE) * 6; var vertex = x + y * sideP; indices[index + 0] = vertex; indices[index + 1] = vertex + 1; indices[index + 2] = vertex + sideP; indices[index + 3] = vertex + sideP + 1; indices[index + 4] = vertex + sideP; indices[index + 5] = vertex + 1; } } mesh.Clear(); } mesh.vertices = positions; mesh.triangles = indices; meshCollider.sharedMesh = mesh; meshCollider.transform.SetParent(terrain.transform, false); }
public static void GenerateMesh(SgtPatch patch) { var terrain = patch.Terrain; if (terrain.Resolution > 0) { var positions = terrain.Positions; var coords1 = terrain.Coords1; var coords2 = terrain.Coords2; var normals = terrain.Normals; var tangents = terrain.Tangents; var quadPoints = terrain.QuadPoints; var quadNormals = terrain.QuadNormals; var quadTangents = terrain.QuadTangents; var indices = terrain.Indices; var res = terrain.Resolution; var resAdd1 = res + 1; var resAdd2 = res + 2; var resAdd3 = res + 3; var resRecip = SgtHelper.Reciprocal(res); var mainVerts = resAdd1 * resAdd1; var skirtVerts = resAdd1 * 4; var mainIndices = res * res * 6; var skirtIndices = res * 24; var vertex = default(int); var vertex2 = default(int); var index = default(int); if (positions.Length != mainVerts + skirtVerts) { terrain.Positions = positions = new Vector3[mainVerts + skirtVerts]; } if (coords1.Length != mainVerts + skirtVerts) { terrain.Coords1 = coords1 = new Vector2[mainVerts + skirtVerts]; } if (coords2.Length != mainVerts + skirtVerts) { terrain.Coords2 = coords2 = new Vector2[mainVerts + skirtVerts]; } if (normals.Length != mainVerts + skirtVerts) { terrain.Normals = normals = new Vector3[mainVerts + skirtVerts]; } if (tangents.Length != mainVerts + skirtVerts) { terrain.Tangents = tangents = new Vector4[mainVerts + skirtVerts]; } if (quadPoints.Length != resAdd3 * resAdd3) { terrain.QuadPoints = quadPoints = new Vector3[resAdd3 * resAdd3]; } if (quadNormals.Length != resAdd2 * resAdd2) { terrain.QuadNormals = quadNormals = new Vector3[resAdd2 * resAdd2]; } if (quadTangents.Length != resAdd2 * resAdd2) { terrain.QuadTangents = quadTangents = new Vector3[resAdd2 * resAdd2]; } // Go through all vertices, but extend the borders by one for (var y = -1; y < resAdd2; y++) { for (var x = -1; x < resAdd2; x++) { var u = x * resRecip; var v = y * resRecip; var pointB = Lerp3(patch.PointBL, patch.PointBR, u); var pointT = Lerp3(patch.PointTL, patch.PointTR, u); var point = Lerp3(pointB, pointT, v).normalized; point *= terrain.GetHeight(point); index = x + 1 + (y + 1) * resAdd3; quadPoints[index] = point; // Is this a main vertex? if (x >= 0 && x < resAdd1 && y >= 0 && y < resAdd1) { var coordB = Lerp2(patch.CoordBL, patch.CoordBR, u); var coordT = Lerp2(patch.CoordTL, patch.CoordTR, u); var coord1 = Lerp2(coordB, coordT, v); vertex = x + y * resAdd1; positions[vertex] = point; coords1[vertex] = coord1; coords2[vertex] = new Vector2(u, v); } } } // Quad normals & tangents for (var y = 0; y < resAdd2; y++) { for (var x = 0; x < resAdd2; x++) { var bl = x + y * resAdd3; var br = x + 1 + y * resAdd3; var tl = x + (y + 1) * resAdd3; var tr = x + 1 + (y + 1) * resAdd3; var b = quadPoints[bl] - quadPoints[br]; var t = quadPoints[tl] - quadPoints[tr]; var l = quadPoints[bl] - quadPoints[tl]; var r = quadPoints[br] - quadPoints[tr]; var h = (b + t).normalized; var v = (l + r).normalized; var i = x + y * resAdd2; quadNormals[i] = Vector3.Cross(h, v); quadTangents[i] = v; } } // Normals & Tangents for (var y = 0; y < resAdd1; y++) { for (var x = 0; x < resAdd1; x++) { var bl = x + y * resAdd2; var br = x + 1 + y * resAdd2; var tl = x + (y + 1) * resAdd2; var tr = x + 1 + (y + 1) * resAdd2; var n = quadNormals[bl] + quadNormals[br] + quadNormals[tl] + quadNormals[tr]; var t = quadTangents[bl] + quadTangents[br] + quadTangents[tl] + quadTangents[tr]; var i = x + y * resAdd1; normals[i] = n.normalized; //normals[i] = positions[i].normalized; tangents[i] = SgtHelper.NewVector4(t.normalized, 1.0f); } } // Skirt vertices var scale = 1.0f - SgtHelper.Divide(terrain.SkirtThickness * Mathf.Pow(0.5f, patch.Depth), 1.0f); for (var i = 0; i < resAdd1; i++) { // Bottom vertex = mainVerts + i; vertex2 = i; positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2]; // Top vertex = mainVerts + i + resAdd1; vertex2 = resAdd1 * res + i; positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2]; // Left vertex = mainVerts + i + resAdd1 + resAdd1; vertex2 = resAdd1 * i; positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2]; // Right vertex = mainVerts + i + resAdd1 + resAdd1 + resAdd1; vertex2 = resAdd1 * i + res; positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2]; } // Indices if (indices.Length != mainIndices + skirtIndices) { terrain.Indices = indices = new int[mainIndices + skirtIndices]; // Main for (var y = 0; y < res; y++) { for (var x = 0; x < res; x++) { index = (x + y * res) * 6; vertex = x + y * resAdd1; indices[index + 0] = vertex; indices[index + 1] = vertex + 1; indices[index + 2] = vertex + resAdd1; indices[index + 3] = vertex + resAdd1 + 1; indices[index + 4] = vertex + resAdd1; indices[index + 5] = vertex + 1; } } // Skirt for (var i = 0; i < res; i++) { // Bottom index = mainIndices + (res * 0 + i) * 6; vertex = mainVerts + i; vertex2 = i; indices[index + 0] = vertex; indices[index + 1] = vertex + 1; indices[index + 2] = vertex2; indices[index + 3] = vertex2 + 1; indices[index + 4] = vertex2; indices[index + 5] = vertex + 1; // Top index = mainIndices + (res * 1 + i) * 6; vertex = mainVerts + i + resAdd1; vertex2 = res * resAdd1 + i; indices[index + 0] = vertex2; indices[index + 1] = vertex2 + 1; indices[index + 2] = vertex; indices[index + 3] = vertex + 1; indices[index + 4] = vertex; indices[index + 5] = vertex2 + 1; // Left index = mainIndices + (res * 2 + i) * 6; vertex = mainVerts + i + resAdd1 + resAdd1; vertex2 = i * resAdd1; indices[index + 0] = vertex; indices[index + 1] = vertex2; indices[index + 2] = vertex + 1; indices[index + 3] = vertex2 + resAdd1; indices[index + 4] = vertex + 1; indices[index + 5] = vertex2; // Right index = mainIndices + (res * 3 + i) * 6; vertex = mainVerts + i + resAdd1 + resAdd1 + resAdd1; vertex2 = i * resAdd1 + res; indices[index + 0] = vertex2; indices[index + 1] = vertex; indices[index + 2] = vertex2 + resAdd1; indices[index + 3] = vertex + 1; indices[index + 4] = vertex2 + resAdd1; indices[index + 5] = vertex; } } if (patch.Mesh != null) { patch.Mesh.Clear(); } else { patch.Mesh = SgtObjectPool <Mesh> .Pop() ?? new Mesh(); patch.Mesh.hideFlags = HideFlags.DontSave; } patch.Mesh.vertices = positions; patch.Mesh.uv = coords1; patch.Mesh.uv2 = coords2; patch.Mesh.normals = normals; patch.Mesh.tangents = tangents; patch.Mesh.triangles = indices; patch.Mesh.RecalculateBounds(); patch.MeshCenter = patch.Mesh.bounds.center; } }