public MeshAndColors createMesh(VoxelModelChunk voxelChunk, ShapeNodeChunk shape) { Vector3 ve = rotateVector(new Vector3(voxelChunk.sizeChunk.sizeX, voxelChunk.sizeChunk.sizeY, voxelChunk.sizeChunk.sizeZ), shape.transform); int sizeX = (int)Math.Abs(ve.x); int sizeY = (int)Math.Abs(ve.y); int sizeZ = (int)Math.Abs(ve.z); // WTF? Dont drink and code!!! Vector3 correction = new Vector3((ve.x < 0) ? Math.Abs(ve.x) - 1 : 0, (ve.y < 0) ? Math.Abs(ve.y) - 1 : 0, (ve.z < 0) ? Math.Abs(ve.z) - 1 : 0); RenderVoxel[,,] voxelArray = new RenderVoxel[sizeX, sizeY, sizeZ]; float maxX = 0; float maxY = 0; float maxZ = 0; float minX = sizeX; float minY = sizeY; float minZ = sizeZ; foreach (Voxel voxel in voxelChunk.voxels) { Vector3 rotVec = rotateVector(new Vector3(voxel.x, voxel.y, voxel.z), shape.transform) + correction; voxelArray[(int)rotVec.x, (int)rotVec.y, (int)rotVec.z] = new RenderVoxel(voxel.colorIndex); if (rotVec.x < minX) { minX = rotVec.x; } if (rotVec.y < minY) { minY = rotVec.y; } if (rotVec.z < minZ) { minZ = rotVec.z; } if (rotVec.x > maxX) { maxX = rotVec.x; } if (rotVec.y > maxY) { maxY = rotVec.y; } if (rotVec.z > maxZ) { maxZ = rotVec.z; } } shape.singleCenter = new Vector3((float)Math.Ceiling(minX + (maxX - minX) / 2f), minZ, (float)Math.Ceiling(minY + (maxY - minY) / 2f)); Vector3 shifts = shape.singleCenter; MeshAndColors meshAndColors = createMeshFromVoxelArray(voxelArray, shifts); return(meshAndColors); }
void Run() { string[] splits = input.Split(' '); size = new Vector3Int( Convert.ToInt32(splits[3] + splits[2] + splits[1] + splits[0], 16), Convert.ToInt32(splits[7] + splits[6] + splits[5] + splits[4], 16), Convert.ToInt32(splits[11] + splits[10] + splits[9] + splits[8], 16)); RenderVoxel[,,] voxelArray = new RenderVoxel[size.x, size.y, size.z]; int x = 0; int y = 0; int z = 0; for (int i = 16; i < splits.Length; i += 2) { int n = Convert.ToInt32(splits[i], 16) + 1; int color = Convert.ToInt32(splits[i + 1], 16); for (int k = 0; k < n; k++) { x++; if (x == size.x) { y++; x = 0; if (y == size.y) { y = 0; z++; } } if (color == 0) { continue; } if (z >= size.z) { break; } voxelArray[x, y, z] = new RenderVoxel(color); } } MagicaRenderer renderer = new MagicaRenderer(); MeshAndColors meshAndColors = renderer.createMeshFromVoxelArray(voxelArray, Vector3.zero); GameObject go = new GameObject(); Color32[] colors = new Color32[meshAndColors.colors.Count]; for (int i = 0; i < meshAndColors.colors.Count; i++) { int c = meshAndColors.colors[i]; colors[i] = new Color(c / 256f, c / 256f, c / 256f, 1); } meshAndColors.mesh.colors32 = colors; (go.AddComponent <MeshFilter>()).mesh = meshAndColors.mesh; (go.AddComponent <MeshRenderer>()).material = Resources.Load("VertexShading", typeof(Material)) as Material; }
public MeshAndColors createMeshFromVoxelArray(RenderVoxel[,,] voxelArray, Vector3 shifts) { // gravity first for (int z = 0; z < voxelArray.GetLength(2); z++) { for (int y = 0; y < voxelArray.GetLength(1); y++) { for (int x = 0; x < voxelArray.GetLength(0); x++) { if (voxelArray[x, y, z] == null) { continue; } if (x > 0 && voxelArray[x - 1, y, z] != null) { voxelArray[x, y, z].sides ^= RenderVoxel.LEFT; voxelArray[x - 1, y, z].sides ^= RenderVoxel.RIGHT; } if (y > 0 && voxelArray[x, y - 1, z] != null) { voxelArray[x, y, z].sides ^= RenderVoxel.BACK; voxelArray[x, y - 1, z].sides ^= RenderVoxel.FRONT; } if (z > 0 && voxelArray[x, y, z - 1] != null) { voxelArray[x, y, z].sides ^= RenderVoxel.DOWN; voxelArray[x, y, z - 1].sides ^= RenderVoxel.UP; } } } } List <int> colors; Mesh mesh; List <Vector3> vertices = new List <Vector3>(); List <int> triangles = new List <int>(); List <int> colorOrder = new List <int>(); colors = new List <int>(); for (int _z = 0; _z < voxelArray.GetLength(2); _z++) { for (int _y = 0; _y < voxelArray.GetLength(1); _y++) { for (int _x = 0; _x < voxelArray.GetLength(0); _x++) { RenderVoxel renderVoxel = voxelArray[_x, _y, _z]; if (renderVoxel == null || renderVoxel.sides == 0) { continue; } float x = _x - shifts.x; float y = _y - shifts.z; float z = _z - shifts.y; if (!colorOrder.Contains(renderVoxel.color)) { colorOrder.Add(renderVoxel.color); } if ((renderVoxel.sides & RenderVoxel.DOWN) != 0) { int startIndex = vertices.Count; vertices.Add(new Vector3(x * size, z * size, y * size)); vertices.Add(new Vector3((x + 1) * size, z * size, y * size)); vertices.Add(new Vector3(x * size, z * size, (y + 1) * size)); vertices.Add(new Vector3((x + 1) * size, z * size, (y + 1) * size)); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); triangles.Add(startIndex); triangles.Add(startIndex + 1); triangles.Add(startIndex + 2); triangles.Add(startIndex + 1); triangles.Add(startIndex + 3); triangles.Add(startIndex + 2); } if ((renderVoxel.sides & RenderVoxel.UP) != 0) { int startIndex = vertices.Count; vertices.Add(new Vector3(x * size, (z + 1) * size, y * size)); vertices.Add(new Vector3((x + 1) * size, (z + 1) * size, y * size)); vertices.Add(new Vector3(x * size, (z + 1) * size, (y + 1) * size)); vertices.Add(new Vector3((x + 1) * size, (z + 1) * size, (y + 1) * size)); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); triangles.Add(startIndex); triangles.Add(startIndex + 2); triangles.Add(startIndex + 1); triangles.Add(startIndex + 2); triangles.Add(startIndex + 3); triangles.Add(startIndex + 1); } if ((renderVoxel.sides & RenderVoxel.LEFT) != 0) { int startIndex = vertices.Count; vertices.Add(new Vector3(x * size, z * size, y * size)); vertices.Add(new Vector3(x * size, z * size, (y + 1) * size)); vertices.Add(new Vector3(x * size, (z + 1) * size, (y + 1) * size)); vertices.Add(new Vector3(x * size, (z + 1) * size, y * size)); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); triangles.Add(startIndex); triangles.Add(startIndex + 1); triangles.Add(startIndex + 2); triangles.Add(startIndex + 2); triangles.Add(startIndex + 3); triangles.Add(startIndex); } if ((renderVoxel.sides & RenderVoxel.RIGHT) != 0) { int startIndex = vertices.Count; vertices.Add(new Vector3((x + 1) * size, z * size, y * size)); vertices.Add(new Vector3((x + 1) * size, z * size, (y + 1) * size)); vertices.Add(new Vector3((x + 1) * size, (z + 1) * size, (y + 1) * size)); vertices.Add(new Vector3((x + 1) * size, (z + 1) * size, y * size)); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); triangles.Add(startIndex); triangles.Add(startIndex + 3); triangles.Add(startIndex + 2); triangles.Add(startIndex + 2); triangles.Add(startIndex + 1); triangles.Add(startIndex); } if ((renderVoxel.sides & RenderVoxel.BACK) != 0) { int startIndex = vertices.Count; vertices.Add(new Vector3(x * size, z * size, y * size)); vertices.Add(new Vector3(x * size, (z + 1) * size, y * size)); vertices.Add(new Vector3((x + 1) * size, (z + 1) * size, y * size)); vertices.Add(new Vector3((x + 1) * size, z * size, y * size)); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); triangles.Add(startIndex); triangles.Add(startIndex + 1); triangles.Add(startIndex + 2); triangles.Add(startIndex + 2); triangles.Add(startIndex + 3); triangles.Add(startIndex); } if ((renderVoxel.sides & RenderVoxel.FRONT) != 0) { int startIndex = vertices.Count; vertices.Add(new Vector3(x * size, z * size, (y + 1) * size)); vertices.Add(new Vector3(x * size, (z + 1) * size, (y + 1) * size)); vertices.Add(new Vector3((x + 1) * size, (z + 1) * size, (y + 1) * size)); vertices.Add(new Vector3((x + 1) * size, z * size, (y + 1) * size)); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); colors.Add(renderVoxel.color); triangles.Add(startIndex); triangles.Add(startIndex + 3); triangles.Add(startIndex + 2); triangles.Add(startIndex + 2); triangles.Add(startIndex + 1); triangles.Add(startIndex); } } } } mesh = new Mesh(); mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; mesh.vertices = vertices.ToArray(); mesh.triangles = triangles.ToArray(); mesh.RecalculateNormals(); MeshAndColors meshAndColors = new MeshAndColors(); meshAndColors.mesh = mesh; meshAndColors.colors = colors; return(meshAndColors); }
public GameObject ImportMagicaVoxelFileAssets(string path) { GameObject levelGo = new GameObject(Path.GetFileName(path)); string fileName = Path.GetFileName(path); List <GameObject> gameObjects = new List <GameObject>(); Dictionary <string, GameObject> namedGameObjects = new Dictionary <string, GameObject>(); Chunk mainChunk = MagicaVoxelReader.ReadMagicaChunks(path); List <Material> colorMaterials = ImportColors(mainChunk); List <string> names = new List <string>(); List <string> doubleNames = new List <string>(); string localPath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine("Assets", "ImportedPrefabs", fileName)); string materialFolder = Path.Combine("Assets", "ImportedPrefabs", fileName, "Materials"); string meshFolder = Path.Combine("Assets", "ImportedPrefabs", fileName, "Meshes"); if (!AssetDatabase.IsValidFolder(localPath)) { AssetDatabase.CreateFolder(Path.Combine("Assets", "ImportedPrefabs"), fileName); } if (!AssetDatabase.IsValidFolder(materialFolder)) { AssetDatabase.CreateFolder(localPath, "Materials"); } if (!AssetDatabase.IsValidFolder(meshFolder)) { AssetDatabase.CreateFolder(localPath, "Meshes"); } for (int m = 0; m < colorMaterials.Count; m++) { AssetDatabase.CreateAsset(colorMaterials[m], Path.Combine(materialFolder, "Color_" + m + ".mat")); } for (int i = 0; i < mainChunk.children.Count; i++) { Chunk chunk = mainChunk.children[i]; if (chunk is VoxelModelChunk) { VoxelModelChunk voxelChunk = (VoxelModelChunk)chunk; foreach (ShapeNodeChunk shape in voxelChunk.shapes) { TransformNodeChunk transformNodeChunk = shape.transform; bool isPotentialAsset = false; while (transformNodeChunk != null) { if (transformNodeChunk.attributes.Count > 0 && transformNodeChunk.attributes.ContainsKey("_name")) { isPotentialAsset = true; break; } } if (!isPotentialAsset) { continue; } MeshAndColors meshAndColors = createMesh(voxelChunk, shape); List <Material> materials = new List <Material>(); foreach (int color in meshAndColors.colors) { materials.Add(colorMaterials[color - 1]); } GameObject go = new GameObject(); gameObjects.Add(go); ObjectAttributes script = go.AddComponent <ObjectAttributes>(); MeshRenderer renderer = go.AddComponent <MeshRenderer>(); renderer.materials = materials.ToArray(); MeshFilter filter = go.AddComponent <MeshFilter>(); filter.mesh = meshAndColors.mesh; Vector3 shift = Vector3.zero; //new Vector3(script.singleCenter.x, 0, script.singleCenter.y); while (transformNodeChunk != null) { if (transformNodeChunk.attributes.Count > 0 && transformNodeChunk.attributes.ContainsKey("_name")) { string name = transformNodeChunk.attributes["_name"]; script.names.Add(name); if (names.Contains(name)) { if (!doubleNames.Contains(name)) { doubleNames.Add(name); } } else { names.Add(name); namedGameObjects.Add(name, go); } } if (transformNodeChunk.frameAttributes[0].ContainsKey("_r")) { script.rotations.Add(transformNodeChunk.frameAttributes[0]["_r"]); } Vector3[] rotationMatrix = getRotationMatrix(transformNodeChunk); script.rotationMatrices.Add(rotationMatrix); if (transformNodeChunk.frameAttributes[0].ContainsKey("_t")) { string[] coords = transformNodeChunk.frameAttributes[0]["_t"].Split(' '); Vector3 currentShift = new Vector3(float.Parse(coords[0]) / 10f, float.Parse(coords[2]) / 10f, float.Parse(coords[1]) / 10f);; script.magicaTransitions.Add(currentShift); shift += currentShift; } if (transformNodeChunk.group != null && transformNodeChunk.group.transform != null) { transformNodeChunk = transformNodeChunk.group.transform; } else { transformNodeChunk = null; } } Vector3 ve = rotateVector(new Vector3(voxelChunk.sizeChunk.sizeX, voxelChunk.sizeChunk.sizeY, voxelChunk.sizeChunk.sizeZ), shape.transform); script.magicaTotalSize = new Vector3(Math.Abs(ve.x), Math.Abs(ve.z), Math.Abs(ve.y)); script.bottomCenterOfVoxelMass = shape.singleCenter / 10f; script.centerOfMagicaMass = new Vector3((float)Math.Floor((double)(Math.Abs(ve.x) / 2f)) / 10f, (float)Math.Floor((double)(Math.Abs(ve.z) / 2f)) / 10f, (float)Math.Floor((double)(Math.Abs(ve.y) / 2f)) / 10f); script.parentVoxFile = Path.GetFileName(path); //shift -= script.trans; shift += new Vector3(script.bottomCenterOfVoxelMass.x - script.centerOfMagicaMass.x, script.bottomCenterOfVoxelMass.y - script.centerOfMagicaMass.y, script.bottomCenterOfVoxelMass.z - script.centerOfMagicaMass.z); //shift += (script.bottomCenterOfVoxelMass - script.centerOfMagicaMass); go.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f); go.transform.position = shift; go.name = script.names[0]; go.transform.parent = levelGo.transform; } } } // remove double named objects since we cannot insert them properly foreach (string name in doubleNames) { namedGameObjects.Remove(name); } foreach (GameObject g in namedGameObjects.Values) { TeardownProperties teardownProperties = g.AddComponent <TeardownProperties>(); // Create the new Prefab. AssetDatabase.CreateAsset(g.GetComponent <MeshFilter>().sharedMesh, Path.Combine(meshFolder, g.name.Replace(" ", "_") + ".mesh")); AssetDatabase.SaveAssets(); PrefabUtility.SaveAsPrefabAssetAndConnect(g, Path.Combine("Assets", "ImportedPrefabs", fileName, g.name.Replace(" ", "_") + ".prefab"), InteractionMode.UserAction); } PrefabUtility.SaveAsPrefabAssetAndConnect(levelGo, Path.Combine("Assets", "ImportedPrefabs", fileName, fileName + ".prefab"), InteractionMode.UserAction); return(levelGo); }
public GameObject ImportMagicaVoxelFile(string path) { Material vertexMaterial = Resources.Load("VertexShading", typeof(Material)) as Material; GameObject levelGo = new GameObject(Path.GetFileName(path)); levelGo.AddComponent <TeardownProperties>(); MagicaImportedFile magicaImportedFile = levelGo.AddComponent <MagicaImportedFile>(); magicaImportedFile.voxFile = Path.GetFileName(path); List <GameObject> gameObjects = new List <GameObject>(); Dictionary <string, GameObject> namedGameObjects = new Dictionary <string, GameObject>(); Chunk mainChunk = MagicaVoxelReader.ReadMagicaChunks(path); List <Material> colorMaterials = ImportColors(mainChunk); List <string> names = new List <string>(); List <string> doubleNames = new List <string>(); for (int i = 0; i < mainChunk.children.Count; i++) { Chunk chunk = mainChunk.children[i]; if (chunk is VoxelModelChunk) { VoxelModelChunk voxelChunk = (VoxelModelChunk)chunk; foreach (ShapeNodeChunk shape in voxelChunk.shapes) { MeshAndColors meshAndColors = createMesh(voxelChunk, shape); Color[] colors = new Color[meshAndColors.colors.Count]; for (int c = 0; c < meshAndColors.colors.Count; c++) { colors[c] = colorMaterials[meshAndColors.colors[c] - 1].color; } meshAndColors.mesh.colors = colors; TransformNodeChunk transformNodeChunk = shape.transform; GameObject go = new GameObject(); gameObjects.Add(go); ObjectAttributes script = go.AddComponent <ObjectAttributes>(); MeshRenderer renderer = go.AddComponent <MeshRenderer>(); renderer.material = vertexMaterial; MeshFilter filter = go.AddComponent <MeshFilter>(); filter.mesh = meshAndColors.mesh; Vector3 shift = Vector3.zero; //new Vector3(script.singleCenter.x, 0, script.singleCenter.y); while (transformNodeChunk != null) { if (transformNodeChunk.attributes.Count > 0 && transformNodeChunk.attributes.ContainsKey("_name")) { string name = transformNodeChunk.attributes["_name"]; script.names.Add(name); if (names.Contains(name)) { if (!doubleNames.Contains(name)) { doubleNames.Add(name); } } else { names.Add(name); namedGameObjects.Add(name, go); } } if (transformNodeChunk.frameAttributes[0].ContainsKey("_r")) { script.rotations.Add(transformNodeChunk.frameAttributes[0]["_r"]); } Vector3[] rotationMatrix = getRotationMatrix(transformNodeChunk); script.rotationMatrices.Add(rotationMatrix); if (transformNodeChunk.frameAttributes[0].ContainsKey("_t")) { string[] coords = transformNodeChunk.frameAttributes[0]["_t"].Split(' '); Vector3 currentShift = new Vector3(float.Parse(coords[0]) / 10f, float.Parse(coords[2]) / 10f, float.Parse(coords[1]) / 10f);; script.magicaTransitions.Add(currentShift); shift += currentShift; } if (transformNodeChunk.group != null && transformNodeChunk.group.transform != null) { transformNodeChunk = transformNodeChunk.group.transform; } else { transformNodeChunk = null; } } Vector3 ve = rotateVector(new Vector3(voxelChunk.sizeChunk.sizeX, voxelChunk.sizeChunk.sizeY, voxelChunk.sizeChunk.sizeZ), shape.transform); script.magicaTotalSize = new Vector3(Math.Abs(ve.x), Math.Abs(ve.z), Math.Abs(ve.y)); script.bottomCenterOfVoxelMass = shape.singleCenter / 10f; script.centerOfMagicaMass = new Vector3((float)Math.Floor((double)(Math.Abs(ve.x) / 2f)) / 10f, (float)Math.Floor((double)(Math.Abs(ve.z) / 2f)) / 10f, (float)Math.Floor((double)(Math.Abs(ve.y) / 2f)) / 10f); script.parentVoxFile = Path.GetFileName(path); //shift -= script.trans; shift += new Vector3(script.bottomCenterOfVoxelMass.x - script.centerOfMagicaMass.x, script.bottomCenterOfVoxelMass.y - script.centerOfMagicaMass.y, script.bottomCenterOfVoxelMass.z - script.centerOfMagicaMass.z); //shift += (script.bottomCenterOfVoxelMass - script.centerOfMagicaMass); go.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f); go.transform.position = shift; go.transform.parent = levelGo.transform; if (script.names.Count > 0) { go.name = script.names[0]; } } } } // remove double named objects since we cannot insert them properly foreach (string name in doubleNames) { namedGameObjects.Remove(name); } foreach (GameObject g in gameObjects) { if (namedGameObjects.Values.Contains(g)) { TeardownProperties teardownProperties = g.AddComponent <TeardownProperties>(); } } return(levelGo); }