Esempio n. 1
0
        public static void FromImage(Texture2D image, GameObject root, float voxelSize, int depth, bool centerPivot, Color cutoutColor)
        {
            if (root != null && image != null && image.width > 0 && image.height > 0 && depth > 0)
            {
                Volume voxelVolume = root.GetComponent <Volume>();

                voxelVolume.XSize            = image.width;
                voxelVolume.YSize            = image.height;
                voxelVolume.ZSize            = depth;
                voxelVolume.Frames[0].XSize  = voxelVolume.XSize;
                voxelVolume.Frames[0].YSize  = voxelVolume.YSize;
                voxelVolume.Frames[0].ZSize  = voxelVolume.ZSize;
                voxelVolume.Frames[0].Voxels = new Voxel[voxelVolume.XSize * voxelVolume.YSize * voxelVolume.ZSize];
                voxelVolume.VoxelSize        = voxelSize;

                if (centerPivot)
                {
                    voxelVolume.Pivot = (new Vector3(voxelVolume.XSize, voxelVolume.YSize, voxelVolume.ZSize) * voxelVolume.VoxelSize) / 2f;
                    voxelVolume.UpdatePivot();
                }

                for (int x = 0; x < image.width; x++)
                {
                    for (int y = 0; y < image.height; y++)
                    {
                        Color col = image.GetPixel(x, y);
                        for (int z = 0; z < depth; z++)
                        {
                            voxelVolume.Frames[0].Voxels[x + voxelVolume.XSize * (y + voxelVolume.YSize * z)] = new Voxel()
                            {
                                State = (col != cutoutColor && col.a > 0f)?VoxelState.Active : VoxelState.Inactive,
                                Color = col,
                                Value = 128
                            };
                        }
                    }
                }

                voxelVolume.CreateChunks();
                voxelVolume.SaveForSerialize();
            }
        }
Esempio n. 2
0
        public static void LoadCompound(BinaryReader stream, GameObject root, float voxelSize, bool first, Color32[] palette)
        {
            var nameLength = stream.ReadInt32();
            var name       = new string(stream.ReadChars(nameLength));

            var px = stream.ReadInt32();
            var py = stream.ReadInt32();
            var pz = stream.ReadInt32();

            px = -px;

            // PicaVoxel doesn't support scaling of volumes, sorry!
            stream.ReadInt32();
            stream.ReadInt32();
            stream.ReadInt32();

            var pivx = stream.ReadSingle();
            var pivy = stream.ReadSingle();
            var pivz = stream.ReadSingle();

            var sizeX = (int)stream.ReadUInt32();
            var sizeY = (int)stream.ReadUInt32();
            var sizeZ = (int)stream.ReadUInt32();

            pivx = sizeX - pivx;

            var child = Editor.Instantiate(EditorUtility.VoxelVolumePrefab, Vector3.zero, Quaternion.identity) as GameObject;

            child.transform.SetParent(root.transform);
            child.name = name;
            child.GetComponent <Volume>().Material = EditorUtility.PicaVoxelDiffuseMaterial;
            child.GetComponent <Volume>().GenerateBasic(FillMode.None);
            Volume voxelVolume = child.GetComponent <Volume>();

            voxelVolume.XSize            = Convert.ToInt32(sizeX);
            voxelVolume.YSize            = Convert.ToInt32(sizeY);
            voxelVolume.ZSize            = Convert.ToInt32(sizeZ);
            voxelVolume.Frames[0].XSize  = Convert.ToInt32(sizeX);
            voxelVolume.Frames[0].YSize  = Convert.ToInt32(sizeY);
            voxelVolume.Frames[0].ZSize  = Convert.ToInt32(sizeZ);
            voxelVolume.Frames[0].Voxels = new Voxel[sizeX * sizeY * sizeZ];
            voxelVolume.VoxelSize        = voxelSize;

            var dataSize       = (int)stream.ReadUInt32();
            var compressedData = stream.ReadBytes(dataSize);

            using (var ms = new MemoryStream(compressedData))
            {
                using (var gzs = new ZlibStream(ms, CompressionMode.Decompress, true))
                {
                    for (var x = 0; x < sizeX; x++)
                    {
                        for (var z = 0; z < sizeZ; z++)
                        {
                            for (var y = 0; y < sizeY; y++)
                            {
                                var r = (byte)gzs.ReadByte();
                                var g = (byte)gzs.ReadByte();
                                var b = (byte)gzs.ReadByte();
                                var m = (byte)gzs.ReadByte();
                                if (m > 0)
                                {
                                    voxelVolume.Frames[0].Voxels[(sizeX - 1 - x) + sizeX * (y + sizeY * z)] = new Voxel()
                                    {
                                        Color = palette == null ? new Color32(r, g, b, 255) : palette[r], Value = 128, State = VoxelState.Active
                                    }
                                }
                                ;
                            }
                        }
                    }
                }
            }

            voxelVolume.CreateChunks();
            voxelVolume.SaveForSerialize();

            var pivot = new Vector3(pivx, pivy, pivz) * voxelSize;

            voxelVolume.Pivot = pivot;
            voxelVolume.UpdatePivot();

            voxelVolume.transform.localPosition = (new Vector3(-sizeX + px, py, pz) * voxelSize) + pivot;

            var childCount = stream.ReadUInt32();

            for (var i = 0; i < childCount; i++)
            {
                LoadNode(stream, child, voxelSize, first, palette);
            }
        }
Esempio n. 3
0
        private static void FromQubicleQB(BinaryReader stream, GameObject root, float voxelSize)
        {
            //const int MAX_VOLUME_DIMENSION = 64;

            uint sizex = 0;
            uint sizey = 0;
            uint sizez = 0;

//            uint version;
            uint colorFormat;
            uint zAxisOrientation;
            uint compressed;
//            uint visibilityMaskEncoded;
            uint numMatrices;

            uint i;
            uint j;
            uint x;
            uint y;
            uint z;

            int posX;
            int posY;
            int posZ;

            uint[,,] matrix;
            List <uint[, , ]> matrixList = new List <uint[, , ]>();
            uint       index;
            uint       data;
            uint       count;
            const uint CODEFLAG      = 2;
            const uint NEXTSLICEFLAG = 6;

            //version = stream.ReadUInt32();
            stream.ReadUInt32();
            colorFormat      = stream.ReadUInt32();
            zAxisOrientation = stream.ReadUInt32();
            compressed       = stream.ReadUInt32();
            //visibilityMaskEncoded = stream.ReadUInt32();
            stream.ReadUInt32();
            numMatrices = stream.ReadUInt32();

            string volumeName = root.name;
            string path       = Helper.GetMeshStorePath();

            for (int d = root.transform.childCount - 1; d >= 0; d--)
            {
                Volume vol = root.transform.GetChild(d).GetComponent <Volume>();
                if (vol != null)
                {
                    if (Directory.Exists(path))
                    {
                        DirectoryInfo   di   = new DirectoryInfo(path);
                        DirectoryInfo[] dirs = di.GetDirectories();
                        for (int dir = 0; dir < dirs.Length; dir++)
                        {
                            if (dirs[dir].Name.ToLower() == vol.AssetGuid.ToLower())
                            {
                                dirs[dir].Delete(true);
                                break;
                            }
                        }
                    }
                    GameObject.DestroyImmediate(root.transform.GetChild(d).gameObject);
                }
            }

            for (i = 0; i < numMatrices; i++) // for each matrix stored in file
            {
                // read matrix name
                byte   nameLength = stream.ReadByte();
                string name       = new string(stream.ReadChars(nameLength));

                // read matrix size
                sizex = stream.ReadUInt32();
                sizey = stream.ReadUInt32();
                sizez = stream.ReadUInt32();

                // read matrix position (in this example the position is irrelevant)
                posX = stream.ReadInt32();
                posY = stream.ReadInt32();
                posZ = stream.ReadInt32();

                // create matrix and add to matrix list
                matrix = new uint[sizex, sizey, sizez];
                matrixList.Add(matrix);

                if (compressed == 0)  // if uncompressd
                {
                    for (z = 0; z < sizez; z++)
                    {
                        for (y = 0; y < sizey; y++)
                        {
                            for (x = 0; x < sizex; x++)
                            {
                                matrix[x, y, z] = stream.ReadUInt32();
                            }
                        }
                    }
                }
                else  // if compressed
                {
                    z = 0;

                    while (z < sizez)
                    {
                        index = 0;

                        while (true)
                        {
                            data = stream.ReadUInt32();

                            if (data == NEXTSLICEFLAG)
                            {
                                break;
                            }
                            else if (data == CODEFLAG)
                            {
                                count = stream.ReadUInt32();
                                data  = stream.ReadUInt32();

                                for (j = 0; j < count; j++)
                                {
                                    x = index % sizex; // mod = modulo e.g. 12 mod 8 = 4
                                    y = index / sizex; // div = integer division e.g. 12 div 8 = 1
                                    index++;
                                    matrix[x, y, z] = data;
                                }
                            }
                            else
                            {
                                x = index % sizex;
                                y = index / sizex;
                                index++;
                                matrix[x, y, z] = data;
                            }
                        }
                        z++;
                    }
                }


                var newObject =
                    Editor.Instantiate(EditorUtility.VoxelVolumePrefab, Vector3.zero, Quaternion.identity) as
                    GameObject;
                if (newObject != null)
                {
                    newObject.name = name != ""?name:volumeName;
                    newObject.GetComponent <Volume>().Material = EditorUtility.PicaVoxelDiffuseMaterial;
                    newObject.GetComponent <Volume>().GenerateBasic(FillMode.None);
                    Volume voxelVolume = newObject.GetComponent <Volume>();

                    voxelVolume.XSize            = Convert.ToInt32(sizex);
                    voxelVolume.YSize            = Convert.ToInt32(sizey);
                    voxelVolume.ZSize            = Convert.ToInt32(sizez);
                    voxelVolume.Frames[0].XSize  = Convert.ToInt32(sizex);
                    voxelVolume.Frames[0].YSize  = Convert.ToInt32(sizey);
                    voxelVolume.Frames[0].ZSize  = Convert.ToInt32(sizez);
                    voxelVolume.Frames[0].Voxels = new Voxel[sizex * sizey * sizez];
                    for (int v = 0; v < voxelVolume.Frames[0].Voxels.Length; v++)
                    {
                        voxelVolume.Frames[0].Voxels[v].Value = 128;
                    }
                    voxelVolume.VoxelSize = voxelSize;

                    if (zAxisOrientation == 0)
                    {
                        voxelVolume.Pivot = new Vector3(sizex, 0, 0) * voxelSize;
                        voxelVolume.UpdatePivot();
                    }

                    for (z = 0; z < sizez; z++)
                    {
                        for (y = 0; y < sizey; y++)
                        {
                            for (x = 0; x < sizex; x++)
                            {
                                Color col = UIntToColor(matrix[x, y, z], colorFormat);

                                if (matrix[x, y, z] != 0)
                                {
                                    voxelVolume.Frames[0].Voxels[(zAxisOrientation == 0 ? sizex - 1 - x : x) + sizex * (y + sizey * z)] = new Voxel()
                                    {
                                        State = VoxelState.Active,
                                        Color = col,
                                        Value = 128
                                    }
                                }
                                ;
                            }
                        }
                    }


                    voxelVolume.CreateChunks();
                    voxelVolume.SaveForSerialize();

                    newObject.transform.position = (new Vector3((zAxisOrientation == 0 ? -posX : posX), posY, posZ) * voxelSize);
                    newObject.transform.parent   = root.transform;
                }
                // }
            }
        }
Esempio n. 4
0
        private void OnEnable()
        {
     
            voxelObject = (Volume) target;
            Undo.undoRedoPerformed += () => voxelObject.OnUndoRedo();

            voxelSizeProperty = serializedObject.FindProperty("VoxelSize");
            overlapAmountProperty = serializedObject.FindProperty("OverlapAmount");
            collisionMode = serializedObject.FindProperty("CollisionMode");
            meshingMode = serializedObject.FindProperty("MeshingMode");
            meshCompression = serializedObject.FindProperty("MeshCompression");
            colliderMeshingMode = serializedObject.FindProperty("MeshColliderMeshingMode");
            separateColliderMesh = serializedObject.FindProperty("GenerateMeshColliderSeparately");
            pivotProperty = serializedObject.FindProperty("Pivot");

            voxelSize = voxelSizeProperty.floatValue;
            overlapAmount = overlapAmountProperty.floatValue;
            pivot = pivotProperty.vector3Value;

            selfShadeInt = serializedObject.FindProperty("SelfShadingIntensity");

            drawGrid = voxelObject.DrawGrid;
            drawMesh = voxelObject.DrawMesh;
            runtimeOnlyMesh = serializedObject.FindProperty("RuntimOnlyMesh");

            material = serializedObject.FindProperty("Material");
            physicMaterial = serializedObject.FindProperty("PhysicMaterial");
            castShadows = serializedObject.FindProperty("CastShadows");
            receiveShadows = serializedObject.FindProperty("ReceiveShadows");
            chunkLayer = serializedObject.FindProperty("ChunkLayer");
            collisionTrigger = serializedObject.FindProperty("CollisionTrigger");

            if (voxelObject != null && !Application.isPlaying && PrefabUtility.GetPrefabType(voxelObject) != PrefabType.Prefab && PrefabUtility.GetPrefabType(voxelObject) != PrefabType.PrefabInstance)
            {
                string path = Path.Combine(Helper.GetMeshStorePath(), voxelObject.AssetGuid);
                if (!Directory.Exists(path))
                    voxelObject.CreateChunks();
            }

            if (!Application.isPlaying && voxelObject.gameObject.activeSelf && PrefabUtility.GetPrefabType(voxelObject) != PrefabType.Prefab && !voxelObject.RuntimOnlyMesh)
                foreach (var frame in voxelObject.Frames)
                {
                    if (frame.HasDeserialized) frame.UpdateChunks(true);
                    frame.HasDeserialized = false;
                }

            paintMode = voxelObject.PaintMode;

            if (EditorPersistence.SelectBox.BottomLeftFront.X > voxelObject.XSize - 1 ||
                EditorPersistence.SelectBox.BottomLeftFront.Y > voxelObject.YSize - 1 ||
                EditorPersistence.SelectBox.BottomLeftFront.Z > voxelObject.ZSize - 1 ||
                EditorPersistence.SelectBox.TopRightBack.X > voxelObject.XSize - 1 ||
                EditorPersistence.SelectBox.TopRightBack.Y > voxelObject.YSize - 1 ||
                EditorPersistence.SelectBox.TopRightBack.Z > voxelObject.ZSize - 1)
                EditorPersistence.SelectBox = new PicaVoxelBox(0, 0, 0, voxelObject.XSize - 1, voxelObject.YSize - 1, voxelObject.ZSize - 1);
        }
Esempio n. 5
0
        public static void Scan(GameObject meshObject, float voxelSize)
        {
            Transform meshTransform = meshObject.transform;

            Mesh       mesh = null;
            MeshFilter mF   = meshObject.GetComponent <MeshFilter>();

            if (mF != null)
            {
                mesh = mF.sharedMesh;
            }
            else
            {
                SkinnedMeshRenderer sMR = meshObject.GetComponent <SkinnedMeshRenderer>();
                if (sMR != null)
                {
                    mesh = sMR.sharedMesh;
                }
            }
            if (mesh == null)
            {
                return;
            }

            // bool addedCollider = false;
            GameObject mcContainer = new GameObject("PVMCC");

            mcContainer.transform.SetParent(meshObject.transform, false);
            MeshCollider mc = mcContainer.AddComponent <MeshCollider>();

            mc.sharedMesh = mesh;

            GameObject mcContainerRev = new GameObject("PVMCCR");

            mcContainerRev.transform.SetParent(meshObject.transform, false);
            Mesh reverseMesh = (Mesh)UnityEngine.Object.Instantiate(mesh);

            reverseMesh.triangles = mesh.triangles.Reverse().ToArray();
            MeshCollider mcr = mcContainerRev.AddComponent <MeshCollider>();

            mcr.sharedMesh = reverseMesh;

            Vector3[] vertices = mesh.vertices;
            if (vertices.Length <= 0)
            {
                return;
            }

            Texture2D renderTex     = null;
            Color     materialColor = Color.white;
            Renderer  rend          = meshObject.GetComponent <Renderer>();

            if (rend != null && rend.sharedMaterial != null && rend.sharedMaterial.mainTexture != null)
            {
                renderTex = (Texture2D)rend.sharedMaterial.mainTexture;
                try
                {
                    renderTex.GetPixel(0, 0);
                }
                catch (Exception)
                {
                    string          path = AssetDatabase.GetAssetPath(rend.sharedMaterial.mainTexture);
                    TextureImporter ti   = (TextureImporter)TextureImporter.GetAtPath(path);
                    ti.isReadable = true;
                    AssetDatabase.ImportAsset(path);
                    ti.isReadable = false;

                    try
                    {
                        renderTex.GetPixel(0, 0);
                    }
                    catch (Exception)
                    {
                        renderTex = null;
                    }
                }
            }
            else if (rend != null && rend.sharedMaterial != null)
            {
                materialColor = rend.sharedMaterial.color;
            }

            Vector3 min, max;

            min = max = meshTransform.TransformPoint(vertices[0]);
            for (int i = 1; i < vertices.Length; i++)
            {
                Vector3 V = meshTransform.TransformPoint(vertices[i]);
                for (int n = 0; n < 3; n++)
                {
                    if (V[n] > max[n])
                    {
                        max[n] = V[n];
                    }
                    if (V[n] < min[n])
                    {
                        min[n] = V[n];
                    }
                }

                vertices[i] = V;
            }
            vertices[0] = meshTransform.TransformPoint(vertices[0]);
            Bounds bounds = new Bounds();

            bounds.SetMinMax(min, max);

            if (bounds.size.x <= 0f || bounds.size.y <= 0f || bounds.size.z <= 0f)
            {
                return;
            }

            var newObject = Editor.Instantiate(EditorUtility.VoxelVolumePrefab, Vector3.zero, Quaternion.identity) as GameObject;

            newObject.name = meshObject.name + " (Voxels)";
            newObject.GetComponent <Volume>().Material = EditorUtility.PicaVoxelDiffuseMaterial;
            newObject.GetComponent <Volume>().GenerateBasic(FillMode.None);
            Volume voxelVolume = newObject.GetComponent <Volume>();

            voxelVolume.XSize            = (int)(bounds.size.x / voxelSize) + 1;
            voxelVolume.YSize            = (int)(bounds.size.y / voxelSize) + 1;
            voxelVolume.ZSize            = (int)(bounds.size.z / voxelSize) + 1;
            voxelVolume.Frames[0].XSize  = voxelVolume.XSize;
            voxelVolume.Frames[0].YSize  = voxelVolume.YSize;
            voxelVolume.Frames[0].ZSize  = voxelVolume.ZSize;
            voxelVolume.Frames[0].Voxels = new Voxel[voxelVolume.XSize * voxelVolume.YSize * voxelVolume.ZSize];
            for (int i = 0; i < voxelVolume.Frames[0].Voxels.Length; i++)
            {
                voxelVolume.Frames[0].Voxels[i].Value = 128;
            }
            voxelVolume.VoxelSize = voxelSize;


            Vector3[] testDirs = { Vector3.forward, Vector3.back, Vector3.left, Vector3.right, Vector3.up, Vector3.down };

            float stepScale = 0.5f;
            int   size      = (int)((bounds.size.x) / (voxelSize * stepScale)) * (int)((bounds.size.y) / (voxelSize * stepScale)) *
                              (int)((bounds.size.z) / (voxelSize * stepScale));
            int progress = 0;

            // Outside
            for (float x = bounds.min.x; x < bounds.max.x + voxelSize; x += voxelSize * stepScale)
            {
                for (float y = bounds.min.y; y < bounds.max.y + voxelSize; y += voxelSize * stepScale)
                {
                    for (float z = bounds.min.z; z < bounds.max.z + voxelSize; z += voxelSize * stepScale)
                    {
                        Vector3 test = new Vector3(x, y, z);

                        for (int d = 0; d < 6; d++)
                        {
                            Vector3 hit;
                            Color   col;
                            if (TestRay(mc, mcContainer, renderTex, materialColor, mesh, test, testDirs[d].normalized, out hit, out col))
                            {
                                int vX = (voxelVolume.XSize - 1) - (int)((bounds.max.x - hit.x) / voxelSize);
                                int vY = (voxelVolume.YSize - 1) - (int)((bounds.max.y - hit.y) / voxelSize);
                                int vZ = (voxelVolume.ZSize - 1) - (int)((bounds.max.z - hit.z) / voxelSize);
                                if (!(vX < voxelVolume.XSize && vY < voxelVolume.YSize && vZ < voxelVolume.ZSize))
                                {
                                    continue;
                                }
                                voxelVolume.Frames[0].Voxels[vX + voxelVolume.XSize * (vY + voxelVolume.YSize * vZ)] = new Voxel()
                                {
                                    State = VoxelState.Active, Color = col, Value = 128
                                };
                            }
                        }

                        progress++;
                    }
                }


                if (UnityEditor.EditorUtility.DisplayCancelableProgressBar("Scanning Mesh", "Scanning Outside", (1f / (float)size) * (float)progress))
                {
                    UnityEditor.EditorUtility.ClearProgressBar();
                    GameObject.DestroyImmediate(voxelVolume.gameObject);
                    UnityEngine.Object.DestroyImmediate(mcContainer);
                    UnityEngine.Object.DestroyImmediate(mcContainerRev);
                    return;
                }
            }

            progress = 0;

            //Inside
            for (float x = bounds.min.x; x < bounds.max.x + voxelSize; x += voxelSize * stepScale)
            {
                for (float y = bounds.min.y; y < bounds.max.y + voxelSize; y += voxelSize * stepScale)
                {
                    for (float z = bounds.min.z; z < bounds.max.z + voxelSize; z += voxelSize * stepScale)
                    {
                        Vector3 test = new Vector3(x, y, z);

                        Vector3 hit;
                        Color   col;

                        float closestHit = Mathf.Infinity;
                        Color closestCol = Color.white;

                        int hitCount = 0;
                        for (int d = 0; d < 6; d++)
                        {
                            if (TestRay(mcr, mcContainerRev, renderTex, materialColor, reverseMesh, test, testDirs[d].normalized, out hit, out col))
                            {
                                if (Vector3.Distance(hit, test) < closestHit)
                                {
                                    closestHit = Vector3.Distance(hit, test);
                                    closestCol = col;
                                }
                                hitCount++;
                            }
                        }

                        if (hitCount == 6)
                        {
                            int vX = (voxelVolume.XSize - 1) - (int)((bounds.max.x - test.x) / voxelSize);
                            int vY = (voxelVolume.YSize - 1) - (int)((bounds.max.y - test.y) / voxelSize);
                            int vZ = (voxelVolume.ZSize - 1) - (int)((bounds.max.z - test.z) / voxelSize);
                            if (!(vX < voxelVolume.XSize && vY < voxelVolume.YSize && vZ < voxelVolume.ZSize))
                            {
                                continue;
                            }
                            voxelVolume.Frames[0].Voxels[vX + voxelVolume.XSize * (vY + voxelVolume.YSize * vZ)] = new Voxel()
                            {
                                State = VoxelState.Active, Color = closestCol, Value = 128
                            };
                        }

                        progress++;
                    }
                }

                if (UnityEditor.EditorUtility.DisplayCancelableProgressBar("Scanning Mesh", "Attempting to fill inside", (1f / (float)size) * (float)progress))
                {
                    UnityEditor.EditorUtility.ClearProgressBar();
                    GameObject.DestroyImmediate(voxelVolume.gameObject);
                    UnityEngine.Object.DestroyImmediate(mcContainer);
                    UnityEngine.Object.DestroyImmediate(mcContainerRev);
                    return;
                }
            }

            UnityEditor.EditorUtility.ClearProgressBar();



            voxelVolume.CreateChunks();
            voxelVolume.SaveForSerialize();
            voxelVolume.Frames[0].OnAfterDeserialize();
            voxelVolume.transform.position = meshObject.transform.position;

            voxelVolume.Pivot = (new Vector3(voxelVolume.XSize, voxelVolume.YSize, voxelVolume.ZSize) * voxelVolume.VoxelSize) / 2f;
            voxelVolume.UpdatePivot();

            UnityEngine.Object.DestroyImmediate(mcContainer);
            UnityEngine.Object.DestroyImmediate(mcContainerRev);

            voxelVolume.UpdateAllChunks();
        }
Esempio n. 6
0
        public static void Generate(int xSize, int ySize, int zSize, float smoothness, float voxelSize)
        {
            var newObject = Editor.Instantiate(EditorUtility.VoxelVolumePrefab, Vector3.zero, Quaternion.identity) as GameObject;

            newObject.name = "Terrain";
            newObject.GetComponent <Volume>().Material = EditorUtility.PicaVoxelDiffuseMaterial;
            newObject.GetComponent <Volume>().GenerateBasic(FillMode.None);
            Volume voxelVolume = newObject.GetComponent <Volume>();

            voxelVolume.XSize            = xSize;
            voxelVolume.YSize            = ySize;
            voxelVolume.ZSize            = zSize;
            voxelVolume.Frames[0].XSize  = voxelVolume.XSize;
            voxelVolume.Frames[0].YSize  = voxelVolume.YSize;
            voxelVolume.Frames[0].ZSize  = voxelVolume.ZSize;
            voxelVolume.Frames[0].Voxels = new Voxel[voxelVolume.XSize * voxelVolume.YSize * voxelVolume.ZSize];

            // Could remove this if we use Value as block type
            for (int i = 0; i < voxelVolume.Frames[0].Voxels.Length; i++)
            {
                voxelVolume.Frames[0].Voxels[i].Value = 128;
            }
            voxelVolume.VoxelSize = voxelSize;



            int progress = 0;

            // float progressSize = xSize*zSize;

            float[][] noise = PerlinNoise.GeneratePerlinNoise(xSize, zSize, 2 + (int)(smoothness * 6f));


            for (int x = 0; x < xSize; x++)
            {
                for (int z = 0; z < zSize; z++)
                {
                    //if (UnityEditor.EditorUtility.DisplayCancelableProgressBar("Terrain Generator", "Generating Terrain",
                    //    (1f/(float) progressSize)*(float) progress))
                    //{
                    //    UnityEditor.EditorUtility.ClearProgressBar();
                    //    GameObject.DestroyImmediate(voxelVolume.gameObject);
                    //    return;
                    //}

                    for (int y = 0; y < ySize; y++)
                    {
                        voxelVolume.Frames[0].Voxels[x + xSize * (y + ySize * z)] = new Voxel()
                        {
                            State = (noise[x][z] >= (1f / (float)ySize) * (float)y)?VoxelState.Active : VoxelState.Inactive,
                            Color = (y == ySize - 1 || noise[x][z] < (1f / (float)ySize) * (float)(y + 1))? new Color32(0, 128, 0, 255) : new Color32(128, 64, 0, 255),
                        };
                    }

                    progress++;
                }
            }

            voxelVolume.CreateChunks();
            voxelVolume.SaveForSerialize();
            voxelVolume.Frames[0].OnAfterDeserialize();

            voxelVolume.Pivot = (new Vector3(voxelVolume.XSize, 0, voxelVolume.ZSize) * voxelVolume.VoxelSize) / 2f;
            voxelVolume.UpdatePivot();

            voxelVolume.UpdateAllChunks();
        }
        public void OnGUI()
        {
            EditorGUILayout.Space();
            EditorUtility.SkinnedLabel("Volume Size: " + voxelObject.name + " (" + voxelObject.XSize + "," + voxelObject.YSize + "," + voxelObject.ZSize + ")");
            EditorGUILayout.Space();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("X:", new[] { GUILayout.Width(30) });
            xSize = EditorGUILayout.IntField(xSize);
            EditorGUILayout.LabelField("Y:", new[] { GUILayout.Width(30) });
            ySize = EditorGUILayout.IntField(ySize);
            EditorGUILayout.LabelField("Z:", new[] { GUILayout.Width(30) });
            zSize = EditorGUILayout.IntField(zSize);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();

            anchorX = (AnchorX)EditorGUILayout.EnumPopup("X Anchor: ", anchorX);
            anchorY = (AnchorY)EditorGUILayout.EnumPopup("Y Anchor: ", anchorY);
            anchorZ = (AnchorZ)EditorGUILayout.EnumPopup("Z Anchor: ", anchorZ);

            EditorGUILayout.Space();
            fillVoxels = EditorGUILayout.ToggleLeft(" Fill any added space", fillVoxels);

            EditorGUILayout.Space();
            EditorUtility.SkinnedLabel(
                "Chunk Size: " + voxelObject.name + " (" + voxelObject.XChunkSize + "," + voxelObject.YChunkSize + "," +
                voxelObject.ZChunkSize + ")");
            EditorGUILayout.Space();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("X:", new[] { GUILayout.Width(30) });
            xChunkSize = EditorGUILayout.IntField(xChunkSize);
            EditorGUILayout.LabelField("Y:", new[] { GUILayout.Width(30) });
            yChunkSize = EditorGUILayout.IntField(yChunkSize);
            EditorGUILayout.LabelField("Z:", new[] { GUILayout.Width(30) });
            zChunkSize = EditorGUILayout.IntField(zChunkSize);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.Space();
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Resize") &&
                (xSize != voxelObject.XSize || ySize != voxelObject.YSize || zSize != voxelObject.ZSize ||
                 xChunkSize != voxelObject.XChunkSize || yChunkSize != voxelObject.YChunkSize ||
                 zChunkSize != voxelObject.ZChunkSize))
            {
                if (xSize < 1)
                {
                    xSize = 1;
                }
                if (ySize < 1)
                {
                    ySize = 1;
                }
                if (zSize < 1)
                {
                    zSize = 1;
                }
                if (xChunkSize < 1)
                {
                    xChunkSize = 1;
                }
                if (yChunkSize < 1)
                {
                    yChunkSize = 1;
                }
                if (zChunkSize < 1)
                {
                    zChunkSize = 1;
                }

                int totalChunkSize = xChunkSize * yChunkSize * zChunkSize;

                if (totalChunkSize > 16 * 16 * 16)
                {
                    UnityEditor.EditorUtility.DisplayDialog("PicaVoxel",
                                                            "The largest chunk size is 16*16*16 voxels TOTAL. Decrease size in one axis to increase the other two.",
                                                            "OK");
                }
                else
                {
                    voxelObject.XChunkSize = xChunkSize;
                    voxelObject.YChunkSize = yChunkSize;
                    voxelObject.ZChunkSize = zChunkSize;


                    if (xSize != voxelObject.XSize || ySize != voxelObject.YSize || zSize != voxelObject.ZSize)
                    {
                        List <Object> undoObjects = new List <Object>();

                        foreach (Frame frame in voxelObject.Frames)
                        {
                            undoObjects.Add(frame);
                        }
                        undoObjects.Add(voxelObject);

                        Undo.RecordObjects(undoObjects.ToArray(), "Resize Voxel Object");
                        foreach (Frame frame in voxelObject.Frames)
                        {
                            UnityEditor.EditorUtility.SetDirty(frame);
                        }
                        UnityEditor.EditorUtility.SetDirty(voxelObject);

                        PicaVoxelBox copyDestBox =
                            new PicaVoxelBox(
                                anchorX == AnchorX.Left
                                    ? 0
                                    : anchorX == AnchorX.Center
                                        ? (xSize / 2) - (voxelObject.XSize / 2)
                                        : xSize - voxelObject.XSize,
                                anchorY == AnchorY.Bottom
                                    ? 0
                                    : anchorY == AnchorY.Center
                                        ? (ySize / 2) - (voxelObject.YSize / 2)
                                        : ySize - voxelObject.YSize,
                                anchorZ == AnchorZ.Front
                                    ? 0
                                    : anchorZ == AnchorZ.Center
                                        ? (zSize / 2) - (voxelObject.ZSize / 2)
                                        : zSize - voxelObject.ZSize,
                                (anchorX == AnchorX.Left
                                    ? 0
                                    : anchorX == AnchorX.Center
                                        ? (xSize / 2) - (voxelObject.XSize / 2)
                                        : xSize - voxelObject.XSize) +
                                (voxelObject.XSize - 1),
                                (anchorY == AnchorY.Bottom
                                    ? 0
                                    : anchorY == AnchorY.Center
                                        ? (ySize / 2) - (voxelObject.YSize / 2)
                                        : ySize - voxelObject.YSize) +
                                (voxelObject.YSize - 1),
                                (anchorZ == AnchorZ.Front
                                    ? 0
                                    : anchorZ == AnchorZ.Center
                                        ? (zSize / 2) - (voxelObject.ZSize / 2)
                                        : zSize - voxelObject.ZSize) +
                                (voxelObject.ZSize - 1));


                        foreach (Frame frame in voxelObject.Frames)
                        {
                            Voxel[] newVox = new Voxel[xSize * ySize * zSize];

                            if (fillVoxels)
                            {
                                for (int x = 0; x < xSize; x++)
                                {
                                    for (int y = 0; y < ySize; y++)
                                    {
                                        for (int z = 0; z < zSize; z++)
                                        {
                                            newVox[x + xSize * (y + ySize * z)] = new Voxel()
                                            {
                                                State = VoxelState.Active,
                                                Color = voxelObject.PaletteColors[0],
                                                Value = 128
                                            }
                                        }
                                    }
                                }
                                ;
                            }

                            int destX = copyDestBox.BottomLeftFront.X;
                            int destY = copyDestBox.BottomLeftFront.Y;
                            int destZ = copyDestBox.BottomLeftFront.Z;
                            for (int x = 0; x < voxelObject.XSize; x++)
                            {
                                for (int y = 0; y < voxelObject.YSize; y++)
                                {
                                    for (int z = 0; z < voxelObject.ZSize; z++)
                                    {
                                        if (destX < 0 || destY < 0 || destZ < 0 || destX >= xSize ||
                                            destY >= ySize || destZ >= zSize)
                                        {
                                            destZ++;
                                            continue;
                                        }

                                        newVox[destX + xSize * (destY + ySize * destZ)] =
                                            frame.Voxels[x + frame.XSize * (y + frame.YSize * z)];
                                        destZ++;
                                    }
                                    destZ = copyDestBox.BottomLeftFront.Z;
                                    destY++;
                                }
                                destY = copyDestBox.BottomLeftFront.Y;
                                destX++;
                            }

                            frame.XSize         = xSize;
                            frame.YSize         = ySize;
                            frame.ZSize         = zSize;
                            frame.EditingVoxels = null;
                            frame.Voxels        = newVox;
                        }


                        voxelObject.XSize = xSize;
                        voxelObject.YSize = ySize;
                        voxelObject.ZSize = zSize;
                    }


                    voxelObject.CreateChunks();

                    voxelObject.SaveForSerialize();

                    //EditorUtility.SetDirty(voxelObject);


                    Close();
                }
            }
            // }
            if (GUILayout.Button("Cancel"))
            {
                Close();
            }
            EditorGUILayout.EndHorizontal();
        }
        public static void FromMagica(BinaryReader stream, GameObject root, float voxelSize, bool centerPivot)
        {
            // check out http://voxel.codeplex.com/wikipage?title=VOX%20Format&referringTitle=Home for the file format used below
            // we're going to return a voxel chunk worth of data

            Color32[] colors = new Color32[256];

            for (int i = 1; i < 256; i++)
            {
                uint hexval = defaultColors[i];
                byte cb     = (byte)((hexval >> 16) & 0xFF);
                byte cg     = (byte)((hexval >> 8) & 0xFF);
                byte cr     = (byte)((hexval >> 0) & 0xFF);

                colors[i - 1] = new Color32(cr, cg, cb, 255);
            }

            MagicaVoxelData[]        voxelData = null;
            List <MagicaVoxelData[]> frames    = new List <MagicaVoxelData[]>();

            //int numFrames = 1;


            string magic = new string(stream.ReadChars(4));

            //int version =
            stream.ReadInt32();


            // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
            if (magic == "VOX ")
            {
                int  sizex = 0, sizey = 0, sizez = 0;
                bool subsample = false;

                while (stream.BaseStream.Position < stream.BaseStream.Length)
                {
                    // each chunk has an ID, size and child chunks
                    char[] chunkId   = stream.ReadChars(4);
                    int    chunkSize = stream.ReadInt32();
                    //int childChunks =
                    stream.ReadInt32();
                    string chunkName = new string(chunkId);

                    if (chunkName == "PACK")
                    {
                        stream.ReadInt32();
                    }
                    else if (chunkName == "SIZE")
                    {
                        sizex = stream.ReadInt32();
                        sizez = stream.ReadInt32();
                        sizey = stream.ReadInt32();

                        //if (sizex > 32 || sizey > 32) subsample = true;

                        stream.ReadBytes(chunkSize - 4 * 3);
                    }
                    else if (chunkName == "XYZI")
                    {
                        // XYZI contains n voxels
                        int numVoxels = stream.ReadInt32();
                        // int div = (subsample ? 2 : 1);

                        // each voxel has x, y, z and color index values
                        voxelData = new MagicaVoxelData[numVoxels];
                        for (int i = 0; i < voxelData.Length; i++)
                        {
                            voxelData[i] = new MagicaVoxelData(stream, subsample);
                        }

                        frames.Add(voxelData);
                    }
                    else if (chunkName == "RGBA")
                    {
                        for (int i = 0; i < 256; i++)
                        {
                            byte r = stream.ReadByte();
                            byte g = stream.ReadByte();
                            byte b = stream.ReadByte();
                            byte a = stream.ReadByte();

                            // convert RGBA to our custom voxel format (16 bits, 0RRR RRGG GGGB BBBB)
                            colors[i] = new Color32(r, g, b, a);
                        }
                    }
                    else
                    {
                        stream.ReadBytes(chunkSize);    // read any excess bytes
                    }
                }

                if (voxelData.Length == 0)
                {
                    return;                        // failed to read any valid voxel data
                }
                if (root != null)
                {
                    Volume voxelVolume = root.GetComponent <Volume>();

                    voxelVolume.XSize = sizex;
                    voxelVolume.YSize = sizey;
                    voxelVolume.ZSize = sizez;
                    voxelVolume.Frames[voxelVolume.CurrentFrame].XSize  = sizex;
                    voxelVolume.Frames[voxelVolume.CurrentFrame].YSize  = sizey;
                    voxelVolume.Frames[voxelVolume.CurrentFrame].ZSize  = sizez;
                    voxelVolume.Frames[voxelVolume.CurrentFrame].Voxels = new Voxel[sizex * sizey * sizez];
                    for (int i = 0; i < voxelVolume.Frames[voxelVolume.CurrentFrame].Voxels.Length; i++)
                    {
                        voxelVolume.Frames[voxelVolume.CurrentFrame].Voxels[i].Value = 128;
                    }
                    voxelVolume.VoxelSize = voxelSize;

                    if (centerPivot)
                    {
                        voxelVolume.Pivot = (new Vector3(voxelVolume.XSize, voxelVolume.YSize, voxelVolume.ZSize) * voxelVolume.VoxelSize) / 2f;
                        voxelVolume.UpdatePivot();
                    }

                    foreach (MagicaVoxelData[] d in frames)
                    {
                        foreach (MagicaVoxelData v in d)
                        {
                            try
                            {
                                voxelVolume.Frames[voxelVolume.CurrentFrame].Voxels[v.x + sizex * (v.z + sizey * v.y)] = new Voxel()
                                {
                                    State = VoxelState.Active,
                                    Color = colors[v.color - 1],
                                    Value = 128
                                };
                            }
                            catch (Exception)
                            {
                                Debug.Log(v.x + " " + v.y + " " + v.z);
                            }
                        }

                        if (frames.IndexOf(d) < frames.Count - 1)
                        {
                            voxelVolume.AddFrame(voxelVolume.CurrentFrame + 1);
                            voxelVolume.Frames[voxelVolume.CurrentFrame].Voxels = new Voxel[sizex * sizey * sizez];
                        }
                    }

                    voxelVolume.SetFrame(0);
                    voxelVolume.CreateChunks();
                    voxelVolume.SaveForSerialize();
                }
            }
        }
Esempio n. 9
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Editor", new GUIStyle()
            {
                fontStyle = FontStyle.Bold
            });

            if (!allRuntimeOnlyMesh)
            {
                if (GUILayout.Button(allEditorsEnabled ? "Stop Editing All" : "Start Editing All"))
                {
                    foreach (Volume v in mpvObject.Volumes)
                    {
                        v.IsEnabledForEditing = !allEditorsEnabled;
                        v.PaintMode           = EditorPaintMode.Color;

                        v.UpdateAllChunks();
                    }

                    SceneView.RepaintAll();
                    allEditorsEnabled = AllEditorsEnabled();
                }
            }

            rtomCheckBox = EditorGUILayout.ToggleLeft(new GUIContent(" Runtime-Only Mesh"),
                                                      rtomCheckBox);
            if (rtomCheckBox != allRuntimeOnlyMesh)
            {
                foreach (Volume v in mpvObject.Volumes)
                {
                    v.IsEnabledForEditing = false;
                    v.RuntimOnlyMesh      = !allRuntimeOnlyMesh;

                    v.CreateChunks();
                    v.UpdateAllChunks();
                }

                allRuntimeOnlyMesh = AllRuntimeOnlyMesh();
                allEditorsEnabled  = AllEditorsEnabled();
            }

            EditorGUILayout.Space();

            EditorGUILayout.LabelField("Size", new GUIStyle()
            {
                fontStyle = FontStyle.Bold
            });
            float size = EditorGUILayout.FloatField("Voxel Size:", voxelSizeProperty.floatValue);

            if (size != voxelSizeProperty.floatValue && size > 0f)
            {
                voxelSizeProperty.floatValue = size;
                voxelSize = voxelSizeProperty.floatValue;
                foreach (Volume v in mpvObject.Volumes)
                {
                    v.VoxelSize = voxelSize;

                    v.CreateChunks();
                }

                mpvObject.RepositionParts();
            }

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Pivot", new GUIStyle()
            {
                fontStyle = FontStyle.Bold
            });
            pivotProperty.vector3Value = EditorGUILayout.Vector3Field("", pivotProperty.vector3Value, null);
            if (pivotProperty.vector3Value != mpvObject.Pivot)
            {
                pivot           = pivotProperty.vector3Value;
                mpvObject.Pivot = pivot;
                mpvObject.RepositionParts();
            }
            if (GUILayout.Button("Set to Center"))
            {
                mpvObject.SetPivotToCenter();
            }

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Individual Pivots", new GUIStyle()
            {
                fontStyle = FontStyle.Bold
            });

            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Set all to Center"))
            {
                foreach (Volume v in mpvObject.Volumes)
                {
                    Vector3 piv = (new Vector3(v.XSize, v.YSize, v.ZSize) * v.VoxelSize) / 2f;
                    v.Pivot = piv;
                    v.UpdatePivot();
                }
            }
            if (GUILayout.Button("Set all to Zero"))
            {
                foreach (Volume v in mpvObject.Volumes)
                {
                    v.Pivot = Vector3.zero;
                    v.UpdatePivot();
                }
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Collision Mode", new GUIStyle()
            {
                fontStyle = FontStyle.Bold
            });
            collisionMode.enumValueIndex =
                Convert.ToInt16(EditorGUILayout.EnumPopup((CollisionMode)collisionMode.enumValueIndex));
            if (collisionMode.enumValueIndex != Convert.ToInt16(mpvObject.CollisionMode))
            {
                foreach (Volume v in mpvObject.Volumes)
                {
                    v.ChangeCollisionMode((CollisionMode)collisionMode.enumValueIndex);
                }
            }
            if (collisionMode.enumValueIndex > 0)
            {
                separateColliderMesh.boolValue = EditorGUILayout.ToggleLeft(new GUIContent(" Generate collider mesh separately (Edit-time only)"),
                                                                            separateColliderMesh.boolValue);
                if (separateColliderMesh.boolValue != mpvObject.GenerateMeshColliderSeparately)
                {
                    foreach (Volume v in mpvObject.Volumes)
                    {
                        v.GenerateMeshColliderSeparately = separateColliderMesh.boolValue;
                        v.UpdateAllChunks();
                    }
                }

                if (separateColliderMesh.boolValue)
                {
                    EditorGUILayout.LabelField("Collider Meshing Mode", new GUIStyle()
                    {
                        fontStyle = FontStyle.Bold
                    });
                    colliderMeshingMode.enumValueIndex =
                        Convert.ToInt16(EditorGUILayout.EnumPopup((MeshingMode)colliderMeshingMode.enumValueIndex));
                    if (colliderMeshingMode.enumValueIndex != Convert.ToInt16(mpvObject.MeshColliderMeshingMode))
                    {
                        foreach (Volume v in mpvObject.Volumes)
                        {
                            v.MeshColliderMeshingMode = (MeshingMode)colliderMeshingMode.enumValueIndex;
                            v.UpdateAllChunks();
                        }
                    }
                }
            }

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Rendering", new GUIStyle()
            {
                fontStyle = FontStyle.Bold
            });
            EditorGUILayout.LabelField("Meshing Mode", new GUIStyle()
            {
                fontStyle = FontStyle.Bold
            });
            meshingMode.enumValueIndex =
                Convert.ToInt16(EditorGUILayout.EnumPopup((MeshingMode)meshingMode.enumValueIndex));
            if (meshingMode.enumValueIndex != Convert.ToInt16(mpvObject.MeshingMode))
            {
                foreach (Volume v in mpvObject.Volumes)
                {
                    v.MeshingMode = (MeshingMode)meshingMode.enumValueIndex;
                    v.UpdateAllChunks();
                }
            }

            selfShadeInt.floatValue = EditorGUILayout.Slider("Self-Shading Intensity", selfShadeInt.floatValue, 0, 1);
            if (selfShadeInt.floatValue != mpvObject.SelfShadingIntensity)
            {
                foreach (Volume v in mpvObject.Volumes)
                {
                    v.SelfShadingIntensity = selfShadeInt.floatValue;
                    v.UpdateAllChunks();
                }
            }

            material.objectReferenceValue = EditorGUILayout.ObjectField("Material: ", material.objectReferenceValue, typeof(Material),
                                                                        false);
            if (material.objectReferenceValue != mpvObject.Material)
            {
                foreach (Volume v in mpvObject.Volumes)
                {
                    v.Material = (Material)material.objectReferenceValue;
                    v.UpdateAllChunks();
                }
            }

            EditorGUILayout.Space();
            if (GUILayout.Button(new GUIContent("Mesh-Only Copy", "Create a copy of this Volume with mesh(es) only")))
            {
                GameObject newMPV = new GameObject(target.name + " (Copy)");
                foreach (Volume vol in mpvObject.Volumes)
                {
                    GameObject bake = Instantiate(EditorUtility.VoxelVolumePrefab, Vector3.zero, Quaternion.identity) as GameObject;

                    Volume v = bake.GetComponent <Volume>();
                    v.XSize                          = vol.XSize;
                    v.YSize                          = vol.YSize;
                    v.ZSize                          = vol.ZSize;
                    v.MeshingMode                    = vol.MeshingMode;
                    v.MeshColliderMeshingMode        = vol.MeshColliderMeshingMode;
                    v.GenerateMeshColliderSeparately = vol.GenerateMeshColliderSeparately;
                    v.Material                       = vol.Material;
                    for (int f = 0; f < vol.Frames.Count; f++)
                    {
                        v.AddFrame(f);
                        v.Frames[f].Voxels = vol.Frames[f].Voxels;
                    }
                    v.CreateChunks();
                    v.ChangeCollisionMode(vol.CollisionMode);
                    v.UpdateAllChunks();

                    bake.tag  = "Untagged";
                    bake.name = vol.name;
                    DestroyImmediate(bake.GetComponent <Volume>());
                    DestroyImmediate(bake.transform.FindChild("Hitbox").gameObject);
                    for (int i = 0; i < bake.transform.childCount; i++)
                    {
                        GameObject o = bake.transform.GetChild(i).gameObject;
                        if (o.GetComponent <Frame>() != null)
                        {
                            DestroyImmediate(o.GetComponent <Frame>());
                            for (int c = 0; c < o.transform.FindChild("Chunks").childCount; c++)
                            {
                                GameObject chunk = o.transform.FindChild("Chunks").GetChild(c).gameObject;
                                if (chunk.GetComponent <Chunk>() != null)
                                {
                                    DestroyImmediate(chunk.GetComponent <Chunk>());
                                }
                            }
                        }
                    }

                    bake.transform.parent        = newMPV.transform;
                    bake.transform.localPosition = vol.transform.localPosition;
                }
            }

            serializedObject.ApplyModifiedProperties();
        }