public GPUSubdivData Next() { var newTriangles = new int[triangles.Length * 4]; var newTriArray = new Triangle_t[triBuffer.count * 4]; var newEdges = new List <Edge_t>(); var eoffset = VertexBuffer.count; for (int i = 0, n = triangles.Length; i < n; i += 3) { int iv0 = triangles[i], iv1 = triangles[i + 1], iv2 = triangles[i + 2]; var e0 = new Edge_t() { v0 = iv0, v1 = iv1 }; var e1 = new Edge_t() { v0 = iv1, v1 = iv2 }; var e2 = new Edge_t() { v0 = iv2, v1 = iv0 }; int ie0 = edges.IndexOf(e0) + eoffset, ie1 = edges.IndexOf(e1) + eoffset, ie2 = edges.IndexOf(e2) + eoffset; int it00 = i * 4, it01 = it00 + 1, it02 = it01 + 1; int it10 = it00 + 3, it11 = it10 + 1, it12 = it11 + 1; int it20 = it10 + 3, it21 = it20 + 1, it22 = it21 + 1; int it30 = it20 + 3, it31 = it30 + 1, it32 = it31 + 1; newTriangles[it00] = iv0; newTriangles[it01] = ie0; newTriangles[it02] = ie2; newTriangles[it10] = ie0; newTriangles[it11] = iv1; newTriangles[it12] = ie1; newTriangles[it20] = ie0; newTriangles[it21] = ie1; newTriangles[it22] = ie2; newTriangles[it30] = ie2; newTriangles[it31] = ie1; newTriangles[it32] = iv2; int it = (i / 3) * 4; // AddTriangle newTriArray[it] = AddTriangle(newEdges, newTriangles[it00], newTriangles[it01], newTriangles[it02]); newTriArray[it + 1] = AddTriangle(newEdges, newTriangles[it10], newTriangles[it11], newTriangles[it12]); newTriArray[it + 2] = AddTriangle(newEdges, newTriangles[it20], newTriangles[it21], newTriangles[it22]); newTriArray[it + 3] = AddTriangle(newEdges, newTriangles[it30], newTriangles[it31], newTriangles[it32]); } var neBuffer = new ComputeBuffer(newEdges.Count, Marshal.SizeOf(typeof(Edge_t))); neBuffer.SetData(newEdges.ToArray()); var ntriBuffer = new ComputeBuffer(newTriArray.Length, Marshal.SizeOf(typeof(Triangle_t))); ntriBuffer.SetData(newTriArray); var next = new GPUSubdivData(subdivBuffer, neBuffer, ntriBuffer, newTriangles, newEdges); ReleaseBuffer(vertBuffer); vertBuffer = null; ReleaseBuffer(edgeBuffer); edgeBuffer = null; ReleaseBuffer(triBuffer); triBuffer = null; subdivBuffer = null; // ref to NULL to use it in next GPUSubdivData return(next); }
// subdivCompute : SubdivisionSurface.compute public static Mesh Subdivide(ComputeShader subdivCompute, Mesh mesh, int details = 1, bool weld = false) { var kernel = new Kernel(subdivCompute, kKernelKey); var data = new GPUSubdivData(mesh); for (int i = 0; i < details; i++) { subdivCompute.SetBuffer(kernel.Index, kVertexBufferKey, data.VertexBuffer); subdivCompute.SetBuffer(kernel.Index, kEdgeBufferKey, data.EdgeBuffer); subdivCompute.SetBuffer(kernel.Index, kTriangleBufferKey, data.TriangleBuffer); subdivCompute.SetBuffer(kernel.Index, kSubdivBufferKey, data.SubdivBuffer); subdivCompute.SetInt(kVertexCountKey, data.VertexBuffer.count); subdivCompute.SetInt(kEdgeCountKey, data.EdgeBuffer.count); subdivCompute.SetInt(kTriangleCountKey, data.TriangleBuffer.count); subdivCompute.SetInt(kSubdivCountKey, data.SubdivBuffer.count); subdivCompute.Dispatch(kernel.Index, data.SubdivBuffer.count / (int)kernel.ThreadX + 1, (int)kernel.ThreadY, (int)kernel.ThreadZ); if (i != details - 1) { data = data.Next(); } } mesh = data.Build(weld); data.Dispose(); return(mesh); }