private void EventMouseDrag(bool first) { if (baseTarget.edit_configureMode == VoxelBase.Edit_configureMode.Material) { UpdateCursorMesh(); switch (baseTarget.edit_materialTypeMode) { case VoxelBase.Edit_MaterialTypeMode.Voxel: { var result = editorCommon.GetMousePositionVoxel(); if (result.HasValue) { editVoxelList.Set(result.Value, true); UpdatePreviewMesh(); } } break; case VoxelBase.Edit_MaterialTypeMode.Fill: { var pos = editorCommon.GetMousePositionVoxel(); if (pos.HasValue) { var result = editorCommon.GetFillVoxel(pos.Value); if (result != null) { for (int i = 0; i < result.Count; i++) { editVoxelList.Set(result[i], true); } UpdatePreviewMesh(); } } } break; case VoxelBase.Edit_MaterialTypeMode.Rect: { var pos = new IntVector2((int)Event.current.mousePosition.x, (int)Event.current.mousePosition.y); if (first) { editorCommon.selectionRect.Reset(); editorCommon.selectionRect.SetStart(pos); } else { editorCommon.selectionRect.SetEnd(pos); } // editVoxelList.Clear(); { var list = editorCommon.GetSelectionRectVoxel(); for (int i = 0; i < list.Count; i++) { editVoxelList.Set(list[i], true); } } UpdatePreviewMesh(); } break; } } }
public void CreateVoxelTable() { #region voxelTable { voxelTable = new DataTable3 <int>(voxelSize.x, voxelSize.y, voxelSize.z); if (voxels != null) { for (int i = 0; i < voxels.Length; i++) { voxelTable.Set(voxels[i].position, i); } } } #endregion #region vertexList { vertexList = new List <IntVector3>(2 * voxels.Length); bool[,,] doneTable = new bool[voxelSize.x + 1, voxelSize.y + 1, voxelSize.z + 1]; Action <IntVector3> AddPoint = (pos) => { if (pos.x < 0 || pos.y < 0 || pos.z < 0) { return; } if (!doneTable[pos.x, pos.y, pos.z]) { doneTable[pos.x, pos.y, pos.z] = true; vertexList.Add(pos); } }; if (voxels != null) { for (int i = 0; i < voxels.Length; i++) { AddPoint(new IntVector3(voxels[i].x, voxels[i].y, voxels[i].z)); AddPoint(new IntVector3(voxels[i].x + 1, voxels[i].y, voxels[i].z)); AddPoint(new IntVector3(voxels[i].x, voxels[i].y + 1, voxels[i].z)); AddPoint(new IntVector3(voxels[i].x, voxels[i].y, voxels[i].z + 1)); AddPoint(new IntVector3(voxels[i].x + 1, voxels[i].y + 1, voxels[i].z)); AddPoint(new IntVector3(voxels[i].x + 1, voxels[i].y, voxels[i].z + 1)); AddPoint(new IntVector3(voxels[i].x, voxels[i].y + 1, voxels[i].z + 1)); AddPoint(new IntVector3(voxels[i].x + 1, voxels[i].y + 1, voxels[i].z + 1)); } } } #endregion #region outsideTable { bool[,,] doneTable = new bool[voxelSize.x, voxelSize.y, voxelSize.z]; outsideTable = new FlagTable3(voxelSize.x, voxelSize.y, voxelSize.z); List <IntVector3> findList = new List <IntVector3>(voxelSize.x * voxelSize.y * voxelSize.z); Action <int, int, int> AddFindList = (x, y, z) => { if (x < 0 || x >= voxelSize.x || y < 0 || y >= voxelSize.y || z < 0 || z >= voxelSize.z) { return; } if (doneTable[x, y, z]) { return; } doneTable[x, y, z] = true; if (VoxelTableContains(x, y, z) >= 0) { return; } if (outsideTable.Get(x, y, z)) { return; } findList.Add(new IntVector3(x, y, z)); outsideTable.Set(x, y, z, true); }; for (int x = 0; x < voxelSize.x; x++) { for (int y = 0; y < voxelSize.y; y++) { AddFindList(x, y, 0); AddFindList(x, y, voxelSize.z - 1); } for (int z = 0; z < voxelSize.z; z++) { AddFindList(x, 0, z); AddFindList(x, voxelSize.y - 1, z); } } for (int z = 0; z < voxelSize.z; z++) { for (int y = 0; y < voxelSize.y; y++) { AddFindList(0, y, z); AddFindList(voxelSize.x - 1, y, z); } } for (int i = 0; i < findList.Count; i++) { var pos = findList[i]; AddFindList(pos.x + 1, pos.y, pos.z); AddFindList(pos.x - 1, pos.y, pos.z); AddFindList(pos.x, pos.y + 1, pos.z); AddFindList(pos.x, pos.y - 1, pos.z); AddFindList(pos.x, pos.y, pos.z + 1); AddFindList(pos.x, pos.y, pos.z - 1); } } #endregion updateVoxelTableLastTimeTicks = DateTime.Now.Ticks; }
public override void GenerateOnly() { if (voxelObject == null || voxelObjectCore.voxelData == null) { return; } var voxelData = voxelObjectCore.voxelData; //BasicCube Vector3 cubeCenter; List <Vector3> cubeVertices; List <Vector3> cubeNormals; List <int> cubeTriangles; CreateBasicCube(out cubeCenter, out cubeVertices, out cubeNormals, out cubeTriangles); #region Voxels List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Color> colors = new List <Color>(); List <Vector4> tangents = new List <Vector4>(); List <int>[] triangles = new List <int> [voxelBase.materialData.Count]; for (int i = 0; i < triangles.Length; i++) { triangles[i] = new List <int>(); } #region Mesh Func <VoxelObjectExplosion.MeshData, VoxelObjectExplosion.MeshData> CreateMesh = (data) => { if (data == null) { data = new VoxelObjectExplosion.MeshData(); } if (data.mesh == null) { data.mesh = new Mesh(); } else { data.mesh.Clear(false); data.mesh.ClearBlendShapes(); } data.materialIndexes.Clear(); #if UNITY_2017_3_OR_NEWER data.mesh.indexFormat = vertices.Count > 65000 ? UnityEngine.Rendering.IndexFormat.UInt32 : UnityEngine.Rendering.IndexFormat.UInt16; #endif data.mesh.vertices = vertices.ToArray(); data.mesh.normals = normals.ToArray(); data.mesh.colors = colors.ToArray(); data.mesh.tangents = tangents.ToArray(); { int materialCount = 0; for (int i = 0; i < triangles.Length; i++) { if (triangles[i].Count > 0) { materialCount++; } } data.mesh.subMeshCount = materialCount; int submesh = 0; for (int i = 0; i < triangles.Length; i++) { if (triangles[i].Count > 0) { data.materialIndexes.Add(i); data.mesh.SetTriangles(triangles[i].ToArray(), submesh++); } } } data.mesh.RecalculateBounds(); { var bounds = data.mesh.bounds; bounds.min -= Vector3.one * explosionBase.edit_velocityMax; bounds.max += Vector3.one * explosionBase.edit_velocityMax; data.mesh.bounds = bounds; } vertices.Clear(); normals.Clear(); colors.Clear(); tangents.Clear(); for (int i = 0; i < voxelBase.materialData.Count; i++) { triangles[i].Clear(); } return(data); }; #endregion { int meshIndex = 0; Action <int, int> AddVertex = (mat, index) => { if (explosionBase.edit_birthRate < 1f) { if (UnityEngine.Random.value >= explosionBase.edit_birthRate) { return; } } if (explosionBase.edit_visibleOnly) { if (!voxelObjectCore.IsVoxelVisible(voxelData.voxels[index].position)) { return; } } #if !UNITY_2017_3_OR_NEWER if (vertices.Count + cubeVertices.Count >= 65000) { for (int i = explosionObject.meshes.Count; i <= meshIndex; i++) { explosionObject.meshes.Add(null); } explosionObject.meshes[meshIndex] = CreateMesh(explosionObject.meshes[meshIndex]); if (!AssetDatabase.Contains(explosionObject.meshes[meshIndex].mesh)) { voxelBaseCore.AddObjectToPrefabAsset(explosionObject.meshes[meshIndex].mesh, "explosion_mesh", meshIndex); } meshIndex++; } #endif var color = voxelData.palettes[voxelData.voxels[index].palette]; var vOffset = vertices.Count; for (int i = 0; i < cubeVertices.Count; i++) { var pos = cubeVertices[i]; pos.x += voxelData.voxels[index].position.x * voxelBase.importScale.x; pos.y += voxelData.voxels[index].position.y * voxelBase.importScale.y; pos.z += voxelData.voxels[index].position.z * voxelBase.importScale.z; vertices.Add(pos); } normals.AddRange(cubeNormals); for (int j = 0; j < cubeTriangles.Count; j++) { triangles[mat].Add(vOffset + cubeTriangles[j]); } for (int j = 0; j < cubeVertices.Count; j++) { colors.Add(color); } { Vector3 center = new Vector3 ( center.x = cubeCenter.x + voxelData.voxels[index].position.x * voxelBase.importScale.x, center.y = cubeCenter.y + voxelData.voxels[index].position.y * voxelBase.importScale.y, center.z = cubeCenter.z + voxelData.voxels[index].position.z * voxelBase.importScale.z ); var velocity = UnityEngine.Random.Range(explosionBase.edit_velocityMin, explosionBase.edit_velocityMax); for (int j = 0; j < cubeVertices.Count; j++) { tangents.Add(new Vector4(center.x - vertices[vOffset + j].x, center.y - vertices[vOffset + j].y, center.z - vertices[vOffset + j].z, velocity)); } } }; if (explosionObject.meshes == null) { explosionObject.meshes = new List <VoxelObjectExplosion.MeshData>(); } FlagTable3 doneTable = new FlagTable3(voxelData.voxelSize.x, voxelData.voxelSize.y, voxelData.voxelSize.z); for (int i = 1; i < voxelBase.materialData.Count; i++) { voxelBase.materialData[i].AllAction((pos) => { doneTable.Set(pos, true); var index = voxelData.VoxelTableContains(pos); if (index < 0) { return; } AddVertex(i, index); }); } for (int index = 0; index < voxelData.voxels.Length; index++) { if (doneTable.Get(voxelData.voxels[index].position)) { continue; } AddVertex(0, index); } if (vertices.Count > 0) { for (int i = explosionObject.meshes.Count; i <= meshIndex; i++) { explosionObject.meshes.Add(null); } explosionObject.meshes[meshIndex] = CreateMesh(explosionObject.meshes[meshIndex]); if (!AssetDatabase.Contains(explosionObject.meshes[meshIndex].mesh)) { voxelBaseCore.AddObjectToPrefabAsset(explosionObject.meshes[meshIndex].mesh, "explosion_mesh", meshIndex); } meshIndex++; } explosionObject.meshes.RemoveRange(meshIndex, explosionObject.meshes.Count - meshIndex); } #endregion #region Material if (explosionObject.materials == null) { explosionObject.materials = new List <Material>(); } if (explosionObject.materials.Count < voxelBase.materialData.Count) { for (int i = explosionObject.materials.Count; i < voxelBase.materialData.Count; i++) { explosionObject.materials.Add(null); } } else if (explosionObject.materials.Count > voxelBase.materialData.Count) { explosionObject.materials.RemoveRange(voxelBase.materialData.Count, explosionObject.materials.Count - voxelBase.materialData.Count); } for (int i = 0; i < voxelBase.materialData.Count; i++) { if (!voxelBase.materialIndexes.Contains(i)) { if (explosionObject.materials[i] != null) { explosionObject.materials[i] = null; voxelBaseCore.DestroyUnusedObjectInPrefabObject(); } continue; } if (explosionObject.materials[i] == null) { explosionObject.materials[i] = new Material(GetStandardShader(voxelBase.materialData[i].transparent)); } else { explosionObject.materials[i].shader = GetStandardShader(voxelBase.materialData[i].transparent); } if (!AssetDatabase.Contains(explosionObject.materials[i])) { explosionObject.materials[i].name = explosionObject.materials[i].shader.name; } if (!AssetDatabase.Contains(explosionObject.materials[i])) { voxelBaseCore.AddObjectToPrefabAsset(explosionObject.materials[i], "explosion_mat", i); } } #endregion }
public override void GenerateOnly() { if (voxelObject == null || voxelObjectCore.voxelData == null) { return; } var voxelData = voxelObjectCore.voxelData; //BasicCube Vector3 cubeCenter; List <Vector3> cubeVertices; List <Vector3> cubeNormals; List <int> cubeTriangles; CreateBasicCube(out cubeCenter, out cubeVertices, out cubeNormals, out cubeTriangles); #region Voxels List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Color> colors = new List <Color>(); List <Vector4> tangents = new List <Vector4>(); List <int>[] triangles = new List <int> [voxelBase.materialData.Count]; for (int i = 0; i < triangles.Length; i++) { triangles[i] = new List <int>(); } #region Mesh Func <VoxelBaseExplosion.MeshData, VoxelBaseExplosion.MeshData> CreateMesh = (data) => { if (data == null) { data = new VoxelObjectExplosion.MeshData(); } if (data.mesh == null) { data.mesh = new Mesh(); } else { data.mesh.Clear(false); data.mesh.ClearBlendShapes(); } data.materialIndexes.Clear(); #if UNITY_2017_3_OR_NEWER data.mesh.indexFormat = vertices.Count > 65000 ? UnityEngine.Rendering.IndexFormat.UInt32 : UnityEngine.Rendering.IndexFormat.UInt16; #endif data.mesh.vertices = vertices.ToArray(); data.mesh.normals = normals.ToArray(); data.mesh.colors = colors.ToArray(); data.mesh.tangents = tangents.ToArray(); { int materialCount = 0; for (int i = 0; i < triangles.Length; i++) { if (triangles[i].Count > 0) { materialCount++; } } data.mesh.subMeshCount = materialCount; int submesh = 0; for (int i = 0; i < triangles.Length; i++) { if (triangles[i].Count > 0) { data.materialIndexes.Add(i); data.mesh.SetTriangles(triangles[i].ToArray(), submesh++); } } } data.mesh.RecalculateBounds(); { var bounds = data.mesh.bounds; bounds.min -= Vector3.one * explosionBase.edit_velocityMax; bounds.max += Vector3.one * explosionBase.edit_velocityMax; data.mesh.bounds = bounds; } vertices.Clear(); normals.Clear(); colors.Clear(); tangents.Clear(); for (int i = 0; i < voxelBase.materialData.Count; i++) { triangles[i].Clear(); } return(data); }; #endregion { var chunkObjects = voxelObject.chunks; FlagTable3 doneTable = new FlagTable3(voxelData.voxelSize.x, voxelData.voxelSize.y, voxelData.voxelSize.z); for (int chunkIndex = 0; chunkIndex < chunkObjects.Length; chunkIndex++) { var chunkObject = chunkObjects[chunkIndex]; if (chunkObject == null) { explosionObject.chunksExplosion[chunkIndex] = null; continue; } var explosionChunk = explosionObject.chunksExplosion[chunkIndex] = chunkObject.gameObject.GetComponent <VoxelChunksObjectChunkExplosion>(); if (explosionChunk == null) { explosionChunk = explosionObject.chunksExplosion[chunkIndex] = Undo.AddComponent <VoxelChunksObjectChunkExplosion>(chunkObject.gameObject); } int meshIndex = 0; Action <int, int> AddVertex = (mat, index) => { if (explosionBase.edit_birthRate < 1f) { if (UnityEngine.Random.value >= explosionBase.edit_birthRate) { return; } } if (explosionBase.edit_visibleOnly) { if (!voxelObjectCore.IsVoxelVisible(voxelData.voxels[index].position)) { return; } } #if !UNITY_2017_3_OR_NEWER if (vertices.Count + cubeVertices.Count >= 65000) { for (int i = explosionChunk.meshes.Count; i <= meshIndex; i++) { explosionChunk.meshes.Add(null); } explosionChunk.meshes[meshIndex] = CreateMesh(explosionChunk.meshes[meshIndex]); { if (voxelBase.legacySubAssetNaming) { explosionChunk.meshes[meshIndex].mesh.name = string.Format("{0}_explosion_mesh{1}", explosionChunk.name, meshIndex); } else { explosionChunk.meshes[meshIndex].mesh.name = Path.GetFileNameWithoutExtension(voxelBase.voxelFilePath) + string.Format("_{0}_explosion_{1}", explosionChunk.name, meshIndex); } } if (!AssetDatabase.Contains(explosionChunk.meshes[meshIndex].mesh)) { voxelBaseCore.AddObjectToPrefabAsset(explosionChunk.meshes[meshIndex].mesh); } meshIndex++; } #endif var velocity = UnityEngine.Random.Range(explosionBase.edit_velocityMin, explosionBase.edit_velocityMax); var color = voxelData.palettes[voxelData.voxels[index].palette]; #if UNITY_2018_1_OR_NEWER if (EditorCommon.IsUniversalRenderPipeline() || EditorCommon.IsHighDefinitionRenderPipeline()) { color.a = velocity; } #endif var vOffset = vertices.Count; for (int i = 0; i < cubeVertices.Count; i++) { var pos = cubeVertices[i]; pos.x += voxelData.voxels[index].position.x * voxelBase.importScale.x; pos.y += voxelData.voxels[index].position.y * voxelBase.importScale.y; pos.z += voxelData.voxels[index].position.z * voxelBase.importScale.z; vertices.Add(pos); } normals.AddRange(cubeNormals); for (int j = 0; j < cubeTriangles.Count; j++) { triangles[mat].Add(vOffset + cubeTriangles[j]); } for (int j = 0; j < cubeVertices.Count; j++) { colors.Add(color); } { Vector3 center = new Vector3 ( center.x = cubeCenter.x + voxelData.voxels[index].position.x * voxelBase.importScale.x, center.y = cubeCenter.y + voxelData.voxels[index].position.y * voxelBase.importScale.y, center.z = cubeCenter.z + voxelData.voxels[index].position.z * voxelBase.importScale.z ); for (int j = 0; j < cubeVertices.Count; j++) { tangents.Add(new Vector4(center.x - vertices[vOffset + j].x, center.y - vertices[vOffset + j].y, center.z - vertices[vOffset + j].z, velocity)); } } }; if (explosionChunk.meshes == null) { explosionChunk.meshes = new List <VoxelBaseExplosion.MeshData>(); } for (int i = 1; i < voxelBase.materialData.Count; i++) { voxelBase.materialData[i].AllAction((pos) => { if (doneTable.Get(pos)) { return; } if (voxelData.chunkTable.Get(pos) != chunkObject.position) { return; } doneTable.Set(pos, true); var index = voxelData.VoxelTableContains(pos); if (index < 0) { return; } AddVertex(i, index); }); } for (int index = 0; index < voxelData.voxels.Length; index++) { var pos = voxelData.voxels[index].position; if (doneTable.Get(pos)) { continue; } if (voxelData.chunkTable.Get(pos) != chunkObject.position) { continue; } doneTable.Set(pos, true); AddVertex(0, index); } if (vertices.Count > 0) { for (int i = explosionChunk.meshes.Count; i <= meshIndex; i++) { explosionChunk.meshes.Add(null); } explosionChunk.meshes[meshIndex] = CreateMesh(explosionChunk.meshes[meshIndex]); if (!AssetDatabase.IsMainAsset(explosionChunk.meshes[meshIndex].mesh)) { if (voxelBase.legacyAssetNaming) { explosionChunk.meshes[meshIndex].mesh.name = string.Format("{0}_explosion_mesh{1}", explosionChunk.name, meshIndex); } else { explosionChunk.meshes[meshIndex].mesh.name = Path.GetFileNameWithoutExtension(voxelBase.voxelFilePath) + string.Format("_{0}_explosion_{1}", explosionChunk.name, meshIndex); } } if (!AssetDatabase.Contains(explosionChunk.meshes[meshIndex].mesh)) { voxelBaseCore.AddObjectToPrefabAsset(explosionChunk.meshes[meshIndex].mesh); } meshIndex++; } explosionChunk.meshes.RemoveRange(meshIndex, explosionChunk.meshes.Count - meshIndex); explosionChunk.chunkBasicOffset = chunkObject.basicOffset; } } #endregion #region Material explosionObject.materialMode = voxelObject.materialMode; if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Combine) { if (explosionObject.materials == null) { explosionObject.materials = new List <Material>(); } if (explosionObject.materials.Count < voxelBase.materialData.Count) { for (int i = explosionObject.materials.Count; i < voxelBase.materialData.Count; i++) { explosionObject.materials.Add(null); } } else if (explosionObject.materials.Count > voxelBase.materialData.Count) { explosionObject.materials.RemoveRange(voxelBase.materialData.Count, explosionObject.materials.Count - voxelBase.materialData.Count); } for (int i = 0; i < explosionObject.chunksExplosion.Length; i++) { explosionObject.chunksExplosion[i].materials = null; } for (int i = 0; i < voxelBase.materialData.Count; i++) { if (!voxelBase.materialIndexes.Contains(i)) { if (explosionObject.materials[i] != null) { explosionObject.materials[i] = null; voxelBaseCore.DestroyUnusedObjectInPrefabObject(); } continue; } if (explosionObject.materials[i] == null) { explosionObject.materials[i] = new Material(GetStandardShader(voxelBase.materialData[i].transparent)); } else { explosionObject.materials[i].shader = GetStandardShader(voxelBase.materialData[i].transparent); } if (!AssetDatabase.Contains(explosionObject.materials[i])) { explosionObject.materials[i].name = explosionObject.materials[i].shader.name; } if (!AssetDatabase.IsMainAsset(explosionObject.materials[i])) { if (voxelBase.legacyAssetNaming) { explosionObject.materials[i].name = string.Format("explosion_mat{0}", i); } else { explosionObject.materials[i].name = Path.GetFileNameWithoutExtension(voxelBase.voxelFilePath) + string.Format("_explosion_{0}", i); } } if (!AssetDatabase.Contains(explosionObject.materials[i])) { voxelBaseCore.AddObjectToPrefabAsset(explosionObject.materials[i]); } } } else if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Individual) { explosionObject.materials = null; for (int chunkIndex = 0; chunkIndex < explosionObject.chunksExplosion.Length; chunkIndex++) { var explosionChunk = explosionObject.chunksExplosion[chunkIndex]; if (explosionChunk.materials == null) { explosionChunk.materials = new List <Material>(); } if (explosionChunk.materials.Count < voxelBase.materialData.Count) { for (int i = explosionChunk.materials.Count; i < voxelBase.materialData.Count; i++) { explosionChunk.materials.Add(null); } } else if (explosionChunk.materials.Count > voxelBase.materialData.Count) { explosionChunk.materials.RemoveRange(voxelBase.materialData.Count, explosionChunk.materials.Count - voxelBase.materialData.Count); } for (int i = 0; i < voxelBase.materialData.Count; i++) { if (!voxelObject.chunks[chunkIndex].materialIndexes.Contains(i)) { if (explosionChunk.materials[i] != null) { explosionChunk.materials[i] = null; voxelBaseCore.DestroyUnusedObjectInPrefabObject(); } continue; } if (explosionChunk.materials[i] == null) { explosionChunk.materials[i] = new Material(GetStandardShader(voxelBase.materialData[i].transparent)); } else { explosionChunk.materials[i].shader = GetStandardShader(voxelBase.materialData[i].transparent); } if (!AssetDatabase.Contains(explosionChunk.materials[i])) { explosionChunk.materials[i].name = explosionChunk.materials[i].shader.name; } if (!AssetDatabase.IsMainAsset(explosionChunk.materials[i])) { if (voxelBase.legacyAssetNaming) { explosionChunk.materials[i].name = string.Format("{0}_explosion_mat{1}", explosionChunk.name, i); } else { explosionChunk.materials[i].name = Path.GetFileNameWithoutExtension(voxelBase.voxelFilePath) + string.Format("_{0}_explosion_{1}", explosionChunk.name, i); } } if (!AssetDatabase.Contains(explosionChunk.materials[i])) { voxelBaseCore.AddObjectToPrefabAsset(explosionChunk.materials[i]); } } } } else { Assert.IsTrue(false); } #endregion }
public List <IntVector3> GetFillVoxel(IntVector3 pos) { if (objectTarget.voxelData == null) { return(null); } if (objectTarget.voxelData.VoxelTableContains(pos) < 0) { return(null); } if (fillVoxelTable == null) { fillVoxelTable = new DataTable3 <List <IntVector3> >(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z); } if (!fillVoxelTable.Contains(pos)) { List <IntVector3> searchList = new List <IntVector3>(); for (int i = 0; i < objectTarget.voxelData.voxels.Length; i++) { int posPalette = 0; var doneTable = new FlagTable3(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z); { var p = objectTarget.voxelData.voxels[i].position; if (fillVoxelTable.Get(p) != null) { continue; } var index = objectTarget.voxelData.VoxelTableContains(p); posPalette = objectTarget.voxelData.voxels[index].palette; searchList.Clear(); searchList.Add(p); doneTable.Set(p, true); } var result = new List <IntVector3>(); for (int j = 0; j < searchList.Count; j++) { var p = searchList[j]; var index = objectTarget.voxelData.VoxelTableContains(p); if (index < 0) { continue; } if (objectTarget.voxelData.voxels[index].palette == posPalette) { result.Add(p); for (int x = p.x - 1; x <= p.x + 1; x++) { for (int y = p.y - 1; y <= p.y + 1; y++) { for (int z = p.z - 1; z <= p.z + 1; z++) { if (x >= 0 && y >= 0 && z >= 0 && x < objectTarget.voxelData.voxelSize.x && y < objectTarget.voxelData.voxelSize.y && z < objectTarget.voxelData.voxelSize.z && !doneTable.Get(x, y, z)) { doneTable.Set(x, y, z, true); var indexTmp = objectTarget.voxelData.VoxelTableContains(x, y, z); if (indexTmp >= 0 && objectTarget.voxelData.voxels[indexTmp].palette == posPalette) { searchList.Add(new IntVector3(x, y, z)); } } } } } } } for (int j = 0; j < result.Count; j++) { fillVoxelTable.Set(result[j], result); } } } var fillVoxel = fillVoxelTable.Get(pos); return(fillVoxel); }
public Dictionary <IntVector3, VoxelBase.Face> GetSelectionRectVoxelFace() { Dictionary <IntVector3, VoxelBase.Face> result = new Dictionary <IntVector3, VoxelBase.Face>(); if (selectionRect.Enable && objectTarget.voxelData != null && objectTarget.voxelData.vertexList != null) { var localToWorldMatrix = objectTarget.transform.localToWorldMatrix; FlagTable3 containsTable = new FlagTable3(objectTarget.voxelData.voxelSize.x + 1, objectTarget.voxelData.voxelSize.y + 1, objectTarget.voxelData.voxelSize.z + 1); for (int i = 0; i < objectTarget.voxelData.vertexList.Count; i++) { var local = objectCore.GetVoxelRatePosition(objectTarget.voxelData.vertexList[i], Vector3.zero); var world = localToWorldMatrix.MultiplyPoint3x4(local); var screen = HandleUtility.WorldToGUIPoint(world); if (selectionRect.rect.Contains(screen)) { containsTable.Set(objectTarget.voxelData.vertexList[i], true); } } containsTable.AllAction((x, y, z) => { Action <int, int, int, VoxelBase.Face> AddFace = (xx, yy, zz, face) => { var pos = new IntVector3(xx, yy, zz); var index = objectTarget.voxelData.VoxelTableContains(pos); if (index < 0) { return; } if ((objectTarget.voxelData.voxels[index].visible & face) == 0) { return; } VoxelBase.Face combineFace; if (!result.TryGetValue(pos, out combineFace)) { result.Add(pos, face); } else { combineFace |= face; result[pos] = combineFace; } }; #region Left if (containsTable.Get(x, y + 1, z) && containsTable.Get(x, y, z + 1) && containsTable.Get(x, y + 1, z + 1)) { AddFace(x, y, z, VoxelBase.Face.left); AddFace(x - 1, y, z, VoxelBase.Face.right); } #endregion #region Down if (containsTable.Get(x + 1, y, z) && containsTable.Get(x, y, z + 1) && containsTable.Get(x + 1, y, z + 1)) { AddFace(x, y, z, VoxelBase.Face.down); AddFace(x, y - 1, z, VoxelBase.Face.up); } #endregion #region Back if (containsTable.Get(x + 1, y, z) && containsTable.Get(x, y + 1, z) && containsTable.Get(x + 1, y + 1, z)) { AddFace(x, y, z, VoxelBase.Face.back); AddFace(x, y, z - 1, VoxelBase.Face.forward); } #endregion }); } return(result); }
public List <IntVector3> GetFillVoxelFace(IntVector3 pos, VoxelBase.Face face) { if (objectTarget.voxelData == null) { return(null); } if (objectTarget.voxelData.VoxelTableContains(pos) < 0) { return(null); } CheckFillVoxelTableCheck(); if (fillVoxelFaceTable == null) { fillVoxelFaceTable = new DataTable3 <Dictionary <int, List <IntVector3> > >(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z); } if (!fillVoxelFaceTable.Contains(pos) || !fillVoxelFaceTable.Get(pos).ContainsKey((int)face)) { List <IntVector3> searchList = new List <IntVector3>(); var doneTable = new FlagTable3(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z); { searchList.Clear(); searchList.Add(pos); doneTable.Set(pos, true); } var result = new List <IntVector3>(); for (int j = 0; j < searchList.Count; j++) { var p = searchList[j]; var index = objectTarget.voxelData.VoxelTableContains(p); if (index < 0) { continue; } if ((objectTarget.voxelData.voxels[index].visible & face) != 0) { result.Add(p); int xOffset = (face & (VoxelBase.Face.up | VoxelBase.Face.down | VoxelBase.Face.forward | VoxelBase.Face.back)) != 0 ? 1 : 0; int yOffset = (face & (VoxelBase.Face.right | VoxelBase.Face.left | VoxelBase.Face.forward | VoxelBase.Face.back)) != 0 ? 1 : 0; int zOffset = (face & (VoxelBase.Face.right | VoxelBase.Face.left | VoxelBase.Face.up | VoxelBase.Face.down)) != 0 ? 1 : 0; for (int x = p.x - xOffset; x <= p.x + xOffset; x++) { for (int y = p.y - yOffset; y <= p.y + yOffset; y++) { for (int z = p.z - zOffset; z <= p.z + zOffset; z++) { if (x >= 0 && y >= 0 && z >= 0 && x < objectTarget.voxelData.voxelSize.x && y < objectTarget.voxelData.voxelSize.y && z < objectTarget.voxelData.voxelSize.z && !doneTable.Get(x, y, z)) { doneTable.Set(x, y, z, true); var indexTmp = objectTarget.voxelData.VoxelTableContains(x, y, z); if (indexTmp >= 0) { searchList.Add(new IntVector3(x, y, z)); } } } } } } } Dictionary <int, List <IntVector3> > data; if (fillVoxelFaceTable.Contains(pos)) { data = fillVoxelFaceTable.Get(pos); } else { data = new Dictionary <int, List <IntVector3> >(); } data[(int)face] = result; fillVoxelFaceTable.Set(pos, data); for (int j = 0; j < result.Count; j++) { if (fillVoxelFaceTable.Contains(result[j])) { data = fillVoxelFaceTable.Get(result[j]); } else { data = new Dictionary <int, List <IntVector3> >(); } data[(int)face] = result; fillVoxelFaceTable.Set(result[j], data); } } var fillVoxel = fillVoxelFaceTable.Get(pos)[(int)face]; return(fillVoxel); }