public static void CombineVoxels(MVVoxModelVoxel[] voxels) { if (voxels != null && voxels.Length > 0) { MVVoxelChunk chunk = new MVVoxelChunk (); MVVoxModel model = voxels [0].parentVoxModel; MVVoxelChunk origChunk = model.vox.voxelChunk; chunk.voxels = new byte[origChunk.sizeX, origChunk.sizeY, origChunk.sizeZ]; foreach (MVVoxModelVoxel v in voxels) { chunk.voxels [v.voxel.x, v.voxel.y, v.voxel.z] = v.voxel.colorIndex; } MVImporter.GenerateFaces(chunk, model.vox.alphaMaskChunk); Mesh[] meshes = MVImporter.CreateMeshesFromChunk(chunk, model.vox.palatte, model.sizePerVox, model.vox.alphaMaskChunk); if (meshes.Length > 1) { Debug.LogError ("[MVCombine] Currently does not support combining voxels into multiple meshes, please reduce the number of voxels you are trying to combine"); return; } Material mat = (model.voxMaterial != null) ? model.voxMaterial : MVImporter.DefaultMaterial; int index = 0; foreach (Mesh mesh in meshes) { GameObject go = MVImporter.CreateGameObject (model.gameObject.transform, Vector3.zero, string.Format ("VoxMesh ({0})", index), mesh, mat); MVVoxModelMesh voxMesh = go.AddComponent<MVVoxModelMesh> (); voxMesh.voxels = voxels.Select( o => o.voxel ).ToArray(); Selection.activeGameObject = go; index++; } foreach (MVVoxModelVoxel v in voxels) { GameObject.DestroyImmediate (v.gameObject); } } else { Debug.LogError("[MVCombine] Invalid voxels"); } }
public static Mesh[] CreateMeshesFromChunk(MVVoxelChunk chunk, Color[] palatte, float sizePerVox, MVVoxelChunk alphaMask) { Vector3 origin = new Vector3( (float)chunk.sizeX / 2, (float)chunk.sizeY / 2, (float)chunk.sizeZ / 2); return(CreateMeshesFromChunk(chunk, palatte, sizePerVox, alphaMask, origin)); }
public static GameObject[] CreateVoxelGameObjectsForChunk(MVVoxelChunk chunk, Color[] palatte, Transform parent, Material mat, float sizePerVox, MVVoxelChunk alphaMask, Vector3 origin) { List <GameObject> result = new List <GameObject> (); Mesh[] meshes = CreateMeshesFromChunk(chunk, palatte, sizePerVox, alphaMask, origin); int index = 0; foreach (Mesh mesh in meshes) { GameObject go = new GameObject(); go.name = string.Format("VoxelMesh ({0})", index); go.transform.SetParent(parent); go.transform.localPosition = Vector3.zero; go.transform.localRotation = Quaternion.Euler(Vector3.zero); go.transform.localScale = Vector3.one; MeshFilter mf = go.AddComponent <MeshFilter> (); mf.mesh = mesh; MeshRenderer mr = go.AddComponent <MeshRenderer> (); mr.material = mat; go.AddComponent <MVVoxModelMesh> (); result.Add(go); index++; } return(result.ToArray()); }
public static GameObject[] CreateVoxelGameObjectsForChunk(MVVoxelChunk chunk, Color[] palatte, Transform parent, Material mat, float sizePerVox, MVVoxelChunk alphaMask) { Vector3 origin = new Vector3( (float)chunk.sizeX / 2, (float)chunk.sizeY / 2, (float)chunk.sizeZ / 2); return(CreateVoxelGameObjectsForChunk(chunk, palatte, parent, mat, sizePerVox, alphaMask, origin)); }
public static GameObject[] CreateIndividualVoxelGameObjectsForChunk(MVVoxelChunk chunk, Color[] palatte, Transform parent, Material mat, float sizePerVox, MVVoxelChunk alphaMask, Vector3 origin) { List <GameObject> result = new List <GameObject> (); if (alphaMask != null && (alphaMask.sizeX != chunk.sizeX || alphaMask.sizeY != chunk.sizeY || alphaMask.sizeZ != chunk.sizeZ)) { Debug.LogErrorFormat("Unable to create meshes from chunk : Chunk's size ({0},{1},{2}) differs from alphaMask chunk's size ({3},{4},{5})", chunk.sizeX, chunk.sizeY, chunk.sizeZ, alphaMask.sizeX, alphaMask.sizeY, alphaMask.sizeZ); return(result.ToArray()); } for (int x = 0; x < chunk.sizeX; ++x) { for (int y = 0; y < chunk.sizeY; ++y) { for (int z = 0; z < chunk.sizeZ; ++z) { if (chunk.voxels [x, y, z] != 0) { float px = (x - origin.x + 0.5f) * sizePerVox, py = (y - origin.y + 0.5f) * sizePerVox, pz = (z - origin.z + 0.5f) * sizePerVox; Color c = palatte [chunk.voxels [x, y, z] - 1]; if (alphaMask != null && alphaMask.voxels != null && alphaMask.voxels[x, y, z] != 0) { c.a = (float)(alphaMask.voxels [x, y, z] - 1) / 255; } GameObject go = CreateGameObject( parent, new Vector3(px, py, pz), string.Format("Voxel ({0}, {1}, {2})", x, y, z), MVImporter.CubeMeshWithColor(sizePerVox, c), mat); MVVoxModelVoxel v = go.AddComponent <MVVoxModelVoxel> (); v.voxel = new MVVoxel() { x = (byte)x, y = (byte)y, z = (byte)z, colorIndex = chunk.voxels [x, y, z] }; result.Add(go); } } } } return(result.ToArray()); }
public static MVMainChunk LoadVOX(string path, MVVoxelChunk alphaMask = null, bool generateFaces = true) { byte[] bytes = File.ReadAllBytes (path); if (bytes [0] != 'V' || bytes [1] != 'O' || bytes [2] != 'X' || bytes [3] != ' ') { Debug.LogError ("Invalid VOX file, magic number mismatch"); return null; } return LoadVOXFromData (bytes, alphaMask, generateFaces); }
private static bool DetermineEmptyOrOtherAlphaVoxel(MVVoxelChunk voxelChunk, MVVoxelChunk alphaMask, int a, int x, int y, int z) { bool isEmpty = voxelChunk.voxels[x, y, z] == 0; if (alphaMask == null) return isEmpty; else { bool otherAlpha = alphaMask.voxels[x, y, z] != a; return isEmpty || otherAlpha; } }
public static Mesh[] CreateMeshesFromChunk(MVVoxelChunk chunk, Color[] palatte, float sizePerVox, MVVoxelChunk alphaMask) { Vector3 origin = new Vector3( (float)chunk.sizeX / 2, (float)chunk.sizeY / 2, (float)chunk.sizeZ / 2); return CreateMeshesFromChunk(chunk, palatte, sizePerVox, alphaMask, origin); }
public static Mesh[] CreateMeshesFromChunk(MVVoxelChunk chunk, Color[] palatte, float sizePerVox, MVVoxelChunk alphaMask, Vector3 origin) { if (alphaMask != null && (alphaMask.sizeX != chunk.sizeX || alphaMask.sizeY != chunk.sizeY || alphaMask.sizeZ != chunk.sizeZ)) { Debug.LogErrorFormat("Unable to create meshes from chunk : Chunk's size ({0},{1},{2}) differs from alphaMask chunk's size ({3},{4},{5})", chunk.sizeX, chunk.sizeY, chunk.sizeZ, alphaMask.sizeX, alphaMask.sizeY, alphaMask.sizeZ); return new Mesh[] { }; } List<Vector3> verts = new List<Vector3> (); List<Vector3> normals = new List<Vector3> (); List<Color> colors = new List<Color> (); List<int> indicies = new List<int> (); Vector3[] faceNormals = new Vector3[] { Vector3.right, Vector3.left, Vector3.up, Vector3.down, Vector3.forward, Vector3.back }; List<Mesh> result = new List<Mesh> (); if (sizePerVox <= 0.0f) sizePerVox = 0.1f; float halfSize = sizePerVox / 2.0f; int currentQuadCount = 0; int totalQuadCount = 0; for (int f = 0; f < 6; ++f) { for (int x = 0; x < chunk.sizeX; ++x) { for (int y = 0; y < chunk.sizeY; ++y) { for (int z = 0; z < chunk.sizeZ; ++z) { int cidx = chunk.faces [f].colorIndices [x, y, z]; int alpha = alphaMask == null ? (byte)0 : alphaMask.voxels[x, y, z]; if (cidx != 0) { float px = (x - origin.x + 0.5f) * sizePerVox, py = (y - origin.y + 0.5f) * sizePerVox, pz = (z - origin.z + 0.5f) * sizePerVox; int rx = x, ry = y, rz = z; switch (f) { case 1: case 0: { ry = y + 1; while (ry < chunk.sizeY && CompareColor(cidx, alpha, chunk, alphaMask, f, x, ry, z)) ry++; ry--; rz = z + 1; while (rz < chunk.sizeZ) { bool inc = true; for (int k = y; k <= ry; ++k) { inc = inc & (CompareColor(cidx, alpha, chunk, alphaMask, f, x, k, rz)); } if (inc) rz++; else break; } rz--; break; } case 3: case 2: { rx = x + 1; while (rx < chunk.sizeX && CompareColor(cidx, alpha, chunk, alphaMask, f, rx, y, z)) rx++; rx--; rz = z + 1; while (rz < chunk.sizeZ) { bool inc = true; for (int k = x; k <= rx; ++k) { inc = inc & (CompareColor(cidx, alpha, chunk, alphaMask, f, k, y, rz)); } if (inc) rz++; else break; } rz--; break; } case 5: case 4: { rx = x + 1; while (rx < chunk.sizeX && CompareColor(cidx, alpha, chunk, alphaMask, f, rx, y, z)) rx++; rx--; ry = y + 1; while (ry < chunk.sizeY) { bool inc = true; for (int k = x; k <= rx; ++k) { inc = inc & (CompareColor(cidx, alpha, chunk, alphaMask, f, k, ry, z)); } if (inc) ry++; else break; } ry--; break; } } for (int kx = x; kx <= rx; ++kx) { for (int ky = y; ky <= ry; ++ky) { for (int kz = z; kz <= rz; ++kz) { if(kx != x || ky != y || kz != z) chunk.faces [f].colorIndices [kx, ky, kz] = 0; } } } int dx = rx - x; int dy = ry - y; int dz = rz - z; switch (f) { case 1: verts.Add (new Vector3 (px - halfSize, py - halfSize, pz - halfSize)); verts.Add (new Vector3 (px - halfSize, py - halfSize, pz + halfSize + sizePerVox * dz)); verts.Add (new Vector3 (px - halfSize, py + halfSize + sizePerVox * dy, pz + halfSize + sizePerVox * dz)); verts.Add (new Vector3 (px - halfSize, py + halfSize + sizePerVox * dy, pz - halfSize)); break; case 0: verts.Add (new Vector3 (px + halfSize, py - halfSize, pz - halfSize)); verts.Add (new Vector3 (px + halfSize, py + halfSize + sizePerVox * dy, pz - halfSize)); verts.Add (new Vector3 (px + halfSize, py + halfSize + sizePerVox * dy, pz + halfSize + sizePerVox * dz)); verts.Add (new Vector3 (px + halfSize, py - halfSize, pz + halfSize + sizePerVox * dz)); break; case 3: verts.Add (new Vector3 (px + halfSize + sizePerVox * dx, py - halfSize, pz - halfSize)); verts.Add (new Vector3 (px + halfSize + sizePerVox * dx, py - halfSize, pz + halfSize + sizePerVox * dz)); verts.Add (new Vector3 (px - halfSize, py - halfSize, pz + halfSize + sizePerVox * dz)); verts.Add (new Vector3 (px - halfSize, py - halfSize, pz - halfSize)); break; case 2: verts.Add (new Vector3 (px + halfSize + sizePerVox * dx, py + halfSize, pz - halfSize)); verts.Add (new Vector3 (px - halfSize, py + halfSize, pz - halfSize)); verts.Add (new Vector3 (px - halfSize, py + halfSize, pz + halfSize + sizePerVox * dz)); verts.Add (new Vector3 (px + halfSize + sizePerVox * dx, py + halfSize, pz + halfSize + sizePerVox * dz)); break; case 5: verts.Add (new Vector3 (px - halfSize, py + halfSize + sizePerVox * dy, pz - halfSize)); verts.Add (new Vector3 (px + halfSize + sizePerVox * dx, py + halfSize + sizePerVox * dy, pz - halfSize)); verts.Add (new Vector3 (px + halfSize + sizePerVox * dx, py - halfSize, pz - halfSize)); verts.Add (new Vector3 (px - halfSize, py - halfSize, pz - halfSize)); break; case 4: verts.Add (new Vector3 (px - halfSize, py + halfSize + sizePerVox * dy, pz + halfSize)); verts.Add (new Vector3 (px - halfSize, py - halfSize, pz + halfSize)); verts.Add (new Vector3 (px + halfSize + sizePerVox * dx, py - halfSize, pz + halfSize)); verts.Add (new Vector3 (px + halfSize + sizePerVox * dx, py + halfSize + sizePerVox * dy, pz + halfSize)); break; } normals.Add (faceNormals [f]); normals.Add (faceNormals [f]); normals.Add (faceNormals [f]); normals.Add (faceNormals [f]); // color index starts with 1 Color c = palatte [cidx - 1]; if (alpha != 0) c.a = (float)(alpha - 1) / 255; colors.Add (c); colors.Add (c); colors.Add (c); colors.Add (c); indicies.Add (currentQuadCount * 4 + 0); indicies.Add (currentQuadCount * 4 + 1); indicies.Add (currentQuadCount * 4 + 2); indicies.Add (currentQuadCount * 4 + 2); indicies.Add (currentQuadCount * 4 + 3); indicies.Add (currentQuadCount * 4 + 0); currentQuadCount += 1; // u3d max if (verts.Count + 4 >= 65000) { Mesh mesh = new Mesh (); mesh.vertices = verts.ToArray(); mesh.colors = colors.ToArray(); mesh.normals = normals.ToArray(); mesh.triangles = indicies.ToArray (); mesh.Optimize (); result.Add (mesh); verts.Clear (); colors.Clear (); normals.Clear (); indicies.Clear (); totalQuadCount += currentQuadCount; currentQuadCount = 0; } } } } } } if (verts.Count > 0) { Mesh mesh = new Mesh (); mesh.vertices = verts.ToArray(); mesh.colors = colors.ToArray(); mesh.normals = normals.ToArray(); mesh.triangles = indicies.ToArray (); mesh.Optimize (); result.Add (mesh); totalQuadCount += currentQuadCount; } Debug.Log (string.Format ("[MVImport] Mesh generated, total quads {0}", totalQuadCount)); return result.ToArray(); }
public static GameObject[] CreateVoxelGameObjectsForChunk(MVVoxelChunk chunk, Color[] palatte, Transform parent, Material mat, float sizePerVox, MVVoxelChunk alphaMask) { Vector3 origin = new Vector3( (float)chunk.sizeX / 2, (float)chunk.sizeY / 2, (float)chunk.sizeZ / 2); return CreateVoxelGameObjectsForChunk(chunk, palatte, parent, mat, sizePerVox, alphaMask, origin); }
public static GameObject[] CreateVoxelGameObjectsForChunk(MVVoxelChunk chunk, Color[] palatte, Transform parent, Material mat, float sizePerVox, MVVoxelChunk alphaMask, Vector3 origin) { List<GameObject> result = new List<GameObject> (); Mesh[] meshes = CreateMeshesFromChunk (chunk, palatte, sizePerVox, alphaMask, origin); int index = 0; foreach (Mesh mesh in meshes) { GameObject go = new GameObject (); go.name = string.Format ("VoxelMesh ({0})", index); go.transform.SetParent (parent); go.transform.localPosition = Vector3.zero; MeshFilter mf = go.AddComponent<MeshFilter> (); mf.mesh = mesh; MeshRenderer mr = go.AddComponent<MeshRenderer> (); mr.material = mat; go.AddComponent<MVVoxModelMesh> (); result.Add (go); index++; } return result.ToArray (); }
public static GameObject[] CreateIndividualVoxelGameObjectsForChunk(MVVoxelChunk chunk, Color[] palatte, Transform parent, Material mat, float sizePerVox, MVVoxelChunk alphaMask, Vector3 origin) { List<GameObject> result = new List<GameObject> (); if (alphaMask != null && (alphaMask.sizeX != chunk.sizeX || alphaMask.sizeY != chunk.sizeY || alphaMask.sizeZ != chunk.sizeZ)) { Debug.LogErrorFormat("Unable to create meshes from chunk : Chunk's size ({0},{1},{2}) differs from alphaMask chunk's size ({3},{4},{5})", chunk.sizeX, chunk.sizeY, chunk.sizeZ, alphaMask.sizeX, alphaMask.sizeY, alphaMask.sizeZ); return result.ToArray(); } for (int x = 0; x < chunk.sizeX; ++x) { for (int y = 0; y < chunk.sizeY; ++y) { for (int z = 0; z < chunk.sizeZ; ++z) { if (chunk.voxels [x, y, z] != 0) { float px = (x - origin.x + 0.5f) * sizePerVox, py = (y - origin.y + 0.5f) * sizePerVox, pz = (z - origin.z + 0.5f) * sizePerVox; Color c = palatte [chunk.voxels [x, y, z] - 1]; if (alphaMask != null && alphaMask.voxels[x, y, z] != 0) c.a = (float)(alphaMask.voxels [x, y, z] - 1) / 255; GameObject go = CreateGameObject ( parent, new Vector3 (px, py, pz), string.Format ("Voxel ({0}, {1}, {2})", x, y, z), MVImporter.CubeMeshWithColor (sizePerVox, c), mat); MVVoxModelVoxel v = go.AddComponent<MVVoxModelVoxel> (); v.voxel = new MVVoxel () { x = (byte)x, y = (byte)y, z = (byte)z, colorIndex = chunk.voxels [x, y, z] }; result.Add (go); } } } } return result.ToArray(); }
static int ReadVoxelChunk(BinaryReader br, MVVoxelChunk chunk) { int chunkSize = br.ReadInt32 (); int childrenSize = br.ReadInt32 (); int numVoxels = br.ReadInt32 (); for (int i = 0; i < numVoxels; ++i) { int x = (int)br.ReadByte (); int z = (int)br.ReadByte (); int y = (int)br.ReadByte (); chunk.voxels [x, y, z] = br.ReadByte(); } if (childrenSize > 0) { br.ReadBytes (childrenSize); Debug.LogWarning ("[MVImporter] Nested chunk not supported"); } return chunkSize + childrenSize + 4 * 3; }
public static void GenerateFaces(MVVoxelChunk voxelChunk, MVVoxelChunk alphaMask) { voxelChunk.faces = new MVFaceCollection[6]; for (int i = 0; i < 6; ++i) { voxelChunk.faces [i].colorIndices = new byte[voxelChunk.sizeX, voxelChunk.sizeY, voxelChunk.sizeZ]; } for (int x = 0; x < voxelChunk.sizeX; ++x) { for (int y = 0; y < voxelChunk.sizeY; ++y) { for (int z = 0; z < voxelChunk.sizeZ; ++z) { int alpha = alphaMask == null ? (byte)0 : alphaMask.voxels[x, y, z]; // left right if (x == 0 || DetermineEmptyOrOtherAlphaVoxel(voxelChunk, alphaMask, alpha, x - 1, y, z)) voxelChunk.faces [(int)MVFaceDir.XNeg].colorIndices [x, y, z] = voxelChunk.voxels [x, y, z]; if (x == voxelChunk.sizeX - 1 || DetermineEmptyOrOtherAlphaVoxel(voxelChunk, alphaMask, alpha, x + 1, y, z)) voxelChunk.faces [(int)MVFaceDir.XPos].colorIndices [x, y, z] = voxelChunk.voxels [x, y, z]; // up down if (y == 0 || DetermineEmptyOrOtherAlphaVoxel(voxelChunk, alphaMask, alpha, x, y - 1, z)) voxelChunk.faces [(int)MVFaceDir.YNeg].colorIndices [x, y, z] = voxelChunk.voxels [x, y, z]; if (y == voxelChunk.sizeY - 1 || DetermineEmptyOrOtherAlphaVoxel(voxelChunk, alphaMask, alpha, x, y + 1, z)) voxelChunk.faces [(int)MVFaceDir.YPos].colorIndices [x, y, z] = voxelChunk.voxels [x, y, z]; // forward backward if (z == 0 || DetermineEmptyOrOtherAlphaVoxel(voxelChunk, alphaMask, alpha, x, y, z - 1)) voxelChunk.faces [(int)MVFaceDir.ZNeg].colorIndices [x, y, z] = voxelChunk.voxels [x, y, z]; if (z == voxelChunk.sizeZ - 1 || DetermineEmptyOrOtherAlphaVoxel(voxelChunk, alphaMask, alpha, x, y, z + 1)) voxelChunk.faces [(int)MVFaceDir.ZPos].colorIndices [x, y, z] = voxelChunk.voxels [x, y, z]; } } } }
public static Mesh[] CreateMeshesFromChunk(MVVoxelChunk chunk, Color[] palatte, float sizePerVox, MVVoxelChunk alphaMask, Vector3 origin) { if (alphaMask != null && alphaMask.voxels != null && (alphaMask.sizeX != chunk.sizeX || alphaMask.sizeY != chunk.sizeY || alphaMask.sizeZ != chunk.sizeZ)) { Debug.LogErrorFormat("Unable to create meshes from chunk : Chunk's size ({0},{1},{2}) differs from alphaMask chunk's size ({3},{4},{5})", chunk.sizeX, chunk.sizeY, chunk.sizeZ, alphaMask.sizeX, alphaMask.sizeY, alphaMask.sizeZ); return(new Mesh[] { }); } List <Vector3> verts = new List <Vector3> (); List <Vector3> normals = new List <Vector3> (); List <Color> colors = new List <Color> (); List <int> indicies = new List <int> (); Vector3[] faceNormals = new Vector3[] { Vector3.right, Vector3.left, Vector3.up, Vector3.down, Vector3.forward, Vector3.back }; List <Mesh> result = new List <Mesh> (); if (sizePerVox <= 0.0f) { sizePerVox = 0.1f; } float halfSize = sizePerVox / 2.0f; int currentQuadCount = 0; int totalQuadCount = 0; for (int f = 0; f < 6; ++f) { for (int x = 0; x < chunk.sizeX; ++x) { for (int y = 0; y < chunk.sizeY; ++y) { for (int z = 0; z < chunk.sizeZ; ++z) { int cidx = chunk.faces [f].colorIndices [x, y, z]; int alpha = 0; if (alphaMask == null && alphaMask.voxels != null) { alpha = alphaMask.voxels[x, y, z]; } if (cidx != 0) { float px = (x - origin.x + 0.5f) * sizePerVox, py = (y - origin.y + 0.5f) * sizePerVox, pz = (z - origin.z + 0.5f) * sizePerVox; int rx = x, ry = y, rz = z; switch (f) { case 1: case 0: { ry = y + 1; while (ry < chunk.sizeY && CompareColor(cidx, alpha, chunk, alphaMask, f, x, ry, z)) { ry++; } ry--; rz = z + 1; while (rz < chunk.sizeZ) { bool inc = true; for (int k = y; k <= ry; ++k) { inc = inc & (CompareColor(cidx, alpha, chunk, alphaMask, f, x, k, rz)); } if (inc) { rz++; } else { break; } } rz--; break; } case 3: case 2: { rx = x + 1; while (rx < chunk.sizeX && CompareColor(cidx, alpha, chunk, alphaMask, f, rx, y, z)) { rx++; } rx--; rz = z + 1; while (rz < chunk.sizeZ) { bool inc = true; for (int k = x; k <= rx; ++k) { inc = inc & (CompareColor(cidx, alpha, chunk, alphaMask, f, k, y, rz)); } if (inc) { rz++; } else { break; } } rz--; break; } case 5: case 4: { rx = x + 1; while (rx < chunk.sizeX && CompareColor(cidx, alpha, chunk, alphaMask, f, rx, y, z)) { rx++; } rx--; ry = y + 1; while (ry < chunk.sizeY) { bool inc = true; for (int k = x; k <= rx; ++k) { inc = inc & (CompareColor(cidx, alpha, chunk, alphaMask, f, k, ry, z)); } if (inc) { ry++; } else { break; } } ry--; break; } } for (int kx = x; kx <= rx; ++kx) { for (int ky = y; ky <= ry; ++ky) { for (int kz = z; kz <= rz; ++kz) { if (kx != x || ky != y || kz != z) { chunk.faces [f].colorIndices [kx, ky, kz] = 0; } } } } int dx = rx - x; int dy = ry - y; int dz = rz - z; switch (f) { case 1: verts.Add(new Vector3(px - halfSize, py - halfSize, pz - halfSize)); verts.Add(new Vector3(px - halfSize, py - halfSize, pz + halfSize + sizePerVox * dz)); verts.Add(new Vector3(px - halfSize, py + halfSize + sizePerVox * dy, pz + halfSize + sizePerVox * dz)); verts.Add(new Vector3(px - halfSize, py + halfSize + sizePerVox * dy, pz - halfSize)); break; case 0: verts.Add(new Vector3(px + halfSize, py - halfSize, pz - halfSize)); verts.Add(new Vector3(px + halfSize, py + halfSize + sizePerVox * dy, pz - halfSize)); verts.Add(new Vector3(px + halfSize, py + halfSize + sizePerVox * dy, pz + halfSize + sizePerVox * dz)); verts.Add(new Vector3(px + halfSize, py - halfSize, pz + halfSize + sizePerVox * dz)); break; case 3: verts.Add(new Vector3(px + halfSize + sizePerVox * dx, py - halfSize, pz - halfSize)); verts.Add(new Vector3(px + halfSize + sizePerVox * dx, py - halfSize, pz + halfSize + sizePerVox * dz)); verts.Add(new Vector3(px - halfSize, py - halfSize, pz + halfSize + sizePerVox * dz)); verts.Add(new Vector3(px - halfSize, py - halfSize, pz - halfSize)); break; case 2: verts.Add(new Vector3(px + halfSize + sizePerVox * dx, py + halfSize, pz - halfSize)); verts.Add(new Vector3(px - halfSize, py + halfSize, pz - halfSize)); verts.Add(new Vector3(px - halfSize, py + halfSize, pz + halfSize + sizePerVox * dz)); verts.Add(new Vector3(px + halfSize + sizePerVox * dx, py + halfSize, pz + halfSize + sizePerVox * dz)); break; case 5: verts.Add(new Vector3(px - halfSize, py + halfSize + sizePerVox * dy, pz - halfSize)); verts.Add(new Vector3(px + halfSize + sizePerVox * dx, py + halfSize + sizePerVox * dy, pz - halfSize)); verts.Add(new Vector3(px + halfSize + sizePerVox * dx, py - halfSize, pz - halfSize)); verts.Add(new Vector3(px - halfSize, py - halfSize, pz - halfSize)); break; case 4: verts.Add(new Vector3(px - halfSize, py + halfSize + sizePerVox * dy, pz + halfSize)); verts.Add(new Vector3(px - halfSize, py - halfSize, pz + halfSize)); verts.Add(new Vector3(px + halfSize + sizePerVox * dx, py - halfSize, pz + halfSize)); verts.Add(new Vector3(px + halfSize + sizePerVox * dx, py + halfSize + sizePerVox * dy, pz + halfSize)); break; } normals.Add(faceNormals [f]); normals.Add(faceNormals [f]); normals.Add(faceNormals [f]); normals.Add(faceNormals [f]); // color index starts with 1 Color c = palatte [cidx - 1]; if (alpha != 0) { c.a = (float)(alpha - 1) / 255; } colors.Add(c); colors.Add(c); colors.Add(c); colors.Add(c); indicies.Add(currentQuadCount * 4 + 0); indicies.Add(currentQuadCount * 4 + 1); indicies.Add(currentQuadCount * 4 + 2); indicies.Add(currentQuadCount * 4 + 2); indicies.Add(currentQuadCount * 4 + 3); indicies.Add(currentQuadCount * 4 + 0); currentQuadCount += 1; // u3d max if (verts.Count + 4 >= 65000) { Mesh mesh = new Mesh(); mesh.vertices = verts.ToArray(); mesh.colors = colors.ToArray(); mesh.normals = normals.ToArray(); mesh.triangles = indicies.ToArray(); result.Add(mesh); verts.Clear(); colors.Clear(); normals.Clear(); indicies.Clear(); totalQuadCount += currentQuadCount; currentQuadCount = 0; } } } } } } if (verts.Count > 0) { Mesh mesh = new Mesh(); mesh.vertices = verts.ToArray(); mesh.colors = colors.ToArray(); mesh.normals = normals.ToArray(); mesh.triangles = indicies.ToArray(); result.Add(mesh); totalQuadCount += currentQuadCount; } Debug.Log(string.Format("[MVImport] Mesh generated, total quads {0}", totalQuadCount)); return(result.ToArray()); }
private static bool CompareColor(int cidx, int alpha, MVVoxelChunk chunk, MVVoxelChunk alphaChunk, int f, int x, int y, int z) { if (alphaChunk == null) return chunk.faces[f].colorIndices[x, y, z] == cidx; else return chunk.faces[f].colorIndices[x, y, z] == cidx && alphaChunk.voxels[x, y, z] == alpha; }
public static MVMainChunk LoadVOXFromData(byte[] data, MVVoxelChunk alphaMask = null, bool generateFaces = true) { using (MemoryStream ms = new MemoryStream(data)) { using (BinaryReader br = new BinaryReader(ms)) { MVMainChunk mainChunk = new MVMainChunk(); // "VOX " br.ReadInt32(); // "VERSION " mainChunk.version = br.ReadBytes(4); byte[] chunkId = br.ReadBytes(4); if (chunkId [0] != 'M' || chunkId [1] != 'A' || chunkId [2] != 'I' || chunkId [3] != 'N') { Debug.LogError("[MVImport] Invalid MainChunk ID, main chunk expected"); return(null); } int chunkSize = br.ReadInt32(); int childrenSize = br.ReadInt32(); // main chunk should have nothing... skip br.ReadBytes(chunkSize); int readSize = 0; while (readSize < childrenSize) { chunkId = br.ReadBytes(4); if (chunkId [0] == 'P' && chunkId [1] == 'A' && chunkId [2] == 'C' && chunkId [3] == 'K') { int chunkContentBytes = br.ReadInt32(); int childrenBytes = br.ReadInt32(); int modelCount = br.ReadInt32(); readSize += chunkContentBytes + childrenBytes + 4 * 3; } else if (chunkId [0] == 'S' && chunkId [1] == 'I' && chunkId [2] == 'Z' && chunkId [3] == 'E') { readSize += ReadSizeChunk(br, mainChunk); } else if (chunkId [0] == 'X' && chunkId [1] == 'Y' && chunkId [2] == 'Z' && chunkId [3] == 'I') { readSize += ReadVoxelChunk(br, mainChunk.voxelChunk); } else if (chunkId [0] == 'R' && chunkId [1] == 'G' && chunkId [2] == 'B' && chunkId [3] == 'A') { mainChunk.palatte = new Color[256]; readSize += ReadPalattee(br, mainChunk.palatte); } else { Debug.LogError("[MVImport] Chunk ID not recognized, got " + System.Text.Encoding.ASCII.GetString(chunkId)); return(null); } } mainChunk.alphaMaskChunk = alphaMask; if (generateFaces) { GenerateFaces(mainChunk.voxelChunk, alphaMask); } if (mainChunk.palatte == null) { mainChunk.palatte = MVMainChunk.defaultPalatte; } return(mainChunk); } } }
public static MVMainChunk LoadVOXFromData(byte[] data, MVVoxelChunk alphaMask = null, bool generateFaces = true) { using (MemoryStream ms = new MemoryStream (data)) { using (BinaryReader br = new BinaryReader (ms)) { MVMainChunk mainChunk = new MVMainChunk (); // "VOX " br.ReadInt32 (); // "VERSION " mainChunk.version = br.ReadBytes(4); byte[] chunkId = br.ReadBytes (4); if (chunkId [0] != 'M' || chunkId [1] != 'A' || chunkId [2] != 'I' || chunkId [3] != 'N') { Debug.LogError ("[MVImport] Invalid MainChunk ID, main chunk expected"); return null; } int chunkSize = br.ReadInt32 (); int childrenSize = br.ReadInt32 (); // main chunk should have nothing... skip br.ReadBytes (chunkSize); int readSize = 0; while (readSize < childrenSize) { chunkId = br.ReadBytes (4); if (chunkId [0] == 'S' && chunkId [1] == 'I' && chunkId [2] == 'Z' && chunkId [3] == 'E') { readSize += ReadSizeChunk (br, mainChunk); } else if (chunkId [0] == 'X' && chunkId [1] == 'Y' && chunkId [2] == 'Z' && chunkId [3] == 'I') { readSize += ReadVoxelChunk (br, mainChunk.voxelChunk); } else if (chunkId [0] == 'R' && chunkId [1] == 'G' && chunkId [2] == 'B' && chunkId [3] == 'A') { mainChunk.palatte = new Color[256]; readSize += ReadPalattee (br, mainChunk.palatte); } else { Debug.LogError ("[MVImport] Chunk ID not recognized, got " + System.Text.Encoding.ASCII.GetString(chunkId)); return null; } } mainChunk.alphaMaskChunk = alphaMask; if (generateFaces) GenerateFaces(mainChunk.voxelChunk, alphaMask); if (mainChunk.palatte == null) mainChunk.palatte = MVMainChunk.defaultPalatte; return mainChunk; } } }