コード例 #1
0
 // Use this for initialization
 private void Start()
 {
     if (PicaVoxelVolume == null)
     {
         return;
     }
     originalVoxels = new Voxel[PicaVoxelVolume.XSize * PicaVoxelVolume.YSize * PicaVoxelVolume.ZSize];
     Helper.CopyVoxelsInBox(ref PicaVoxelVolume.GetCurrentFrame().Voxels, ref originalVoxels,
                            new PicaVoxelPoint(PicaVoxelVolume.XSize, PicaVoxelVolume.YSize, PicaVoxelVolume.ZSize),
                            new PicaVoxelPoint(PicaVoxelVolume.XSize, PicaVoxelVolume.YSize, PicaVoxelVolume.ZSize), true);
     PicaVoxelVolume.GetCurrentFrame().Voxels =
         new Voxel[PicaVoxelVolume.XSize * PicaVoxelVolume.YSize * PicaVoxelVolume.ZSize];
     PicaVoxelVolume.UpdateAllChunks();
     radius = StartRadius;
     gameObject.SetActive(false);
 }
コード例 #2
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();
        }
コード例 #3
0
ファイル: MeshScanner.cs プロジェクト: unitycoder/PicaVoxel
        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();
        }
コード例 #4
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();
        }