Esempio n. 1
0
    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);
    }
Esempio n. 2
0
    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;
    }
Esempio n. 3
0
    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();
        }