internal void ExecuteSpawn() { lock (this) { if (m_removeQueued || !m_spawnQueued) { return; } if (VoxelMap == null) { var mat = MatrixD.CreateFromQuaternion(Rotation); mat.Translation = WorldPosition; var genSeed = WorldPosition.GetHashCode(); if (VoxelUtility.TryFindAsteroidSeed(ref genSeed, Size, SeedSpecs.ProhibitsOre, SeedSpecs.RequiresOre, 10) || !SeedSpecs.ExcludeInvalid) { VoxelMap = VoxelUtility.SpawnAsteroid(new MyPositionAndOrientation(mat), VoxelUtility.CreateProceduralAsteroidProvider(genSeed, Size)); VoxelMap.OnPhysicsChanged += MarkForSave; } } m_spawnQueued = false; m_removeQueued = false; } }
public void Execute(int index) { int position = surfaceVoxelsIndex[index]; int3 position3 = VoxelUtility.Index1ToIndex3(position); Debug.Assert(surfaceVoxels.TryGetValue(position, out bool v)); int noNeighborCount_Debug = 0; int3[] neighborPosition3 = new int3[] { position3 + new int3(1, 0, 0), position3 + new int3(-1, 0, 0), position3 + new int3(0, 1, 0), position3 + new int3(0, -1, 0), position3 + new int3(0, 0, 1), position3 + new int3(0, 0, -1) }; foreach (var neighborPos in neighborPosition3) { if (!surfaceVoxels.TryGetValue(VoxelUtility.Index3ToIndex1(neighborPos), out bool v1)) { int surface = VoxelUtility.GetSurfaceIndex(position3, neighborPos); surfaceFaces.TryAdd(surface, true); noNeighborCount_Debug++; } } if (noNeighborCount_Debug == 6) { Debug.LogError("No neighboring voxel for " + position3); } }
private void CheckRaycastHit() { var rayPosition = CachedTransform.position + Vector3.forward * RAY_LENGTH; if (VoxelUtility.VoxelRayCast(CachedTransform.position, transform.TransformDirection(Vector3.forward), out var voxel, RAY_LENGTH)) { rayPosition = voxel.HitPosition; _currentHitVoxel = voxel.VoxelInfo; }
public override bool TickAfterSimulationRoundRobin() { ProceduralBody body; if (_addQueue.TryDequeue(out body)) { var generatorDef = MyDefinitionManagerBase.Static.GetDefinition <MyPlanetGeneratorDefinition>(body.GeneratorId); body.Result = VoxelUtility.SpawnPlanet(body.Position.Translation, generatorDef, body.Seed, (float)body.Radius, body.Name); return(true); } return(false); }
private void Awake() { _cameraTransform = _camera.transform; _voxelGeometryController = new VoxelGeometryController(8, GetMaxVerticesCount()); _voxelBuilderController = new VoxelBuilderController(); _voxelPhysicsController = new VoxelPhysicsController(); _fallingConstructionFactory = new FallingConstructionFactory(_fallingChunksTransform, 32); _camera.Hitted += OnHitted; var magicaVoxelReader = new MagicaReader(); var path = GetPathInStreamingAssets(_volumePath); var magicaFile = magicaVoxelReader.LoadFile(path); _voxelModel = magicaFile.ToModel(_volumeSize); var chunkSize = _chunkSize; var chunksCount = _chunkDrawSize.x * _chunkDrawSize.y * _chunkDrawSize.z; Debug.Log($"chunksCount = {chunksCount}"); for (var i = 0; i < chunksCount; i++) { var chunkPositionNormalized = VoxelUtility.GetVoxelPosition(i, _chunkDrawSize); var chunkIndex = VoxelChunkUtility.GetIndex(chunkPositionNormalized); var chunkPosition = chunkPositionNormalized * chunkSize; var chunkGameObject = new GameObject(); var chunkView = chunkGameObject.AddComponent <VolumeChunk>(); chunkGameObject.name = $"VolumeChunk[{i}]"; chunkView.SetPosition(new Vector3(chunkPosition.x, chunkPosition.y, chunkPosition.z)); chunkView.SetParent(_volumeChunksTransform); chunkView.SetMaterial(_chunkMaterial); chunkView.SetLayer(VolumeChunk.VolumeLayer); _chunks[chunkIndex] = chunkView; var geometryRequest = GetGeometryRequestById(chunkIndex); _chunkRequestQueue.Push(geometryRequest); } _chunkRenderer = new VoxelChunkRenderer(_cameraTransform, _chunks, _volumeSize, _chunkSize, _chunkDrawSize); _chunkRenderer.ChunkUpdated += OnChunkUpdated; }
public static VoxelGeometryVolumeRequest CreateVolumeRequest(int chunkIndex, Vector3Int chunkSize, VoxelModel model, Vector3Int chunkDimensions) { var position = VoxelUtility.GetVoxelPosition(chunkIndex, chunkDimensions); var request = new VoxelGeometryVolumeRequest { chunkPosition = new Vector3Int(position.x, position.y, position.z), chunkSize = chunkSize, scale = 1f, pivot = new Vector3(0.0f, 0.0f, 0.0f), model = model, faceColorMultipliers = FaceColorMultipliers, edgeColorMultiplier = new Vector3(0.07f, 0.08f, 0.12f), cornerColorMultiplier = new Vector3(-0.14f, -0.25f, -0.4f) }; return(request); }
public void Execute(int index) { int xGrid = index / totalGridCount.y; //[0,totalGridCount.x) int yGrid = index % totalGridCount.y; bool inside = false; for (int z = 0; z != totalGridCount.z - 1; ++z) { int faceIndex = VoxelUtility.GetSurfaceIndex(new int3(xGrid, yGrid, z), new int3(xGrid, yGrid, z + 1)); if (surfaceFaces.TryGetValue(faceIndex, out bool v)) { inside = !inside; } if (inside) { volumeVoxels.TryAdd(VoxelUtility.Index3ToIndex1(new int3(xGrid, yGrid, z + 1)), true); } } }
public void Iterate_Over_KeysWithRefs() { var count = 10; var dictionary = GetDictionary(); var sw = Stopwatch.StartNew(); for (var i = 0; i < count; i++) { foreach (var key in dictionary.Keys) { var position = VoxelUtility.GetPositionByHash(key); var index = VoxelUtility.GetVoxelIndex(position, _voxelsSize); ref var voxel = ref _voxels[index]; var color = voxel.colorIndex; voxel.data = 0; voxel.colorIndex = 0; } }
public static VoxelModel ToModel(this MagicaFile magicaFile, Vector3Int volumeSize) { var magicaChunks = magicaFile.Chunks; var volume = new VoxelModel(volumeSize, magicaFile.Palette); var minPosition = new Vector3Int(int.MaxValue, int.MaxValue, int.MaxValue); var maxPosition = new Vector3Int(int.MinValue, int.MinValue, int.MinValue); var magicaSize = new Vector3(); for (var chunkIndex = 0; chunkIndex < magicaChunks.Length; chunkIndex++) { var magicaChunk = magicaChunks[chunkIndex]; var defaultPosition = magicaChunk.position; var chunkSize = magicaChunk.size; var chunkPosition = defaultPosition - chunkSize / 2; magicaChunk.position = chunkPosition; for (var i = 0; i < 3; i++) { if (chunkPosition[i] < minPosition[i]) { minPosition[i] = chunkPosition[i]; } } for (var i = 0; i < 3; i++) { if (chunkPosition[i] + chunkSize[i] > maxPosition[i]) { maxPosition[i] = chunkPosition[i] + chunkSize[i]; } } for (var i = 0; i < 3; i++) { magicaSize[i] = maxPosition[i] - minPosition[i]; } magicaChunks[chunkIndex] = magicaChunk; } foreach (var chunk in magicaChunks) { var voxels = chunk.voxels; var chunkPosition = new Vector3Int(chunk.position.x, chunk.position.y, chunk.position.z); var positionAdjustment = chunkPosition - minPosition; var rotation = chunk.rotation; var size = chunk.size; foreach (var magicaVoxel in voxels) { var voxelPosition = new Vector3Int(magicaVoxel.x, magicaVoxel.y, magicaVoxel.z); for (var i = 0; i < 3; i++) { var multiplier = rotation[i]; if (multiplier != 1) { var value = voxelPosition[i] * multiplier; voxelPosition[i] = size[i] + value - 1; } } var position = voxelPosition + positionAdjustment; var index = VoxelUtility.GetVoxelIndex(position, volumeSize); var voxel = new VoxelEntity { colorIndex = magicaVoxel.colorIndex, data = 100 }; volume.SetVoxel(index, voxel); } } return(volume); }
private void coverVoxelsWithTriangleEdge(float3 A, float3 B) { int3 aVoxelIndex = VoxelUtility.PosToIndex3(A); int3 bVoxelIndex = VoxelUtility.PosToIndex3(B); int aVoxelIndex1 = VoxelUtility.Index3ToIndex1(aVoxelIndex); int bVoxeklndex1 = VoxelUtility.Index3ToIndex1(bVoxelIndex); float3 aVoxelCenter = VoxelUtility.Index3ToPos(aVoxelIndex); float3 bVoxelCenter = VoxelUtility.Index3ToPos(bVoxelIndex); if (aVoxelIndex.x == bVoxelIndex.x && aVoxelIndex.y == bVoxelIndex.y || aVoxelIndex.x == bVoxelIndex.x && aVoxelIndex.z == bVoxelIndex.z || aVoxelIndex.y == bVoxelIndex.y && aVoxelIndex.z == bVoxelIndex.z) { /*Same Grid or 6-neighbor*/ voxels.TryAdd(aVoxelIndex1, true); voxels.TryAdd(bVoxeklndex1, true); return; } if (aVoxelIndex.x == bVoxelIndex.x) { /*yz plane neighbor */ float2 xy = LinePlaneIntersect(A, B, 'z', 0.5f * (aVoxelCenter.z + bVoxelCenter.z)); float x = xy.x; float y = xy.y; //if (!(A.x <= x && x <= B.x || B.x <= x && x <= A.x)){ // Debug.Log(A + "<>" + B + "<>" + aVoxelCenter + "<>" + bVoxelCenter + " -> " + x); //} //Debug.Assert(A.x <= x && x <= B.x || B.x <= x && x <= A.x); int connector; if (math.abs(y - A.y) < math.abs(y - B.y)) { connector = VoxelUtility.Index3ToIndex1(new int3(aVoxelIndex.x, aVoxelIndex.y, bVoxelIndex.z)); } else { connector = VoxelUtility.Index3ToIndex1(new int3(aVoxelIndex.x, bVoxelIndex.y, aVoxelIndex.z)); } voxels.TryAdd(connector, true); return; } if (aVoxelIndex.y == bVoxelIndex.y) { /*xz plane neighbor */ float2 yz = LinePlaneIntersect(A, B, 'x', 0.5f * (aVoxelCenter.x + bVoxelCenter.x)); float y = yz.x; float z = yz.y; //Debug.Assert(A.y <= y && y <= B.y || B.y <= y && y <= A.y); int connector; if (math.abs(z - A.z) < math.abs(z - B.z)) { connector = VoxelUtility.Index3ToIndex1(new int3(bVoxelIndex.x, aVoxelIndex.y, aVoxelIndex.z)); } else { connector = VoxelUtility.Index3ToIndex1(new int3(aVoxelIndex.x, aVoxelIndex.y, bVoxelIndex.z)); } voxels.TryAdd(connector, true); return; } if (aVoxelIndex.z == bVoxelIndex.z) { /*xy plane neighbor */ float2 xz = LinePlaneIntersect(A, B, 'y', 0.5f * (aVoxelCenter.y + bVoxelCenter.y)); float x = xz.x; float z = xz.y; //Debug.Assert(A.z <= z && z <= B.z || B.z <= z && z <= A.z); int connector; if (math.abs(x - A.x) < math.abs(x - B.x)) { connector = VoxelUtility.Index3ToIndex1(new int3(aVoxelIndex.x, bVoxelIndex.y, aVoxelIndex.z)); } else { connector = VoxelUtility.Index3ToIndex1(new int3(bVoxelIndex.x, aVoxelIndex.y, aVoxelIndex.z)); } voxels.TryAdd(connector, true); return; } /*3D diagonal */ float2 _yz = LinePlaneIntersect(A, B, 'x', 0.5f * (aVoxelCenter.x + bVoxelCenter.x)); if (RectContains(new float2(aVoxelCenter.y, aVoxelCenter.z), _yz)) { /*baa */ voxels.TryAdd(VoxelUtility.Index3ToIndex1(new int3(bVoxelIndex.x, aVoxelIndex.y, aVoxelIndex.z)), true); } else { if (RectContains(new float2(bVoxelCenter.y, bVoxelCenter.z), _yz)) { /*abb */ voxels.TryAdd(VoxelUtility.Index3ToIndex1(new int3(aVoxelIndex.x, bVoxelIndex.y, bVoxelIndex.z)), true); } } float2 _xz = LinePlaneIntersect(A, B, 'y', 0.5f * (aVoxelCenter.y + bVoxelCenter.y)); if (RectContains(new float2(aVoxelCenter.x, aVoxelCenter.z), _xz)) { /*aba */ voxels.TryAdd(VoxelUtility.Index3ToIndex1(new int3(aVoxelIndex.x, bVoxelIndex.y, aVoxelIndex.z)), true); } else { if (RectContains(new float2(bVoxelCenter.x, bVoxelCenter.z), _xz)) { /*bab */ voxels.TryAdd(VoxelUtility.Index3ToIndex1(new int3(bVoxelIndex.x, aVoxelIndex.y, bVoxelIndex.z)), true); } } float2 _xy = LinePlaneIntersect(A, B, 'z', 0.5f * (aVoxelCenter.z + bVoxelCenter.z)); if (RectContains(new float2(aVoxelCenter.x, aVoxelCenter.y), _xy)) { /*aab */ voxels.TryAdd(VoxelUtility.Index3ToIndex1(new int3(aVoxelIndex.x, aVoxelIndex.y, bVoxelIndex.z)), true); } else { if (RectContains(new float2(bVoxelCenter.x, bVoxelCenter.y), _xy)) { /*bba */ voxels.TryAdd(VoxelUtility.Index3ToIndex1(new int3(bVoxelIndex.x, bVoxelIndex.y, aVoxelIndex.z)), true); } } }
protected override JobHandle OnUpdate(JobHandle inputDeps) { var voxelArray = volumetric ? volumePosArray : surfacePosArray; int existingCount = newGroup.CalculateLength() + movingGroup.CalculateLength() + finishedGroup.CalculateLength(); int incAmount = math.min((int)math.ceil(voxelArray.Length / minDuration * Time.deltaTime), voxelArray.Length - existingCount); //Debug.Log(finishedGroup.CalculateLength() + " finished"); if (finishedGroup.CalculateLength() == voxelArray.Length) { Debug.Log("Finished"); return(inputDeps); } //When there's too much moving job, stop adding new objects if (movingGroup.CalculateLength() >= maxMovingNumber) { incAmount = 0; } // Move NativeHashMap <Entity, bool> reachedTargetVoxel = new NativeHashMap <Entity, bool>(movingGroup.CalculateLength(), Allocator.TempJob); var moveJob = new MoveVoxel { finishedOutput = reachedTargetVoxel.ToConcurrent(), deltaTime = Time.deltaTime, lerpSpeed = randomGenerater, tolerance = voxelSize * 0.1f, }; JobHandle moveHandle = moveJob.Schedule(movingGroup, inputDeps); moveHandle.Complete(); // Spawn var entities = new NativeArray <Entity>(incAmount, Allocator.TempJob); EntityManager.Instantiate(voxelPrefab, entities); var spawnPositions = new NativeArray <float3>(incAmount, Allocator.TempJob); GeneratePoints.RandomPointsInUnitSphere(spawnPositions); int spawnBase = finishedGroup.CalculateLength() + movingGroup.CalculateLength(); for (int i = 0; i != incAmount; ++i) { RenderMesh m = EntityManager.GetSharedComponentData <RenderMesh>(entities[i]); m.material = VoxelUtility.GetMaterial(VoxelUtility.Index1ToPos(voxelArray[i + spawnBase]).y); EntityManager.SetSharedComponentData(entities[i], m); EntityManager.SetComponentData(entities[i], new Voxel { targetPosition = VoxelUtility.Index1ToPos(voxelArray[i + spawnBase]) }); Vector3 rdnCenter = spawnPositions[i]; float3 rdnCenterf = VoxelUtility.BBoxCenter + (float3)rdnCenter * VoxelUtility.DiagonalLength; var localToWorld = new LocalToWorld { Value = float4x4.TRS( rdnCenterf, quaternion.Euler( UnityEngine.Random.Range(0.0f, 360f), UnityEngine.Random.Range(0.0f, 360f), UnityEngine.Random.Range(0.0f, 360f)), new float3(voxelSize, voxelSize, voxelSize)) }; EntityManager.SetComponentData(entities[i], localToWorld); } EntityManager.RemoveComponent(entities, ComponentType.ReadWrite <NewVoxel>()); EntityManager.AddComponent(entities, ComponentType.ReadWrite <MovingVoxel>()); var justReachedVoxels = reachedTargetVoxel.GetKeyArray(Allocator.TempJob); EntityManager.RemoveComponent(justReachedVoxels, ComponentType.ReadWrite <MovingVoxel>()); entities.Dispose(); reachedTargetVoxel.Dispose(); justReachedVoxels.Dispose(); spawnPositions.Dispose(); return(moveHandle); }
protected override void OnCreateManager() { //Comment this in Build version // UnityEditor.SceneView.FocusWindowIfItsOpen(typeof(UnityEditor.SceneView)); randomGenerater = new Unity.Mathematics.Random(1); modelPrefab = Resources.Load <GameObject>(modelName); modelMesh = ((MeshFilter)modelPrefab.GetComponentInChildren(typeof(MeshFilter))).sharedMesh; VoxelUtility.Init(modelMesh, voxelSize, bottomColor, topColor); VoxelUtility.Describe(); float3[] f3Vertex = modelMesh.vertices.ToList().ConvertAll(input => new float3(input.x, input.y, input.z)).ToArray(); var meshVertexs = new NativeArray <float3>(f3Vertex, Allocator.TempJob); int3[] i3Triangle = new int3[modelMesh.triangles.Length / 3]; int[] tri = modelMesh.triangles; for (int i = 0; i != i3Triangle.Length; ++i) { i3Triangle[i].x = tri[i * 3]; i3Triangle[i].y = tri[i * 3 + 1]; i3Triangle[i].z = tri[i * 3 + 2]; } var meshTriangles = new NativeArray <int3>(i3Triangle, Allocator.TempJob); hashMap = new NativeHashMap <int, bool>(VoxelUtility.TotalGridsCount, Allocator.TempJob); var HashTriangleToVoxelJob = new HashTriangleToVoxel { vertexs = meshVertexs, triangles = meshTriangles, voxels = hashMap.ToConcurrent(), }; JobHandle toSurfaceVoxelHandle = HashTriangleToVoxelJob.Schedule(i3Triangle.Length, 64); toSurfaceVoxelHandle.Complete(); surfacePosArray = hashMap.GetKeyArray(Allocator.Persistent); // Length = # surface voxels /*End of step a */ NativeHashMap <int, bool> surfaceHashMap = new NativeHashMap <int, bool>(VoxelUtility.TotalGridsCount * 3, Allocator.TempJob); var HashVoxelCommonFaceJob = new HashSurfaceVoxelUnCommonFace { surfaceVoxels = hashMap, surfaceVoxelsIndex = surfacePosArray, surfaceFaces = surfaceHashMap.ToConcurrent() }; JobHandle toSurfaceFaceHandle = HashVoxelCommonFaceJob.Schedule(surfacePosArray.Length, 64, toSurfaceVoxelHandle); toSurfaceFaceHandle.Complete(); Debug.Log("# Face Before removal: NumFace = " + surfaceHashMap.Length + " \nNumV= " + hashMap.Length); RemoveOneConsecutiveSurface(ref surfaceHashMap); Debug.Log("Faces Count After removal: " + surfaceHashMap.Length); /*End of step c*/ int3 totalGridsCount = VoxelUtility.CalculateTotalGrids; NativeHashMap <int, bool> volumeHashMap = new NativeHashMap <int, bool>(VoxelUtility.TotalGridsCount, Allocator.TempJob); var castRayToVolumeJob = new CastRayToVolume { surfaceFaces = surfaceHashMap, volumeVoxels = volumeHashMap.ToConcurrent(), totalGridCount = totalGridsCount }; JobHandle castRayHandle = castRayToVolumeJob.Schedule(totalGridsCount.x * totalGridsCount.y, 64, toSurfaceFaceHandle); castRayHandle.Complete(); volumePosArray = volumeHashMap.GetKeyArray(Allocator.Persistent); Debug.Log("Surface voxels Count: " + surfacePosArray.Length); Debug.Log("Volume voxels Count: " + volumePosArray.Length); meshVertexs.Dispose(); meshTriangles.Dispose(); hashMap.Dispose(); surfaceHashMap.Dispose(); volumeHashMap.Dispose(); if (randomOrder) { Shuffle(surfacePosArray); Shuffle(volumePosArray); } voxelPrefab = Resources.Load <GameObject>("Voxel"); newGroup = GetEntityQuery(new EntityQueryDesc { All = new [] { ComponentType.ReadWrite <Voxel>(), ComponentType.ReadWrite <LocalToWorld>(), ComponentType.ReadWrite <NewVoxel>() }, Options = EntityQueryOptions.Default }); movingGroup = GetEntityQuery(new EntityQueryDesc { All = new [] { ComponentType.ReadWrite <Voxel>(), ComponentType.ReadWrite <LocalToWorld>(), ComponentType.ReadWrite <MovingVoxel>() }, Options = EntityQueryOptions.Default }); finishedGroup = GetEntityQuery(new EntityQueryDesc { All = new [] { ComponentType.ReadWrite <Voxel>(), ComponentType.ReadWrite <LocalToWorld>() }, None = new ComponentType[] { ComponentType.ReadWrite <MovingVoxel>(), ComponentType.ReadWrite <NewVoxel>() }, Options = EntityQueryOptions.Default }); }
void RemoveOneConsecutiveSurface(ref NativeHashMap <int, bool> hashmap) { NativeHashMap <int, bool> removedSurface = new NativeHashMap <int, bool>(hashmap.Capacity, Allocator.TempJob); var keys = hashmap.GetKeyArray(Allocator.TempJob); int index1 = keys[0]; keys.Dispose(); Queue <int> toBeRemoved = new Queue <int>(); toBeRemoved.Enqueue(index1); //Debug.Log("Removal starts from " + VoxelUtility.getFacePosition(index1)); while (toBeRemoved.Count > 0) { int workingIndex = toBeRemoved.Dequeue(); hashmap.Remove(workingIndex); removedSurface.TryAdd(workingIndex, true); int3 voxel1, voxel2; (voxel1, voxel2) = VoxelUtility.SurfaceIndexToVoxels(workingIndex); int3[] neighborInc = new int3[4]; if (voxel1.x != voxel2.x) { neighborInc[0] = new int3(0, 1, 0); neighborInc[1] = new int3(0, -1, 0); neighborInc[2] = new int3(0, 0, 1); neighborInc[3] = new int3(0, 0, -1); } if (voxel1.y != voxel2.y) { neighborInc[0] = new int3(1, 0, 0); neighborInc[1] = new int3(-1, 0, 0); neighborInc[2] = new int3(0, 0, 1); neighborInc[3] = new int3(0, 0, -1); } if (voxel1.z != voxel2.z) { neighborInc[0] = new int3(1, 0, 0); neighborInc[1] = new int3(-1, 0, 0); neighborInc[2] = new int3(0, 1, 0); neighborInc[3] = new int3(0, -1, 0); } foreach (int3 voxel in new int3[] { voxel1, voxel2 }) { foreach (int3 inc in neighborInc) { int3 candidateNeighbor = voxel + inc; int candidateFace = VoxelUtility.GetSurfaceIndex(voxel, candidateNeighbor); if (hashmap.TryGetValue(candidateFace, out bool v)) { if (v) { // only enqueue newly discovered neighbor toBeRemoved.Enqueue(candidateFace); // set face's flag to False: it has already be put into queue hashmap.Remove(candidateFace); hashmap.TryAdd(candidateFace, false); } } } } foreach (int3 inc in neighborInc) { int3 voxel1Offseted = voxel1 + inc; int3 voxel2Offseted = voxel2 + inc; int candidateFace = VoxelUtility.GetSurfaceIndex(voxel1Offseted, voxel2Offseted); if (hashmap.TryGetValue(candidateFace, out bool v)) { if (v) { // only enqueue newly discovered neighbor toBeRemoved.Enqueue(candidateFace); // set face's flag to False: it has already be put into queue hashmap.Remove(candidateFace); hashmap.TryAdd(candidateFace, false); } } } } if (hashmap.Length < removedSurface.Length) { hashmap.Dispose(); hashmap = removedSurface; } else { removedSurface.Dispose(); } }
public VoxelHitInfo GetHitInfo(RaycastHit hit) { var direction = _meshRayCastUseCase.HitDirection.Value; return(new VoxelHitInfo(this, hit.point, VoxelUtility.DirectionalCenterPoint(CachedTransform.position, direction), direction)); }