public void NewVoxelStructure() { GameObject newGameObject = new GameObject(); VoxelContainer newVoxelContainer = newGameObject.AddComponent<VoxelContainer>(); for (int i = 0; i < this.sizeVector.x; i++) { for (int j = 0; j < this.sizeVector.y; j++) { for (int z = 0; z < this.sizeVector.z; z++) { Voxel newVoxel = new Voxel(); newVoxel.position.x = i; newVoxel.position.y = j; newVoxel.position.z = z; newVoxelContainer.AddVoxel(newVoxel); } } } newVoxelContainer.BuildMesh(false, true, true, true); if (SceneView.lastActiveSceneView != null) { UnityEditor.Selection.activeGameObject = newGameObject; SceneView.lastActiveSceneView.pivot = newGameObject.transform.position; SceneView.lastActiveSceneView.Repaint(); } }
private Voxel AddVoxelAtPosition(Vector3 aPosition, VoxelContainer aVoxelContainer, MeshCollider aMeshCollider) { if (aVoxelContainer.voxels.ContainsKey(aPosition)) { return(aVoxelContainer.voxels[aPosition]); } Voxel newVoxel = new Voxel(); newVoxel.position = aPosition; newVoxel.SetContainer(aVoxelContainer); aVoxelContainer.AddVoxel(newVoxel); return(newVoxel); }
private void ImportAssetOptionsQEObject(string aFilename) { if (Path.GetExtension(aFilename).ToUpper() != ".qb".ToUpper()) { Debug.LogError("Extension must be .qb"); return; } //Consts uint CODEFLAG = 2; uint NEXTSLICEFLAG = 6; //Parent Gameobject GameObject parentGameObject = new GameObject(); parentGameObject.name = Path.GetFileNameWithoutExtension(aFilename); BinaryReader br = new BinaryReader(File.Open(aFilename, FileMode.Open)); try { if (br == null) { Debug.Log("VoxelMax: Could not open file. Filename: " + aFilename); return; } uint fileVersion = br.ReadUInt32(); uint colorFormat = br.ReadUInt32(); uint zAxisOrientation = br.ReadUInt32(); uint compressed = br.ReadUInt32(); uint visibilityMaskEncoded = br.ReadUInt32(); uint numMatrices = br.ReadUInt32(); Debug.Log("Qubicle File Import Info\r\n" + "File Version: " + fileVersion + "\r\n" + "Color Format: " + colorFormat + "\r\n" + "zAxisOrientation: " + zAxisOrientation + "\r\n" + "visibilityMaskEncoded: " + visibilityMaskEncoded + "\r\n" + "Object Count: " + numMatrices); for (uint i = 0; i < numMatrices; i++) { // read matrix name byte nameLength = br.ReadByte(); string matrixName = new string(br.ReadChars(nameLength)); GameObject newGameObject = new GameObject(); newGameObject.transform.parent = parentGameObject.transform; newGameObject.name = matrixName; VoxelContainer newVoxelContainer = newGameObject.AddComponent <VoxelContainer>(); // read matrix size uint sizeX = br.ReadUInt32(); uint sizeY = br.ReadUInt32(); uint sizeZ = br.ReadUInt32(); // read matrix position (in this example the position is irrelevant) int posX = br.ReadInt32(); int posY = br.ReadInt32(); int posZ = br.ReadInt32(); newGameObject.transform.position = new Vector3(posX, posY, posZ); if (compressed == 0) // if uncompressd { for (uint z = 0; z < sizeZ; z++) { for (uint y = 0; y < sizeY; y++) { for (uint x = 0; x < sizeX; x++) { uint curColor = br.ReadUInt32(); if (curColor != 0) { Voxel newVoxel = new Voxel(); newVoxel.position = new Vector3(x, y, z); newVoxel.color = this.UIntToColor(curColor); newVoxelContainer.AddVoxel(newVoxel, false); } } } } } else // if compressed { uint z = 0; while (z < sizeZ) { z++; uint index = 0; while (true) { uint data = br.ReadUInt32(); if (data == NEXTSLICEFLAG) { break; } else if (data == CODEFLAG) { uint count = br.ReadUInt32(); data = br.ReadUInt32(); for (uint j = 0; j < count; j++) { uint x = index % sizeX + 1; // mod = modulo e.g. 12 mod 8 = 4 uint y = index / sizeX + 1; // div = integer division e.g. 12 div 8 = 1 index++; if (data != 0) { Voxel newVoxel = new Voxel(); newVoxel.position = new Vector3(x, y, z); newVoxel.color = this.UIntToColor(data); newVoxelContainer.AddVoxel(newVoxel, false); } } } else { uint x = index % sizeX + 1; uint y = index / sizeX + 1; index++; if (data != 0) { Voxel newVoxel = new Voxel(); newVoxel.position = new Vector3(x, y, z); newVoxel.color = this.UIntToColor(data); newVoxelContainer.AddVoxel(newVoxel, false); } } } } } newVoxelContainer.UpdateStructure(); newVoxelContainer.BuildMesh(true, true, true, true); } } finally { br.Close(); } }
private void MoveAggregatedVoxelsIntoNewContainers(object aBuildTask) { PhysicsBuildTask buildTask = (PhysicsBuildTask)aBuildTask; int gameObjectIndex = 0; try { if (buildTask.physicsAggregatedList != null) { while (buildTask.physicsAggregatedList.Count > 1) { int smallestIndex = 0; VoxelContainer newContainer = buildTask.voxelContainerList[gameObjectIndex]; newContainer.AssignUVDictionary(this.container); foreach (Voxel curVoxel in buildTask.physicsAggregatedList[smallestIndex]) { newContainer.AddVoxel(curVoxel, true); lock (this.container.voxels) { this.container.RemoveVoxel(curVoxel, true); } } Texture2D curTexture = null; int curTextureWidth = 0; int curTextureHeight = 0; foreach (VoxelArea curArea in this.container.voxelAreas.Values) { curTexture = curArea.GetTexture(); curTextureWidth = curArea.GetTextureWidth(); curTextureHeight = curArea.GetTextureHeight(); if (curTexture != null) { break; } } foreach (VoxelArea curArea in newContainer.voxelAreas.Values) { curArea.SetTexture(curTexture, curTextureWidth, curTextureHeight); } foreach (VoxelArea curArea in newContainer.voxelAreas.Values) { curArea.SetTexture(curTexture, curTextureWidth, curTextureHeight); } newContainer.GenerateAreaBuffers(); newContainer.rebuildCollider = false; List <VoxelContainer.ColliderDescriptor> colliders = newContainer.PrepareColliderDescriptors(); buildTask.colliders.Add(colliders); gameObjectIndex++; buildTask.physicsAggregatedList.RemoveAt(smallestIndex); } buildTask.mainBodyCollider = this.container.PrepareColliderDescriptors(); lock (this.container.voxels) { this.container.rebuildCollider = false; this.container.GenerateAreaBuffers(); this.container.mustRebuildBeforeUpdate = false; this.container.ingameBuildTask = null; } this.currentState = PhysicsState.Finalisation; buildTask.isReady = true; } } catch (Exception e) { Debug.LogError("VoxelPhysics error: " + e.Message); } }
private void ExportObjectToVoxFile(string aFilename) { GameObject tempGameObject = new GameObject(); VoxelContainer voxelContainer = tempGameObject.AddComponent <VoxelContainer>(); try { List <VoxelContainer> containers = new List <VoxelContainer>(); VoxelContainer rootContainer = this.voxelObject.GetComponent <VoxelContainer>(); if (this.exportChildObjects) { containers.AddRange(this.voxelObject.transform.GetComponentsInChildren <VoxelContainer>()); } else { if (rootContainer != null) { containers.Add(rootContainer); } } foreach (VoxelContainer curContainer in containers) { foreach (Voxel curVoxel in curContainer.voxels.Values) { Voxel newVoxel = new Voxel(); newVoxel.color = curVoxel.color; //Transform the positions into the same matrix newVoxel.position = this.voxelObject.transform.InverseTransformPoint(curContainer.gameObject.transform.TransformPoint(curVoxel.position)); voxelContainer.AddVoxel(newVoxel, false); } } if (voxelContainer.voxels.Count == 0) { Debug.LogError("Vox Export: Did not found voxels or voxelContainer in the structure! Please make sure you selected an object with voxelcontainer"); return; } if (Path.GetExtension(aFilename).ToUpper() != ".vox".ToUpper()) { Debug.LogError("Extension must be .vox"); return; } BinaryWriter bw = new BinaryWriter(File.OpenWrite(aFilename)); try { char[] magicalString = "VOX ".ToCharArray(); bw.Write(magicalString); int fileVersion = 150; bw.Write(fileVersion); //Main chunk //Chunk header char[] mainChunk = "MAIN".ToCharArray(); bw.Write(mainChunk); int chunkSize = 0; //3*4bytes bw.Write(chunkSize); int childChunks = (3 * 12) + 12 + (voxelContainer.voxels.Count * 4) + 4 + (256 * 4); //3 chunk header + size values + voxels values + voxelnumbers + color palette bw.Write(childChunks); //Size chunk //Chunk header char[] sizeChunk = "SIZE".ToCharArray(); bw.Write(sizeChunk); chunkSize = 3 * 4;//3*4bytes bw.Write(chunkSize); childChunks = 0; bw.Write(childChunks); //Chunk data Vector3 sizeVector = voxelContainer.GetMaxContainerVector() - voxelContainer.GetMinContainerVector(); int size = (int)sizeVector.x; bw.Write(size); //x size = (int)sizeVector.z; bw.Write(size); //y size = (int)sizeVector.y; bw.Write(size); //z //XYZI chunk //Chunk header char[] XYZIChunk = "XYZI".ToCharArray(); bw.Write(XYZIChunk); chunkSize = 4 * voxelContainer.voxels.Count + 4;//the Voxel's preferences are stored on 4 bytes bw.Write(chunkSize); childChunks = 0; bw.Write(childChunks); List <Color> colorPalette = voxelContainer.GetColorPalette(); if (colorPalette.Count > 255) { Debug.LogError("Export Failed: MagicaVoxel does not support more then 255 colors."); return; } //Prepare Transform Vector //We need it because, it looks like MagicaVoxel drops everything under 0 Vector3 transFormVector = Vector3.zero; Vector3 minVector = voxelContainer.GetMinContainerVector(); if (minVector.x < 0) { transFormVector.x = minVector.x * -1f; } if (minVector.y < 0) { transFormVector.y = minVector.y * -1f; } if (minVector.z < 0) { transFormVector.z = minVector.z * -1f; } //Chunk Data int voxelNumber = voxelContainer.voxels.Count; bw.Write(voxelNumber); foreach (Voxel curVoxel in voxelContainer.voxels.Values) { Vector3 voxelPos = curVoxel.position + transFormVector; byte coord = (byte)voxelPos.x; bw.Write(coord); coord = (byte)voxelPos.z; bw.Write(coord); coord = (byte)voxelPos.y; bw.Write(coord); byte colorIndex = (byte)(colorPalette.IndexOf(curVoxel.color) + 1); bw.Write(colorIndex); } //RGBA chunk //Chunk header char[] RGBAChunk = "RGBA".ToCharArray(); bw.Write(RGBAChunk); chunkSize = 4 * 256;//Colors are stored in bytes bw.Write(chunkSize); childChunks = 0; bw.Write(childChunks); //Color data for (int j = 0; j < colorPalette.Count; j++) { byte colorR = (byte)(colorPalette[j].r * 255); bw.Write(colorR); byte colorG = (byte)(colorPalette[j].g * 255); bw.Write(colorG); byte colorB = (byte)(colorPalette[j].b * 255); bw.Write(colorB); byte colorA = (byte)(colorPalette[j].a * 255); bw.Write(colorA); } if (colorPalette.Count < 256) { //Fill update the color palette to 255 for (int j = colorPalette.Count; j < 256; j++) { for (int k = 0; k < 4; k++) { byte color = 255; bw.Write(color); } } } } finally { bw.Flush(); bw.Close(); } } finally { DestroyImmediate(tempGameObject); } }
private void LoadVoxFile(string aFileName) { //I dissabled compiler warning, because we want to load some values from the file even if we would not use it later. //I think it is cleaner this way #pragma warning disable //Prepare Object GameObject newGameObject = new GameObject(); newGameObject.name = "ImportedFromMagicaVoxel"; VoxelContainer newVoxelContainer = newGameObject.AddComponent <VoxelContainer>(); //Open File BinaryReader br = new BinaryReader(File.OpenRead(aFileName)); string magic = new string(br.ReadChars(4)); int version = br.ReadInt32(); if (magic == "VOX ") { int sizex = 0, sizey = 0, sizez = 0; Color[] colors = null; MagicaVoxelData[] voxelData = null; while (br.BaseStream.Position < br.BaseStream.Length) { char[] chunkId = br.ReadChars(4); int chunkSize = br.ReadInt32(); int childChunks = br.ReadInt32(); string chunkName = new string(chunkId); if (chunkName == "SIZE") { sizex = br.ReadInt32(); sizey = br.ReadInt32(); sizez = br.ReadInt32(); br.ReadBytes(chunkSize - 4 * 3); } else if (chunkName == "XYZI") { int numVoxels = br.ReadInt32(); voxelData = new MagicaVoxelData[numVoxels]; for (int i = 0; i < voxelData.Length; i++) { voxelData[i] = new MagicaVoxelData(br); } } else if (chunkName == "RGBA") { colors = new Color[256]; for (int i = 0; i < 256; i++) { byte r = br.ReadByte(); byte g = br.ReadByte(); byte b = br.ReadByte(); byte a = br.ReadByte(); colors[i].r = r / 255f; colors[i].g = g / 255f; colors[i].b = b / 255f; colors[i].a = a / 255f; } } else { br.ReadBytes(chunkSize); } } if ((voxelData == null) || (voxelData.Length == 0)) { return; } for (int i = 0; i < voxelData.Length; i++) { Vector3 position = new Vector3(voxelData[i].x, voxelData[i].z, voxelData[i].y); if (!newVoxelContainer.voxels.ContainsKey(position)) { Voxel newVoxel = new Voxel(); newVoxel.position = position; newVoxel.color = (colors == null ? UShortToColor(voxColors[voxelData[i].color - 1]) : colors[voxelData[i].color - 1]); newVoxelContainer.AddVoxel(newVoxel, false); } } newVoxelContainer.UpdateStructure(); newVoxelContainer.BuildMesh(true, true, true, true); } else { Debug.LogError("Error durring vox import. Probably this is not a .vox file."); return; } #pragma warning restore }