private static byte GetPatchTypeSize(PatchType patchType) { switch (patchType) { case PatchType.I4: return(32); case PatchType.I8: return(64); default: throw new CompilerException("unknown patch type: " + patchType.ToString()); } }
static Mesh BuildOceanPatch(PatchType pt, float vertDensity) { ArrayList verts = new ArrayList(); ArrayList indices = new ArrayList(); // stick a bunch of verts into a 1m x 1m patch (scaling happens later) float dx = 1f / vertDensity; ////////////////////////////////////////////////////////////////////////////////// // verts // see comments within PatchType for diagrams of each patch mesh // skirt widths on left, right, bottom and top (in order) float skirtXminus = 0f, skirtXplus = 0f; float skirtZminus = 0f, skirtZplus = 0f; // set the patch size if (pt == PatchType.Fat) { skirtXminus = skirtXplus = skirtZminus = skirtZplus = 1f; } else if (pt == PatchType.FatX || pt == PatchType.FatXOuter) { skirtXplus = 1f; } else if (pt == PatchType.FatXZ || pt == PatchType.FatXZOuter) { skirtXplus = skirtZplus = 1f; } else if (pt == PatchType.FatXSlimZ) { skirtXplus = 1f; skirtZplus = -1f; } else if (pt == PatchType.SlimX) { skirtXplus = -1f; } else if (pt == PatchType.SlimXZ) { skirtXplus = skirtZplus = -1f; } else if (pt == PatchType.SlimXFatZ) { skirtXplus = -1f; skirtZplus = 1f; } float sideLength_verts_x = 1f + vertDensity + skirtXminus + skirtXplus; float sideLength_verts_z = 1f + vertDensity + skirtZminus + skirtZplus; float start_x = -0.5f - skirtXminus * dx; float start_z = -0.5f - skirtZminus * dx; float end_x = 0.5f + skirtXplus * dx; float end_z = 0.5f + skirtZplus * dx; for (float j = 0; j < sideLength_verts_z; j++) { // interpolate z across patch float z = Mathf.Lerp(start_z, end_z, j / (sideLength_verts_z - 1f)); // push outermost edge out to horizon if (pt == PatchType.FatXZOuter && j == sideLength_verts_z - 1f) { z *= 100f; } for (float i = 0; i < sideLength_verts_x; i++) { // interpolate x across patch float x = Mathf.Lerp(start_x, end_x, i / (sideLength_verts_x - 1f)); // push outermost edge out to horizon if (i == sideLength_verts_x - 1f && (pt == PatchType.FatXOuter || pt == PatchType.FatXZOuter)) { x *= 100f; } // could store something in y, although keep in mind this is a shared mesh that is shared across multiple lods verts.Add(new Vector3(x, 0f, z)); } } ////////////////////////////////////////////////////////////////////////////////// // indices int sideLength_squares_x = (int)sideLength_verts_x - 1; int sideLength_squares_z = (int)sideLength_verts_z - 1; for (int j = 0; j < sideLength_squares_z; j++) { for (int i = 0; i < sideLength_squares_x; i++) { bool flipEdge = false; if (i % 2 == 1) { flipEdge = !flipEdge; } if (j % 2 == 1) { flipEdge = !flipEdge; } int i0 = i + j * (sideLength_squares_x + 1); int i1 = i0 + 1; int i2 = i0 + (sideLength_squares_x + 1); int i3 = i2 + 1; if (!flipEdge) { // tri 1 indices.Add(i3); indices.Add(i1); indices.Add(i0); // tri 2 indices.Add(i0); indices.Add(i2); indices.Add(i3); } else { // tri 1 indices.Add(i3); indices.Add(i1); indices.Add(i2); // tri 2 indices.Add(i0); indices.Add(i2); indices.Add(i1); } } } ////////////////////////////////////////////////////////////////////////////////// // create mesh Mesh mesh = new Mesh(); if (verts != null && verts.Count > 0) { Vector3[] arrV = new Vector3[verts.Count]; verts.CopyTo(arrV); int[] arrI = new int[indices.Count]; indices.CopyTo(arrI); mesh.SetIndices(null, MeshTopology.Triangles, 0); mesh.vertices = arrV; mesh.normals = null; mesh.SetIndices(arrI, MeshTopology.Triangles, 0); // recalculate bounds. add a little allowance for snapping. in the chunk renderer script, the bounds will be expanded further // to allow for horizontal displacement mesh.RecalculateBounds(); Bounds bounds = mesh.bounds; bounds.extents = new Vector3(bounds.extents.x + dx, 100f, bounds.extents.z + dx); mesh.bounds = bounds; mesh.name = pt.ToString(); } return(mesh); }
Mesh BuildWaterPatch(PatchType pt, float baseVertDensity) { ArrayList verts = new ArrayList(); ArrayList indices = new ArrayList(); float dx = 1f / baseVertDensity; float skirtXminus = 0f, skirtXplus = 0f; float skirtZminus = 0f, skirtZplus = 0f; switch (pt) { case PatchType.Extra: skirtXminus = skirtXplus = skirtZminus = skirtZplus = 1f; break; case PatchType.ExtraX: skirtXplus = 1f; break; case PatchType.ExtraXOuter: skirtXplus = 1f; break; case PatchType.ExtraXZ: skirtXplus = skirtZplus = 1f; break; case PatchType.ExtraXZOuter: skirtXplus = skirtZplus = 1f; break; case PatchType.ExtraXLessZ: skirtXplus = 1f; skirtZplus = -1f; break; case PatchType.LessX: skirtXplus = -1f; break; case PatchType.LessXZ: skirtXplus = skirtZplus = -1f; break; case PatchType.LessXExtraZ: skirtXplus = -1f; skirtZplus = 1f; break; default: break; } float sideLength_verts_x = 1f + baseVertDensity + skirtXminus + skirtXplus; float sideLength_verts_z = 1f + baseVertDensity + skirtZminus + skirtZplus; float start_x = -0.5f - skirtXminus * dx; float start_z = -0.5f - skirtZminus * dx; float end_x = 0.5f + skirtXplus * dx; float end_z = 0.5f + skirtZplus * dx; for (float j = 0; j < sideLength_verts_z; j++) { float z = Mathf.Lerp(start_z, end_z, j / (sideLength_verts_z - 1f)); if (pt == PatchType.ExtraXZOuter && j == sideLength_verts_z - 1f) { z *= 100f; } for (float i = 0; i < sideLength_verts_x; i++) { float x = Mathf.Lerp(start_x, end_x, i / (sideLength_verts_x - 1f)); if (i == sideLength_verts_x - 1f && (pt == PatchType.ExtraXOuter || pt == PatchType.ExtraXZOuter)) { x *= 100f; } verts.Add(new Vector3(x, 0f, z)); } } int sideLength_squares_x = (int)sideLength_verts_x - 1; int sideLength_squares_z = (int)sideLength_verts_z - 1; for (int j = 0; j < sideLength_squares_z; j++) { for (int i = 0; i < sideLength_squares_x; i++) { bool flipEdge = false; if (i % 2 == 1) { flipEdge = !flipEdge; } if (j % 2 == 1) { flipEdge = !flipEdge; } int i0 = i + j * (sideLength_squares_x + 1); int i1 = i0 + 1; int i2 = i0 + (sideLength_squares_x + 1); int i3 = i2 + 1; if (!flipEdge) { indices.Add(i3);//tri 1 indices.Add(i1); indices.Add(i0); indices.Add(i0);//tri 2 indices.Add(i2); indices.Add(i3); } else { indices.Add(i3);//tri 1 indices.Add(i1); indices.Add(i2); indices.Add(i0);//tri 2 indices.Add(i2); indices.Add(i1); } } } Mesh mesh = new Mesh(); if (verts != null && verts.Count > 0) { Vector3[] arrV = new Vector3[verts.Count]; verts.CopyTo(arrV); int[] arrI = new int[indices.Count]; indices.CopyTo(arrI); mesh.SetIndices(null, MeshTopology.Triangles, 0); mesh.vertices = arrV; mesh.normals = null; mesh.SetIndices(arrI, MeshTopology.Triangles, 0); mesh.RecalculateBounds(); Bounds bounds = mesh.bounds; bounds.extents = new Vector3(bounds.extents.x + dx, 100f, bounds.extents.z + dx); mesh.bounds = bounds; mesh.name = pt.ToString(); } return(mesh); }