Example #1
0
        public void Length()
        {
            var array = new NativeArray3D <int>(length, width, height, Unity.Collections.Allocator.Temp);

            Assert.AreEqual(length * width * height, array.Length);
            array.Dispose();
        }
Example #2
0
 public static JobHandle Schedule(NativeArray3D <GridNode> grid, ulong flags, int3 min, int3 max)
 {
     return(new SetFlagsInNodeRange
     {
         Flags = flags,
         Grid = grid,
         LocalGridMin = min,
         LocalGridMax = max,
     }.Schedule());
 }
Example #3
0
        public void Dispose()
        {
            var array = new NativeArray3D <int>(length, width, height, Unity.Collections.Allocator.Temp);

            Assert.IsTrue(array.IsCreated);
            array.Dispose();

            Assert.Throws <System.ObjectDisposedException>(() =>
            {
                array[0, 0, 0] = 10;
            });

            Assert.False(array.IsCreated);

            Assert.Throws <System.ObjectDisposedException>(() =>
            {
                array.Dispose();
            });
            Assert.Throws <System.ObjectDisposedException>(() =>
            {
                array.Dispose(default).Complete();
Example #4
0
            public int3 GetNearestNodeIndices(NativeArray3D <GridNode> array, Vector3 position, GridViewData viewData)
            {
                var gridX = ToGridDistance(position.x, viewData.BoxSize);
                var gridY = ToGridDistance(position.y, viewData.BoxSize);
                var gridZ = ToGridDistance(position.z, viewData.BoxSize);

                if (gridX < 0)
                {
                    gridX = 0;
                }
                if (gridY < 0)
                {
                    gridY = 0;
                }
                if (gridZ < 0)
                {
                    gridZ = 0;
                }
                var xLen = array.GetLength(0);
                var yLen = array.GetLength(1);
                var zLen = array.GetLength(2);

                if (gridX > xLen)
                {
                    gridX = xLen;
                }
                if (gridY > yLen)
                {
                    gridY = yLen;
                }
                if (gridZ > zLen)
                {
                    gridZ = zLen;
                }
                return(new int3(gridX, gridY, gridZ));
            }
            public static unsafe (PathStatus PathStatus, List <GridNode> NodePath, List <Vector3> VectorPath) Complete(BurstAStarPathFinder pathFinder, ref NativeArray3D <GridNode> grid,
                                                                                                                       INativeArrayProducer <NativeAreaDefinition> areas, int queryId, GridPoint start, GridPoint end, ulong allowedFlags, float4x4 localToWorld)
            {
                using (var nativeAreas = areas.ToNativeArray(Allocator.TempJob))
                    using (var nativePath = new NativeList <GridNode>(grid.Length, Allocator.TempJob))
                        using (var nativeVectorPath = new NativeList <Vector3>(grid.Length, Allocator.TempJob))
                            using (var nativePriorityQueue = new NativePriorityQueue(grid.Length / 8, Allocator.TempJob))
                            {
                                var result = new PathFindingJobResult();
                                var job    = new PathFindingJob
                                {
                                    QueryId         = queryId,
                                    AllowedFlags    = allowedFlags,
                                    StartPoint      = start,
                                    EndPoint        = end,
                                    OpenQueue       = nativePriorityQueue,
                                    Grid            = grid,
                                    Areas           = nativeAreas,
                                    Path            = nativePath,
                                    MaxPoints       = 5000,
                                    WorldPath       = nativeVectorPath,
                                    TransformMatrix = localToWorld,
                                    ResultPtr       = &result
                                };

                                pathFinder.Stopwatch.Restart();
                                job.Run();
                                pathFinder.Stopwatch.Stop();

                                var path      = job.Path.ToArray().ToList();
                                var worldPath = nativeVectorPath.ToArray().ToList();
                                return(result.PathStatus, path, worldPath);
                            }
            }
        /// <summary>
        /// Voxelizes the mesh into the specified grid. The mesh is scaled to fit the grid (minus padding).
        /// Returns the voxelization job containing its job handle. The voxelization job must be disposed once the job has completed.
        /// </summary>
        /// <param name="vertices"></param>
        /// <param name="normals"></param>
        /// <param name="grid"></param>
        /// <param name="material"></param>
        /// <param name="properties"></param>
        /// <returns>The voxelization job containing its job handle. The voxelization job must be disposed once the job has completed.</returns>
        public static VoxelizationJob Voxelize <TIndexer>(NativeArray <float3> vertices, NativeArray <float3> normals, NativeArray3D <Voxel, TIndexer> grid, int material, VoxelizationProperties properties)
            where TIndexer : struct, IIndexer
        {
            var triangles = vertices.Length / 3;

            var width  = grid.Length(0);
            var height = grid.Length(1);
            var depth  = grid.Length(2);

            var scaledVertices = new NativeArray <float3>(vertices.Length, Allocator.TempJob);

            var scaleJobHandle = new VoxelizerMeshScaleJob
            {
                inVertices  = vertices,
                outVertices = scaledVertices,
                width       = grid.Length(0),
                height      = grid.Length(1),
                depth       = grid.Length(2),
                padding     = properties.padding
            }.Schedule();

            var binsStream = new NativeStream(triangles, Allocator.TempJob);

            //Bin triangles
            var binJobHandle = new VoxelizerBinJob
            {
                vertices = scaledVertices,
                width    = width,
                height   = height,
                depth    = depth,
                stream   = binsStream.AsWriter()
            }.Schedule(triangles, properties.parallelForBatchCount, scaleJobHandle);

            var binColsX = new NativeList <VoxelizerCollectBinsJob.Column>(Allocator.TempJob);
            var binColsY = new NativeList <VoxelizerCollectBinsJob.Column>(Allocator.TempJob);
            var binColsZ = new NativeList <VoxelizerCollectBinsJob.Column>(Allocator.TempJob);

            var binsX = new NativeList <int>(Allocator.TempJob);
            var binsY = new NativeList <int>(Allocator.TempJob);
            var binsZ = new NativeList <int>(Allocator.TempJob);

            //Collect bins and reorder
            var collectBinsJobHandle = new VoxelizerCollectBinsJob
            {
                stream      = binsStream.AsReader(),
                streams     = triangles,
                width       = width,
                height      = height,
                depth       = depth,
                binColumnsX = binColsX,
                binsX       = binsX,
                binColumnsY = binColsY,
                binsY       = binsY,
                binColumnsZ = binColsZ,
                binsZ       = binsZ
            }.Schedule(binJobHandle);

            var intersectionsStreamX = new NativeStream(height * depth, Allocator.TempJob);
            var intersectionsStreamY = new NativeStream(width * depth, Allocator.TempJob);
            var intersectionsStreamZ = new NativeStream(width * height, Allocator.TempJob);

            //Intersect X axis
            var intersectXJobHandle = new VoxelizerMeshIntersectionJob
            {
                vertices      = scaledVertices,
                normals       = normals,
                columns       = binColsX.AsDeferredJobArray(),
                bins          = binsX,
                width         = width,
                height        = height,
                depth         = depth,
                axis          = 0,
                stream        = intersectionsStreamX.AsWriter(),
                smoothNormals = properties.smoothNormals
            }.Schedule(binColsX, properties.parallelForBatchCount, collectBinsJobHandle);

            //Intersect Y axis
            var intersectYJobHandle = new VoxelizerMeshIntersectionJob
            {
                vertices      = scaledVertices,
                normals       = normals,
                columns       = binColsY.AsDeferredJobArray(),
                bins          = binsY,
                width         = width,
                height        = height,
                depth         = depth,
                axis          = 1,
                stream        = intersectionsStreamY.AsWriter(),
                smoothNormals = properties.smoothNormals
            }.Schedule(binColsY, properties.parallelForBatchCount, collectBinsJobHandle);

            //Intersect Z axis
            var intersectZJobHandle = new VoxelizerMeshIntersectionJob
            {
                vertices      = scaledVertices,
                normals       = normals,
                columns       = binColsZ.AsDeferredJobArray(),
                bins          = binsZ,
                width         = width,
                height        = height,
                depth         = depth,
                axis          = 2,
                stream        = intersectionsStreamZ.AsWriter(),
                smoothNormals = properties.smoothNormals
            }.Schedule(binColsZ, properties.parallelForBatchCount, collectBinsJobHandle);

            var intersectionColsX = new NativeList <VoxelizerCollectBinsJob.Column>(height * depth, Allocator.TempJob);
            var intersectionColsY = new NativeList <VoxelizerCollectBinsJob.Column>(width * depth, Allocator.TempJob);
            var intersectionColsZ = new NativeList <VoxelizerCollectBinsJob.Column>(width * height, Allocator.TempJob);

            var intersectionsX = new NativeList <float4>(Allocator.TempJob);
            var intersectionsY = new NativeList <float4>(Allocator.TempJob);
            var intersectionsZ = new NativeList <float4>(Allocator.TempJob);

            //Collect X axis
            var collectXJobHandle = new VoxelizerCollectIntersectionsJob
            {
                stream        = intersectionsStreamX.AsReader(),
                binColumns    = binColsX,
                columns       = intersectionColsX,
                intersections = intersectionsX
            }.Schedule(intersectXJobHandle);

            //Collect Y axis
            var collectYJobHandle = new VoxelizerCollectIntersectionsJob
            {
                stream        = intersectionsStreamY.AsReader(),
                binColumns    = binColsY,
                columns       = intersectionColsY,
                intersections = intersectionsY
            }.Schedule(intersectYJobHandle);

            //Collect Z axis
            var collectZJobHandle = new VoxelizerCollectIntersectionsJob
            {
                stream        = intersectionsStreamZ.AsReader(),
                binColumns    = binColsZ,
                columns       = intersectionColsZ,
                intersections = intersectionsZ
            }.Schedule(intersectZJobHandle);

            //Voxelizing using only the axis intersections can result in holes.
            //The voxelizer job will detect those holes and put them in this list
            //so they can be fixed later
            var holes = new NativeList <VoxelizerFillJob <TIndexer> .Hole>(Allocator.TempJob);

            //Fill in materials and normals where possible
            var voxelizerFillJobHandle = new VoxelizerFillJob <TIndexer>
            {
                colsX          = intersectionColsX,
                colsY          = intersectionColsY,
                colsZ          = intersectionColsZ,
                intersectionsX = intersectionsX,
                intersectionsY = intersectionsY,
                intersectionsZ = intersectionsZ,
                material       = material,
                grid           = grid,
                holes          = holes,
                angleThreshold = properties.angleThreshold,
                snapThreshold  = properties.snapThreshold
            }.Schedule(JobHandle.CombineDependencies(collectXJobHandle, collectYJobHandle, collectZJobHandle));

            //If there are holes in the voxel data, i.e. missing intersections and normals,
            //then they are patched up in a second pass
            var patchesQueue = new NativeQueue <VoxelizerFindPatchesJob <TIndexer> .PatchedHole>(Allocator.TempJob);

            //Find all hole patches in parallel
            var findPatchesJobHandle = new VoxelizerFindPatchesJob <TIndexer>
            {
                vertices       = scaledVertices,
                normals        = normals,
                holes          = holes.AsDeferredJobArray(),
                angleThreshold = properties.angleThreshold,
                smoothNormals  = properties.smoothNormals,
                queue          = patchesQueue.AsParallelWriter()
            }.Schedule(holes, properties.parallelForBatchCount, voxelizerFillJobHandle);

            //Apply the hole patches to the grid
            var applyPatchesJobHandle = new VoxelizerApplyPatchesJob <TIndexer>
            {
                queue = patchesQueue,
                grid  = grid
            }.Schedule(findPatchesJobHandle);

            return(new VoxelizationJob(applyPatchesJobHandle,
                                       scaledVertices,
                                       binsStream,
                                       binColsX, binColsY, binColsZ,
                                       binsX, binsY, binsZ,
                                       intersectionsStreamX, intersectionsStreamY, intersectionsStreamZ,
                                       intersectionColsX, intersectionColsY, intersectionColsZ,
                                       intersectionsX, intersectionsY, intersectionsZ,
                                       holes,
                                       patchesQueue));
        }
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        if (!_voxelWorldSystem.IsInitialized)
        {
            return(inputDeps);
        }

        if (_isInitialized)
        {
            return(inputDeps);
        }

        var xzSize = _voxelWorldSystem.VoxelWorld.ChunkSize * _voxelWorldSystem.VoxelWorld.MaxChunks;

        VoxelsMap = new NativeArray3D <Entity>(xzSize.x, _voxelWorldSystem.VoxelWorld.ChunkSize.y, xzSize.z, Allocator.Persistent);

        _isInitialized = true;

        var worldPosition = GetComponentDataFromEntity <Translation>(true)[_voxelWorldSystem.VoxelWorld.Entity].Value;
        var World         = _voxelWorldSystem.VoxelWorld;
        var et            = _chunkGroup.ToEntityArray(Allocator.Persistent);
        var tmp           = _chunkGroup.ToComponentDataArray <VoxelChunk>(Allocator.Persistent);
        var pos           = _chunkGroup.ToComponentDataArray <Translation>(Allocator.Persistent);

        for (int i = 0; i < tmp.Length; i++)
        {
            var chunkEntity = et[i];
            var voxelChunk  = tmp[i];
            var translation = pos[i];

            if (voxelChunk.NeedsUpdate == 1)
            {
                int3  offset = World.MaxChunks * World.ChunkSize / 2;
                float x      = worldPosition.x + voxelChunk.X * World.ChunkSize.x - offset.x;
                float z      = worldPosition.z + voxelChunk.Z * World.ChunkSize.z - offset.z;
                float y      = worldPosition.y;
                translation.Value = new Vector3(x, y, z);

                EntityManager.SetComponentData(chunkEntity, translation);

                voxelChunk.NeedsUpdate   = 0;
                voxelChunk.IsInitialized = 1;

                EntityManager.SetComponentData(chunkEntity, voxelChunk);
            }

            if (voxelChunk.IsInitialized == 1 && voxelChunk.IsPopulated == 0)
            {
                var terrainHeight = GenerateTerrainHeight(voxelChunk, translation, _voxelWorldSystem.VoxelWorld.ChunkSize);

                for (int x = 0; x < World.ChunkSize.x; x++)
                {
                    for (int y = 0; y < World.ChunkSize.y; y++)
                    {
                        for (int z = 0; z < World.ChunkSize.z; z++)
                        {
                            Vector3 position = new float3(translation.Value.x + x, translation.Value.y + y, translation.Value.z + z);
                            Entity  voxelEntity;

                            switch (terrainHeight[x, y, z])
                            {
                            case 1:
                                voxelEntity = EntityManager.Instantiate(voxelChunk.VoxelPrefab1);
                                break;

                            case 2:
                                voxelEntity = EntityManager.Instantiate(voxelChunk.VoxelPrefab2);
                                break;

                            default:
                                continue;
                            }

                            EntityManager.SetComponentData(voxelEntity, new Voxel
                            {
                                Entity           = voxelEntity,
                                VoxelChunkEntity = chunkEntity,
                                X           = x,
                                Y           = y,
                                Z           = z,
                                Initialized = 1
                            });

                            EntityManager.SetComponentData(voxelEntity, new Translation
                            {
                                Value = position
                            });

                            VoxelsMap[x, y, z] = voxelEntity;
                        }
                    }
                }

                voxelChunk.IsPopulated = 1;
            }
        }

        et.Dispose();
        tmp.Dispose();
        pos.Dispose();
        return(inputDeps);
    }
    private void Update()
    {
        if (undo)
        {
            undo = false;

            var editManager = GetComponent <VoxelEditManagerContainer>().Instance;
            if (editManager != null)
            {
                editManager.Undo();
            }
        }

        if (redo)
        {
            redo = false;

            var editManager = GetComponent <VoxelEditManagerContainer>().Instance;
            if (editManager != null)
            {
                editManager.Redo();
            }
        }

        if (!lockSelection)
        {
            Camera camera = Camera.current;
            if (camera != null)
            {
                Vector3 relPos = camera.transform.position - transform.position;
                Vector3 relDir = Quaternion.Inverse(transform.rotation) * camera.transform.forward.normalized;

                //if (field.RayCast(relPos, relDir, 16, out TestVoxelField.RayCastResult result))
                if (gameObject.GetComponent <VoxelWorldContainer>().Instance.RayCast(relPos, relDir, 64, out VoxelWorld <MortonIndexer> .RayCastResult result))
                {
                    selectedCell = new Vector3Int(Mathf.FloorToInt(result.pos.x), Mathf.FloorToInt(result.pos.y), Mathf.FloorToInt(result.pos.z));
                }
                else
                {
                    selectedCell = null;
                }

                if (selectedCell != null)
                {
                    lockedSelection = selectedCell.Value;
                }
                else
                {
                    lockedSelection = Vector3Int.zero;
                }
            }
            else
            {
                selectedCell = null;
            }
        }
        else
        {
            selectedCell = lockedSelection;
        }

        if (selectedCell != null && prevSelectedCell != selectedCell)
        {
            //field.FillCell(selectedCell.Value.x, selectedCell.Value.y, selectedCell.Value.z, 0, gizmoCellMaterials, gizmoCellIntersections, gizmoCellNormals);
            var sculpture = gameObject.GetComponent <VoxelWorldContainer>().Instance;
            VoxelChunk <MortonIndexer> chunk = sculpture.GetChunk(ChunkPos.FromVoxel(selectedCell.Value, sculpture.ChunkSize));
            if (chunk != null)
            {
                chunk.FillCell(
                    ((selectedCell.Value.x % sculpture.ChunkSize) + sculpture.ChunkSize) % sculpture.ChunkSize,
                    ((selectedCell.Value.y % sculpture.ChunkSize) + sculpture.ChunkSize) % sculpture.ChunkSize,
                    ((selectedCell.Value.z % sculpture.ChunkSize) + sculpture.ChunkSize) % sculpture.ChunkSize,
                    0, gizmoCellMaterials, gizmoCellIntersections, gizmoCellNormals);

                gizmoCell = new RawArrayVoxelCell(0, (Vector3)selectedCell.Value, gizmoCellMaterials, gizmoCellIntersections, gizmoCellNormals);

                NativeMemoryCache memoryCache = new NativeMemoryCache(Allocator.Persistent);

                var polygonizer = new CMSVoxelPolygonizer <RawArrayVoxelCell, CMSStandardProperties, SvdQefSolver <RawArrayVoxelCell>, IntersectionSharpFeatureSolver <RawArrayVoxelCell> >(new CMSStandardProperties(), new SvdQefSolver <RawArrayVoxelCell>(), new IntersectionSharpFeatureSolver <RawArrayVoxelCell>(), memoryCache);

                var components        = new NativeList <VoxelMeshComponent>(Allocator.Persistent);
                var componentIndices  = new NativeList <PackedIndex>(Allocator.Persistent);
                var componentVertices = new NativeList <VoxelMeshComponentVertex>(Allocator.Persistent);

                polygonizer.Polygonize(gizmoCell, components, componentIndices, componentVertices);

                gizmoComponents = new List <VoxelMeshComponent>(components.Length);
                for (int i = 0; i < components.Length; i++)
                {
                    gizmoComponents.Add(components[i]);
                }

                gizmoComponentIndices = new List <PackedIndex>(componentIndices.Length);
                for (int i = 0; i < componentIndices.Length; i++)
                {
                    gizmoComponentIndices.Add(componentIndices[i]);
                }

                gizmoComponentVertices = new List <VoxelMeshComponentVertex>(componentVertices.Length);
                for (int i = 0; i < componentVertices.Length; i++)
                {
                    gizmoComponentVertices.Add(componentVertices[i]);
                }

                memoryCache.Dispose();
                components.Dispose();
                componentIndices.Dispose();
                componentVertices.Dispose();

                gizmoPosition  = selectedCell.Value;
                gizmoTransform = Matrix4x4.TRS(transform.position, transform.rotation, transform.lossyScale);
            }
        }

        prevSelectedCell = selectedCell;

        float brushSize = 2.1f + 8;

        if (placeSdf)
        {
            placeSdf   = false;
            regenerate = true;

            var editManager = GetComponent <VoxelEditManagerContainer>().Instance;

            switch (brushType)
            {
            case BrushType.Sphere:
                gameObject.GetComponent <VoxelWorldContainer>().Instance.ApplySdf(new Vector3(gizmoPosition.x, gizmoPosition.y, gizmoPosition.z), Quaternion.Euler(sdfRotation), new SphereSDF(brushSize), MaterialColors.ToInteger(materialRed, materialGreen, materialBlue, materialTexture), replaceSdfMaterial, editManager.Consumer());
                break;

            case BrushType.Box:
                gameObject.GetComponent <VoxelWorldContainer>().Instance.ApplySdf(new Vector3(gizmoPosition.x, gizmoPosition.y, gizmoPosition.z), Quaternion.Euler(sdfRotation), new BoxSDF(brushSize), MaterialColors.ToInteger(materialRed, materialGreen, materialBlue, materialTexture), replaceSdfMaterial, editManager.Consumer());
                break;

            case BrushType.Cylinder:
                gameObject.GetComponent <VoxelWorldContainer>().Instance.ApplySdf(new Vector3(gizmoPosition.x, gizmoPosition.y, gizmoPosition.z), Quaternion.Euler(sdfRotation), new CylinderSDF(brushSize, brushSize), MaterialColors.ToInteger(materialRed, materialGreen, materialBlue, materialTexture), replaceSdfMaterial, editManager.Consumer());
                break;

            case BrushType.Pyramid:
                gameObject.GetComponent <VoxelWorldContainer>().Instance.ApplySdf(new Vector3(gizmoPosition.x, gizmoPosition.y - brushSize / 2, gizmoPosition.z), Quaternion.Euler(sdfRotation), new PyramidSDF(brushSize * 2, brushSize * 2), MaterialColors.ToInteger(materialRed, materialGreen, materialBlue, materialTexture), replaceSdfMaterial, editManager.Consumer());
                break;

            case BrushType.Mesh:
                var mesh      = voxelizeMesh.mesh;
                var triangles = mesh.triangles;
                var vertices  = mesh.vertices;
                var normals   = mesh.normals;

                var inVertices = new NativeArray <float3>(triangles.Length, Allocator.TempJob);
                var inNormals  = new NativeArray <float3>(triangles.Length, Allocator.TempJob);

                for (int l = triangles.Length, i = 0; i < l; i += 3)
                {
                    inVertices[i]     = vertices[triangles[i]];
                    inVertices[i + 1] = vertices[triangles[i + 1]];
                    inVertices[i + 2] = vertices[triangles[i + 2]];

                    inNormals[i]     = normals[triangles[i]];
                    inNormals[i + 1] = normals[triangles[i + 1]];
                    inNormals[i + 2] = normals[triangles[i + 2]];
                }

                int voxelizerSize = 64;
                var outVoxels     = new NativeArray3D <Voxel.Voxel, MortonIndexer>(new MortonIndexer(voxelizerSize, voxelizerSize, voxelizerSize), voxelizerSize, voxelizerSize, voxelizerSize, Allocator.TempJob);

                var voxelizationProperties = smoothVoxelizerNormals ? Voxelizer.VoxelizationProperties.SMOOTH : Voxelizer.VoxelizationProperties.FLAT;

                var watch = new System.Diagnostics.Stopwatch();
                watch.Start();

                using (var job = Voxelizer.Voxelize(inVertices, inNormals, outVoxels, MaterialColors.ToInteger(materialRed, materialGreen, materialBlue, materialTexture), voxelizationProperties))
                {
                    job.Handle.Complete();
                }

                watch.Stop();
                Debug.Log("Voxelized mesh: " + watch.ElapsedMilliseconds + "ms");
                watch.Reset();
                watch.Start();

                //TODO Make voxelizer also undoable?
                gameObject.GetComponent <VoxelWorldContainer>().Instance.ApplyGrid((int)gizmoPosition.x, (int)gizmoPosition.y, (int)gizmoPosition.z, outVoxels, true, false, null);

                watch.Stop();
                Debug.Log("Applied to grid: " + watch.ElapsedMilliseconds + "ms");

                inVertices.Dispose();
                inNormals.Dispose();
                outVoxels.Dispose();

                break;

            case BrushType.Custom:
                using (var sdf = customBrush.Instance.CreateSdf(Allocator.TempJob))
                {
                    gameObject.GetComponent <VoxelWorldContainer>().Instance.ApplySdf(new Vector3(gizmoPosition.x, gizmoPosition.y, gizmoPosition.z), Quaternion.Euler(sdfRotation), sdf, MaterialColors.ToInteger(materialRed, materialGreen, materialBlue, materialTexture), replaceSdfMaterial, editManager.Consumer());
                }
                break;
            }
        }

        if (gizmoPosition != null)
        {
            switch (brushType)
            {
            case BrushType.Sphere:
                gameObject.GetComponent <SdfShapeRenderHandler>().Render(new Vector3(gizmoPosition.x, gizmoPosition.y, gizmoPosition.z), Quaternion.Euler(sdfRotation), new SphereSDF(brushSize));
                break;

            case BrushType.Box:
                gameObject.GetComponent <SdfShapeRenderHandler>().Render(new Vector3(gizmoPosition.x, gizmoPosition.y, gizmoPosition.z), Quaternion.Euler(sdfRotation), new BoxSDF(brushSize));
                break;

            case BrushType.Cylinder:
                gameObject.GetComponent <SdfShapeRenderHandler>().Render(new Vector3(gizmoPosition.x, gizmoPosition.y, gizmoPosition.z), Quaternion.Euler(sdfRotation), new CylinderSDF(brushSize, brushSize));
                break;

            case BrushType.Pyramid:
                gameObject.GetComponent <SdfShapeRenderHandler>().Render(new Vector3(gizmoPosition.x, gizmoPosition.y - brushSize / 2, gizmoPosition.z), Quaternion.Euler(sdfRotation), new PyramidSDF(brushSize * 2, brushSize * 2));
                break;

            case BrushType.Custom:
                Matrix4x4 brushTransform = Matrix4x4.TRS(new Vector3(gizmoPosition.x, gizmoPosition.y, gizmoPosition.z), Quaternion.Euler(sdfRotation), new Vector3(1, 1, 1));
                using (var sdf = customBrush.Instance.CreateSdf(Allocator.TempJob))
                {
                    gameObject.GetComponent <SdfShapeRenderHandler>().Render(brushTransform, sdf);
                }

                Camera camera = Camera.current;
                if (camera != null)
                {
                    selectedPrimitive = -1;

                    var   ray    = camera.transform.forward.normalized;
                    float maxDst = 60.0f;
                    int   steps  = Mathf.CeilToInt(maxDst * 2);
                    for (int i = 0; i < steps && selectedPrimitive < 0; i++)
                    {
                        var pos = camera.transform.position + ray * maxDst / steps * i;

                        int j = 0;
                        foreach (var primitive in customBrush.Instance.Primitives)
                        {
                            var renderSdf = customBrush.Instance.Evaluator.GetRenderSdf(primitive);
                            if (renderSdf != null && renderSdf.Eval(math.mul(math.mul(brushTransform, primitive.invTransform), new float4(pos, 1.0f)).xyz) < 0)
                            {
                                selectedPrimitive = j;
                                break;
                            }
                            j++;
                        }
                    }
                }
                if (selectedPrimitive >= 0 && selectedPrimitive < customBrush.Instance.Primitives.Count)
                {
                    var primitive = customBrush.Instance.Primitives[selectedPrimitive];
                    var renderSdf = customBrush.Instance.Evaluator.GetRenderSdf(primitive);
                    if (renderSdf != null)
                    {
                        gameObject.GetComponent <SdfShapeRenderHandler>().Render(brushTransform * (Matrix4x4)primitive.transform, renderSdf);
                    }
                }
                break;
            }
        }

        if (generateEachFrame || regenerate)
        {
            regenerate = false;
            //GenerateMesh();
        }
    }
Example #9
0
 public NativeArray3DDebugView(NativeArray3D <T> array)
 {
     m_Array = array;
 }