Пример #1
0
//threaded mesh creation
// basically just creates the triangles and vertices on a thread then adds them to a mesh
//in the main thread
/// <summary>
/// Creates the vertices.
/// </summary>
        public void CreateVertices()
        {
            canCreatemesh = false;

            //create the verts
            verts = MarchingCubes.CreateVertices(Voxels, this, 2, 2, lodLevel);

            //store the size so as to avoid garbage creation
            size = verts.Length;

            //create normals
            normals = MeshFactory.CalculateNormals(Voxels, size, verts, lodLevel);

            //create colors

            int V = size;

            uv = new Color[size];
            for (int i = 0; i < size; i++)
            {
                int x = Mathf.RoundToInt((verts[i].x - normals[i].x) / VoxelTerrainEngine.TriSize[lodLevel]);
                int y = Mathf.RoundToInt((verts[i].y - normals[i].y) / VoxelTerrainEngine.TriSize[lodLevel]);
                int z = Mathf.RoundToInt((verts[i].z - normals[i].z) / VoxelTerrainEngine.TriSize[lodLevel]);

                //conversion from voxel value to voxel type
                //seems to work well
                byte vox = Materials[x, y, z];

                //basically each value gets assigned a color of 0.5 to 1.0
                //in theory each decimal could be a voxel type
                if (vox == (int)VoxelType.Stone)
                {
                    uv[i] = new Color(1, 0, 0, 0);
                }

                else if (vox == (int)VoxelType.Grass)
                {
                    uv[i] = new Color(0, 1, 0, 0);
                }

                else if (vox == (int)VoxelType.SandStone)
                {
                    uv[i] = new Color(0, 0, 1, 0);
                }

                else if (vox == (int)VoxelType.Dirt)
                {
                    uv[i] = new Color(0, 0, 0, 1);
                }
            }
            canCreatemesh = true;
            VoxelTerrainEngine.MeshChunks.Enqueue(this);
        }
Пример #2
0
/// <summary>
/// Creates the voxels.
/// </summary>
        public void CreateVoxels()
        {
            if (VoxelSaver.GetBool("hasSavedChunk") == false && hasVoxels == false)
            {
                Voxels    = MeshFactory.CreateVoxels(Voxels, RealPos - new Vector3(2, 2, 2), this, lodLevel);
                hasVoxels = true;
            }

            else if (VoxelSaver.GetBool("hasSavedChunk") && hasVoxels == false && hasloaded == false)
            {
                LoadVoxels();
                hasVoxels = true;
                hasloaded = true;
            }
            VoxelTerrainEngine.GenerateVertices.Enqueue(this);
        }
Пример #3
0
        //calculate normals for the mesh
        public static Vector3[] CalculateNormals(byte[,,] m_voxels, int size, Vector3 [] verts, int lod)
        {
            Vector3[,,] m_normals;
            Vector3[] normals = new Vector3[size];

            int w = m_voxels.GetLength(0);

            int h = m_voxels.GetLength(1);

            int l = m_voxels.GetLength(2);

            //This calculates the normal of each voxel. If you have a 3d array of data
            //the normal is the derivitive of the x, y and z axis.
            //Normally you need to flip the normal (*-1) but it is not needed in this case.
            //If you dont call this function the normals that Unity generates for a mesh are used.



            m_normals = new Vector3[w, h, l];

            for (int x = 2; x < w - 2; x++)
            {
                for (int y = 2; y < h - 2; y++)
                {
                    for (int z = 2; z < l - 2; z++)
                    {
                        float dx = m_voxels[x + 1, y, z] - m_voxels[x - 1, y, z];
                        float dy = m_voxels[x, y + 1, z] - m_voxels[x, y - 1, z];
                        float dz = m_voxels[x, y, z + 1] - m_voxels[x, y, z - 1];

                        m_normals[x, y, z] = Vector3.Normalize(new Vector3(dx, dy, dz));
                    }
                }
            }
            for (int i = 0; i < size; i++)
            {
                normals[i] = MeshFactory.TriLinearInterpNormal(verts[i] / VoxelTerrainEngine.TriSize[lod], m_normals);
            }

            return(normals);
        }
Пример #4
0
        public static Vector3[] CalculateNormalsRemove(byte[,,] m_voxels, int size, Vector3 [] verts)
        {
            Vector3[] normals = new Vector3[size];
            //float startTime = Time.realtimeSinceStartup;
            int w = m_voxels.GetLength(0);
            int h = m_voxels.GetLength(1);
            int l = m_voxels.GetLength(2);

            //This calculates the normal of each voxel. If you have a 3d array of data
            //the normal is the derivitive of the x, y and z axis.
            //Normally you need to flip the normal (*-1) but it is not needed in this case.
            //If you dont call this function the normals that Unity generates for a mesh are used.



            m_normals2 = new Vector3[w, h, l];

            for (int x = 2; x < w - 2; x++)
            {
                for (int y = 2; y < h - 2; y++)
                {
                    for (int z = 2; z < l - 2; z++)
                    {
                        float dx = m_voxels[x + 1, y, z] - m_voxels[x - 1, y, z];
                        float dy = m_voxels[x, y + 1, z] - m_voxels[x, y - 1, z];
                        float dz = m_voxels[x, y, z + 1] - m_voxels[x, y, z - 1];

                        m_normals2[x, y, z] = Vector3.Normalize(new Vector3(dx, dy, dz));
                    }
                }
            }
            for (int i = 0; i < size; i++)
            {
                normals[i] = MeshFactory.TriLinearInterp(verts[i]);
            }
            //Debug.Log("Calculate normals time = " + (Time.realtimeSinceStartup-startTime).ToString() );

            return(normals);
        }
Пример #5
0
        //this is called if the voxel has changed and needs to be reloaded
        //had to do it this way or else we end up with strange terrain errors

        public void CreateMeshesWithVoxels()
        {
            //set flag so this mesh wont get created twice
            canCreatemesh = false;

            verts = MeshFactory.CreateverticesVoxels(Voxels, this);
            //cache vertices size to avoid gc allocation

            size = verts.Length;

            normals = MeshFactory.CalculateNormalsRemove(Voxels, size, verts);

            control = new Color[size];

            float R = 0;
            float G = 0;
            float B = 0;
            float A = 0;

            for (int i = 0; i < size; i++)
            {
                R = 0;
                G = 0;
                B = 0;
                A = 0;
                int x = Mathf.RoundToInt(verts[i].x - normals[i].x);

                int y = Mathf.RoundToInt(verts[i].y - normals[i].y);

                int z = Mathf.RoundToInt(verts[i].z - normals[i].z);

                byte vox = (byte)((float)Voxels[x, y, z] / 255 * 8);

                if (vox == (int)VoxelType.Dirt)
                {
                    R = 0.5f;
                }

                if (vox == (int)VoxelType.Stone)
                {
                    G = 0.5f;
                }

                if (vox == (int)VoxelType.SandStone)
                {
                    B = 0.5f;
                }

                if (vox == (int)VoxelType.Grass)
                {
                    A = 0.5f;
                }

                if (vox == (int)VoxelType.Iron)
                {
                    R = 1;
                }

                if (vox == (int)VoxelType.Gold)
                {
                    G = 1;
                }

                if (vox == (int)VoxelType.GunPowder)
                {
                    B = 1;
                }

                if (vox == (int)VoxelType.Tungsten)
                {
                    A = 1;
                }

                control[i] = new Color(R, G, B, A);
            }
            canCreatemesh = true;
        }
Пример #6
0
//threaded mesh creation
// basically just creates the triangles and vertices on a thread then adds them to a mesh
//in the main thread
        public void CreateMeshesAndvoxels(bool MakeNewVoxels)
        {
            canCreatemesh = false;

            if (MakeNewVoxels && VoxelSaver.GetBool("hasSavedChunk") == false)
            {
                Voxels = MeshFactory.CreateVoxels(Voxels, m_pos, this, generator.noise);
            }

            else
            {
                LoadVoxels();
            }

            //create the verts
            verts = MeshFactory.MarchingCubes.CreateVertices(Voxels, this, 2, 2);

            //store the size so as to avoid garbage creation
            size = verts.Length;

            //create normals
            normals = MeshFactory.CalculateNormals(Voxels, size, verts);

            //create colors
            control = new Color[size];

            float R = 0;
            float G = 0;
            float B = 0;
            float A = 0;

            for (int i = 0; i < size; i++)
            {
                R = 0;
                G = 0;
                B = 0;
                A = 0;

                int x = Mathf.RoundToInt(verts[i].x - normals[i].x);
                int y = Mathf.RoundToInt(verts[i].y - normals[i].y);
                int z = Mathf.RoundToInt(verts[i].z - normals[i].z);

                //conversion from voxel value to voxel type
                //seems to work well
                byte vox = (byte)((float)Voxels[x, y, z] / 255 * 8);
                //basically each value gets assigned a color of 0.5 to 1.0
                //in theory each decimal could be a voxel type
                if (vox == (int)VoxelType.Dirt)
                {
                    R = 0.5f;
                }
                if (vox == (int)VoxelType.Stone)
                {
                    G = 0.5f;
                }
                if (vox == (int)VoxelType.SandStone)
                {
                    B = 0.5f;
                }
                if (vox == (int)VoxelType.Grass)
                {
                    A = 0.5f;
                }

                if (vox == (int)VoxelType.Iron)
                {
                    R = 1;
                }
                if (vox == (int)VoxelType.Gold)
                {
                    G = 1;
                }
                if (vox == (int)VoxelType.GunPowder)
                {
                    B = 1;
                }
                if (vox == (int)VoxelType.Tungsten)
                {
                    A = 1;
                }
                control[i] = new Color(R, G, B, A);
            }
            canCreatemesh = true;
        }