protected override JobHandle OnUpdate(JobHandle inputDeps) { //throw new System.NotImplementedException(); NativeArray <Entity> entities = eq.ToEntityArray(Allocator.TempJob); if (entities.Length == 0) { return(inputDeps); } World.Active.EntityManager.AddComponent(entities[0], typeof(shouldFilterMesh)); World.Active.EntityManager.RemoveComponent(entities[0], typeof(shouldGenerateMesh)); int SizeX = World.Active.EntityManager.GetComponentData <ChunkStatus>(entities[0]).SizeX; int SizeY = World.Active.EntityManager.GetComponentData <ChunkStatus>(entities[0]).SizeY; int SizeZ = World.Active.EntityManager.GetComponentData <ChunkStatus>(entities[0]).SizeZ; NativeArray <float3> cornerMemoryPool = new NativeArray <float3>(SizeX * SizeY * SizeZ * 8, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <float> gridMemoryPool = new NativeArray <float>(SizeX * SizeY * SizeZ * 8, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <float3> vertMemoryPool = new NativeArray <float3>(SizeX * SizeY * SizeZ * 12, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <int> edgeTable = new NativeArray <int>(256, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <int> triTable = new NativeArray <int>(4096, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); edgeTable.CopyFrom(MCTables.CubeEdgeFlags); triTable.CopyFrom(MCTables.triTable); MarchingCubesJob MCJob = new MarchingCubesJob { SizeX = SizeX, SizeY = SizeY, GridSize = 1f, edgeTable = edgeTable, triTable = triTable, vertListSlicePool = vertMemoryPool, cornerSlicePool = cornerMemoryPool, gridSlicePool = gridMemoryPool, voxelData = GetBufferFromEntity <VoxelData>(false), unfilteredVerticesData = GetBufferFromEntity <UnfilteredVerticesArray>(false), entities = entities, entity = entities[0] }; JobHandle MCHandle = MCJob.Schedule((SizeX - 1) * (SizeY - 1) * (SizeZ - 1), 1, inputDeps); return(MCHandle); }
void RequestUpdateChunk(Chunk chunk) { // Determine if chunk should be at maximum detail if (chunk.WithinRadius(viewer.position, viewDistance)) { // is chunk already at max subdivision if (chunk.lod > 0) { if (chunk.children == null) { chunk.Split(); chunk.mesh.Clear(); } foreach (Chunk child in chunk.children) { RequestUpdateChunk(child); } return; } } else { chunk.Merge(); } // Only render if any changes are made to the chunk if (!chunk.dirty) { return; } int numVertsPerAxis = resolution + 1; int numVerts = numVertsPerAxis * numVertsPerAxis * numVertsPerAxis; int numVoxels = resolution * resolution * resolution; Vector3 mapSize = (Vector3)numberOfChunks * (chunkSize << levelsOfDetail); // Only used for "edge solidification". float vertSpacing = (float)chunk.size / resolution; Vector3 center = chunk.position; var vertexBuffer = new NativeArray <Vector3>(numVerts, Allocator.TempJob); var densityBuffer = new NativeArray <float>(numVerts, Allocator.TempJob); var triangleBuffer = new NativeQueue <Triangle>(Allocator.TempJob); // Generate vertex density values JobHandle densityJobHandle = densityGenerator.Generate(vertexBuffer, densityBuffer, numVertsPerAxis, chunk.size, vertSpacing, mapSize, center, densityOffset); var marchJob = new MarchingCubesJob(vertexBuffer, densityBuffer, triangleBuffer.AsParallelWriter(), resolution, surfaceLevel); JobHandle marchJobHandle = marchJob.Schedule(numVoxels, 128, densityJobHandle); jobQueue.Enqueue(new JobData(chunk, marchJobHandle, triangleBuffer)); chunk.dirty = false; }
public static void GenerateMarchingCubesWithJob(Voxel[,,] voxels, Vector3Int cellSize, Vector3 chunkScale, bool triangleIndexing, List <Vector3> vertices, List <int> triangles, List <Color> colors) { NativeArray <Vector3> nativeVertices = new NativeArray <Vector3>(15 * cellSize.x * cellSize.y * cellSize.z, Allocator.TempJob); NativeArray <int> nativeTriangles = new NativeArray <int>(15 * cellSize.x * cellSize.y * cellSize.z, Allocator.TempJob); NativeArray <Color> nativeColors = new NativeArray <Color>(15 * cellSize.x * cellSize.y * cellSize.z, Allocator.TempJob); NativeCounter counter = new NativeCounter(Allocator.TempJob); NativeArray <Voxel> nativeVoxels = new NativeArray <Voxel>(voxels.Length, Allocator.TempJob); nativeVoxels.ManagedToNative(voxels); MarchingCubesJob marchingCubesJob = new MarchingCubesJob { vertices = nativeVertices, counter = counter.ToConcurrent(), voxels = nativeVoxels, colors = nativeColors, cellSize = cellSize, gridSize = cellSize + Vector3Int.one, chunkScale = chunkScale, }; JobHandle marchingCubesJobHandle = marchingCubesJob.Schedule(voxels.Length, 32); marchingCubesJobHandle.Complete(); if (counter.Count > 0) { int verticeSize = counter.Count * 3; int triangleSize = verticeSize; if (triangleIndexing) { verticeSize = TriangleIndexingForJob(nativeVertices, nativeTriangles, nativeColors, verticeSize); } else { AddTriangleIndexForNoIndexing triangleJob = new AddTriangleIndexForNoIndexing { triangles = nativeTriangles }; JobHandle triangleJobHandle = triangleJob.Schedule(verticeSize, 32); triangleJobHandle.Complete(); } NativeSlice <Vector3> nativeSliceVertices = new NativeSlice <Vector3>(nativeVertices, 0, verticeSize); NativeSlice <Color> nativeSliceColors = new NativeSlice <Color>(nativeColors, 0, verticeSize); NativeSlice <int> nativeSliceTriangles = new NativeSlice <int>(nativeTriangles, 0, triangleSize); colors.Clear(); vertices.Clear(); triangles.Clear(); vertices.NativeAddRange(nativeSliceVertices); triangles.NativeAddRange(nativeSliceTriangles); colors.NativeAddRange(nativeSliceColors); } counter.Dispose(); nativeVertices.Dispose(); nativeTriangles.Dispose(); nativeVoxels.Dispose(); nativeColors.Dispose(); }
public void computeIsoSurface(float isoValue) { if (curVertices.IsCreated) { curVertices.Dispose(); } if (curNormals.IsCreated) { curNormals.Dispose(); } if (curTriangles.IsCreated) { curTriangles.Dispose(); } //CountVertexPerVoxelJob NativeArray <uint2> vertPerCellIn = new NativeArray <uint2>(totalSize, Allocator.TempJob); NativeArray <uint2> vertPerCell = new NativeArray <uint2>(totalSize, Allocator.TempJob); NativeArray <uint> compactedVoxel = new NativeArray <uint>(totalSize, Allocator.TempJob); var countVJob = new CountVertexPerVoxelJob() { densV = values, nbTriTable = nbTriTable, triTable = triTable, vertPerCell = vertPerCellIn, gridSize = gridSize, totalVoxel = totalSize, isoValue = isoValue }; var countVJobHandle = countVJob.Schedule(totalSize, 128); countVJobHandle.Complete(); //exclusivescan => compute the total number of vertices uint2 lastElem = vertPerCellIn[totalSize - 1]; float timerEsc = Time.realtimeSinceStartup; var escanJob = new ExclusiveScanTrivialJob() { vertPerCell = vertPerCellIn, result = vertPerCell, totalVoxel = totalSize }; var escanJobJobHandle = escanJob.Schedule(); escanJobJobHandle.Complete(); uint2 lastScanElem = vertPerCell[totalSize - 1]; uint newTotalVoxels = lastElem.y + lastScanElem.y; uint totalVerts = lastElem.x + lastScanElem.x; if (totalVerts <= 0) { Debug.LogWarning("Empty iso-surface"); vertPerCell.Dispose(); compactedVoxel.Dispose(); return; } curVertices = new NativeArray <float3>((int)totalVerts, Allocator.Persistent); curNormals = new NativeArray <float3>((int)totalVerts, Allocator.Persistent); //Double the triangles to have both faces curTriangles = new NativeArray <int>((int)totalVerts * 2, Allocator.Persistent); //compactvoxels var compactJob = new CompactVoxelJob() { vertPerCell = vertPerCell, compVoxel = compactedVoxel, gridSize = gridSize, totalVoxel = totalSize, lastElem = lastElem.y }; var compactJobHandle = compactJob.Schedule(totalSize, 128); compactJobHandle.Complete(); //MC var MCJob = new MarchingCubesJob() { vertices = curVertices, compVoxel = compactedVoxel, vertPerCell = vertPerCell, densV = values, nbTriTable = nbTriTable, triTable = triTable, oriGrid = originGrid, dx = dx, gridSize = gridSize, isoValue = isoValue, totalVerts = totalVerts }; var MCJobHandle = MCJob.Schedule((int)newTotalVoxels, 128); MCJobHandle.Complete(); //Normals var NormJob = new ComputeNormalsJob() { normals = curNormals, vertices = curVertices, densV = values, oriGrid = originGrid, dx = dx, gridSize = gridSize }; var NormJobHandle = NormJob.Schedule((int)totalVerts, 128); NormJobHandle.Complete(); for (int i = 0; i < totalVerts - 3; i += 3) { curTriangles[i] = i; curTriangles[i + 1] = i + 1; curTriangles[i + 2] = i + 2; } //Double the triangles to have both faces for (int i = (int)totalVerts; i < totalVerts * 2 - 3; i += 3) { curTriangles[i] = i - (int)totalVerts; curTriangles[i + 2] = i + 1 - (int)totalVerts; //Invert triangles here curTriangles[i + 1] = i + 2 - (int)totalVerts; } vertPerCellIn.Dispose(); vertPerCell.Dispose(); compactedVoxel.Dispose(); }