/// <summary> /// Create metadata from a quadnode /// </summary> /// <param name="node"></param> private void GenerateChunkdata(QuadNode <ChunkData> node, Zone2 region) { ChunkData data = new ChunkData(); data.bounds = null; data.breakpoint = maxResolutionAt * Mathf.Pow(2, maxDepth - node.depth); data.faceRegion = region; node.value = data; }
/// <summary> /// Scale region by a constant /// </summary> /// <param name="f"></param> /// <returns></returns> public Zone2 scale(float f) { Zone2 b = new Zone2(); b.a = this.a * f; b.b = this.b * f; b.c = this.c * f; b.d = this.d * f; return(b); }
/// <summary> /// Subdivide this range into 4 quadrants /// </summary> /// <param name="NE">North east zone</param> /// <param name="NW">North west zone</param> /// <param name="SE">South east zone</param> /// <param name="SW">South west zone</param> public void QuadSubdivide(out Zone2 NE, out Zone2 NW, out Zone2 SE, out Zone2 SW) { //Create 4 subdivided ranges Vector2 topl = this.a; Vector2 topr = this.b; Vector2 btnl = this.d; Vector2 btnr = this.c; Vector2 tc = Vector3.Lerp(topl, topr, 0.5f); Vector2 lm = Vector3.Lerp(topl, btnl, 0.5f); Vector2 rm = Vector3.Lerp(topr, btnr, 0.5f); Vector2 mc = Vector3.Lerp(lm, rm, 0.5f); Vector2 bc = Vector3.Lerp(btnl, btnr, 0.5f); NW = new Zone2(topl, tc, mc, lm); NE = new Zone2(tc, topr, rm, mc); SW = new Zone2(lm, mc, bc, btnl); SE = new Zone2(mc, rm, btnr, bc); }
/// <summary> /// Make mesh /// </summary> /// <param name="topLeft"></param> /// <param name="topRight"></param> /// <param name="bottomLeft"></param> /// <param name="bottomRight"></param> /// <param name="radius"></param> /// <returns></returns> public override MeshData Make(Vector3 topLeft, Vector3 topRight, Vector3 bottomLeft, Vector3 bottomRight, Zone2 uvRange, float radius) { //Initial Calculations int width = resolution + 2; int size = width * width; int skirtVertices = useSkirts ? (width * 4) : 0; //4 + resolution * 4; Vector3[] v = new Vector3[size + skirtVertices]; Vector3[] n = new Vector3[size + skirtVertices]; Vector2[] u = new Vector2[size + skirtVertices]; int[] t = new int[ ((2 * (width - 1) * (width - 1)) * 3) + (useSkirts ? (6 * (skirtVertices - 1)) : 0) ]; //Initial Representivitive Normals and UVs Vector3 topNormal = (topLeft - bottomLeft).normalized; Vector3 rightNormal = (topRight - topLeft).normalized; Vector2 uvTopLeft = uvRange.a; Vector2 uvTopRight = uvRange.b; Vector2 uvBottomLeft = uvRange.d; Vector2 uvBottomRight = uvRange.c; float step = 1.0f / (resolution + 1); //Create Planar Faces int tidx = 0; for (int i = 0; i < width; i++) { for (int j = 0; j < width; j++) { int idx = i + width * j; //Create Vertice on Unit Cube Vector3 rawPosition = Vector3.Lerp( Vector3.Lerp(topLeft, topRight, i * step), Vector3.Lerp(bottomLeft, bottomRight, i * step), j * step ); //Transform Vertice to Unit Sphere Vector3 pos = IMeshService.Spherify(rawPosition); //Sample Noise to Get Altitude float alt = GetAltitude(rawPosition, radius); v [idx] = pos * alt; //Create UV for Texturing (optional) Vector2 uv = Vector2.Lerp( Vector2.Lerp(uvTopLeft, uvTopRight, i * step), Vector2.Lerp(uvBottomLeft, uvBottomRight, i * step), j * step ); u[idx] = uv; //Create Normals //TODO take terrain shape into account n[idx] = GetNormal(rawPosition, radius); //Create Triangles if (i > 0 && j > 0) { t[tidx++] = ((i - 1) + width * (j - 1)); t[tidx++] = ((i) + width * (j - 1)); t[tidx++] = (idx); t[tidx++] = ((i - 1) + width * (j - 1)); t[tidx++] = (idx); t[tidx++] = ((i - 1) + width * (j)); } } } //Create Skirts if (useSkirts) { for (int i = 0; i < width; i++) { //Top int idx = i; Vector3 p = v [idx]; Vector2 uv = u [idx]; Vector3 norm = topNormal; v [size + i] = p * skirtSize; n [size + i] = norm; u [size + i] = uv; if (i != 0) { t [tidx++] = idx; t [tidx++] = idx - 1; t [tidx++] = size + (i - 1); t [tidx++] = idx; t [tidx++] = size + (i - 1); t [tidx++] = size + i; } //Bottom idx = i + width * (width - 1); p = v [idx]; uv = u [idx]; norm = -topNormal; v [size + width + i] = p * skirtSize; n [size + width + i] = norm; u [size + width + i] = uv; if (i != 0) { t [tidx++] = idx - 1; t [tidx++] = idx; t [tidx++] = size + (width + i); t [tidx++] = idx - 1; t [tidx++] = size + (width + i); t [tidx++] = size + (width + i - 1); } //Left idx = 0 + width * (i); p = v [idx]; uv = u [idx]; norm = -rightNormal; v [size + 2 * width + i] = p * skirtSize; n [size + 2 * width + i] = norm; u [size + 2 * width + i] = uv; if (i != 0) { t [tidx++] = width * (i - 1); t [tidx++] = idx; t [tidx++] = size + (2 * width + i); t [tidx++] = width * (i - 1); t [tidx++] = size + (2 * width + i); t [tidx++] = size + (2 * width + i - 1); } //Right idx = (width - 1) + width * i; p = v [idx]; uv = u [idx]; norm = rightNormal; v [size + 3 * width + i] = p * skirtSize; n [size + 3 * width + i] = norm; u [size + 3 * width + i] = uv; if (i != 0) { t [tidx++] = idx; t [tidx++] = (width - 1) + width * (i - 1); t [tidx++] = size + (3 * width + i - 1); t [tidx++] = idx; t [tidx++] = size + (3 * width + i - 1); t [tidx++] = size + (3 * width + i); } } } MeshData m = new MeshData(); m.name = "Surface_r" + resolution; m.vertices = v; m.uvs = u; m.triangles = t; m.normals = n; return(m); }
public abstract MeshData Make( Vector3 topLeft, Vector3 topRight, Vector3 bottomLeft, Vector3 bottomRight, Zone2 uvRange, float radius );
public override MeshData Make(Vector3 topLeft, Vector3 topRight, Vector3 bottomLeft, Vector3 bottomRight, Zone2 uvRange, float radius) { //Replace resolution with one matching out shader's threads //Resolution is number of vertices across any axis int resolution = (resolutionMultipler > 1 ? resolutionMultipler : 1) * numthreads.xy; //Ensure multiple of xy //Initialize values int width = resolution; int size = width * width; int num_vertices = size; int num_normals = size; int num_uvs = size; int num_triangles = ((width - 1) * (width - 1)) * 6; //Create Buffers Vector3[] v = new Vector3[num_vertices]; Vector3[] n = new Vector3[num_normals]; Vector2[] u = new Vector2[num_uvs]; int[] t = new int[num_triangles]; ComputeBuffer vb = new ComputeBuffer(v.Length, 3 * sizeof(float)); //3 floats * 4 bytes / float ComputeBuffer nb = new ComputeBuffer(n.Length, 3 * sizeof(float)); ComputeBuffer ub = new ComputeBuffer(u.Length, 2 * sizeof(float)); ComputeBuffer tb = new ComputeBuffer(t.Length, sizeof(int)); //Transfer data to GPU shader.SetInt(arrayWidthParameter, width); shader.SetFloat(radiusParameter, radius); shader.SetVector(topLeftParameter, topLeft); shader.SetVector(topRightParameter, topRight); shader.SetVector(bottomLeftParameter, bottomLeft); shader.SetVector(bottomRightParameter, bottomRight); if (useSkirts) { } shader.SetBuffer(handle, vertexArray, vb); shader.SetBuffer(handle, normalArray, nb); shader.SetBuffer(handle, uvArray, ub); shader.SetBuffer(handle, triangleArray, tb); //Dispatch the shader shader.Dispatch(handle, width / numthreads.x, width / numthreads.y, 1); if (useSkirts) { //shader.Dispatch(skirtHandle, width / numthreads.x, 1, 1); } //Retrieve data from GPU vb.GetData(v); nb.GetData(n); ub.GetData(u); tb.GetData(t); //Dispose buffers to be cleaned up by GC vb.Dispose(); nb.Dispose(); ub.Dispose(); tb.Dispose(); //Create mesh MeshData m = new MeshData(); m.name = "Surface_r" + resolution; m.vertices = v; m.uvs = u; m.triangles = t; m.normals = n; return(m); }
public override MeshData Make(Vector3 topLeft, Vector3 topRight, Vector3 bottomLeft, Vector3 bottomRight, Zone2 uvRange, float radius) { int width = subdivisions + 2; int size = width * width; Vector3[] v = new Vector3[size]; Vector3[] n = new Vector3[size]; Vector2[] u = new Vector2[size]; List <int> t = new List <int>(); Vector2 uvTopLeft = uvRange.a; Vector2 uvTopRight = uvRange.b; Vector2 uvBottomLeft = uvRange.d; Vector2 uvBottomRight = uvRange.c; float step = 1.0f / (subdivisions + 1); for (int i = 0; i < width; i++) { for (int j = 0; j < width; j++) { int idx = i + width * j; //Create Vertice Vector3 rawPosition = Vector3.Lerp( Vector3.Lerp(topLeft, topRight, i * step), Vector3.Lerp(bottomLeft, bottomRight, i * step), j * step ); Vector3 pos = IMeshService.Spherify(rawPosition); v[idx] = pos * GetAltitude(pos, radius);; //Create uv Vector2 uv = Vector2.Lerp( Vector2.Lerp(uvTopLeft, uvTopRight, i * step), Vector2.Lerp(uvBottomLeft, uvBottomRight, i * step), j * step ); u[idx] = uv; //Create normals n[idx] = GetNormal(pos, radius); //Create triangles if (i > 0 && j > 0) { t.Add((i - 1) + width * (j - 1)); t.Add((i) + width * (j - 1)); t.Add(idx); t.Add((i - 1) + width * (j - 1)); t.Add(idx); t.Add((i - 1) + width * (j)); } } } MeshData m = new MeshData(); m.name = "Surface_r" + subdivisions; m.vertices = v; m.uvs = u; m.triangles = t.ToArray(); m.normals = n; return(m); }