Beispiel #1
0
        protected void assignMesh(GameObject meshObject, SubstanceCollection substances, Dictionary <int, int> vertices, List <int> triangles, byte[] MATS)
        {
            byte[] substanceArray = substances.getSubstances();
            bool   hasGrass       = substanceArray.Length == 1 && control.voxelSubstances[substanceArray[0]].grassMaterial != null;
            int    vertexCount    = vertices.Count;

            if (hasGrass)
            {
                vertexCount *= 2;
            }
            Vector3[] verts = new Vector3[vertexCount];
            Vector3[] norms = new Vector3[vertexCount];
            Vector2[] uvs   = new Vector2[vertexCount];

            // create the vertex, normal, and uv arrays
            foreach (int index in vertices.Keys)
            {
                int i = vertices[index];
                norms[i] = NORMS[index];
                verts[i] = VERTS[index];
                switch (substances.getSubstanceRelativeIndex(MATS[index]))
                {
                case 0:
                    uvs[i] = Vector2.zero;
                    break;

                case 1:
                    uvs[i] = Vector2.right;
                    break;

                case 2:
                    uvs[i] = Vector2.up;
                    break;
                }
            }
            if (hasGrass)
            {
                VoxelSubstance substance = control.voxelSubstances[substanceArray[0]];
                for (int i = vertices.Count; i < vertexCount; ++i)
                {
                    int index = i - vertices.Count;
                    norms[i] = norms[index];
                    verts[i] = verts[index];
                    if (norms[i].y > substance.grassMinFlatness)
                    {
                        float factor = (norms[i].y - substance.grassMinFlatness + 0.1f) / (1 - substance.grassMinFlatness + 0.1f);
                        verts[i].y += substance.grassHeight * factor;
                        uvs[i]      = new Vector2(0, 1 - factor);
                    }
                    else
                    {
                        uvs[i] = Vector2.up;
                    }
                }
            }

            // apply the render materials to the renderer
            MeshRenderer   rend   = meshObject.GetComponent <MeshRenderer>();
            PhysicMaterial phyMat = null;

            if (substanceArray.Length == 1)
            {
                Material[] materials = new Material[1];
                if (hasGrass)
                {
                    materials    = new Material[2];
                    materials[1] = control.voxelSubstances[substanceArray[0]].grassMaterial;
                }
                materials[0] = control.voxelSubstances[substanceArray[0]].renderMaterial;
                materials[0].EnableKeyword("IS_BASE");
                rend.sharedMaterials = materials;
                phyMat = control.voxelSubstances[substanceArray[0]].physicsMaterial;
            }
            else
            {
                Material[] materials = new Material[substanceArray.Length];
                for (int i = 0; i < materials.Length; ++i)
                {
                    Material material = new Material(control.voxelSubstances[substanceArray[i]].blendMaterial);
                    material.renderQueue = i;
                    if (!control.saveMeshes)
                    {
                        material.hideFlags = HideFlags.HideAndDontSave;
                    }
                    switch (i)
                    {
                    case 0:
                        material.EnableKeyword("IS_BASE");
                        phyMat = control.voxelSubstances[substanceArray[i]].physicsMaterial;
                        break;

                    case 1:
                        material.EnableKeyword("IS_X");
                        break;

                    case 2:
                        material.EnableKeyword("IS_Y");
                        break;
                    }
                    materials[i] = material;
                }
                rend.materials = materials;
            }

            Mesh m = meshObject.GetComponent <MeshFilter>().sharedMesh;

            m.Clear();
            int[] triangleArray = triangles.ToArray();

            // reduce mesh
            if (control.reduceMeshes)
            {
                HashSet <int> verticesRemoved = VoxelMeshReducer.reduce(ref verts, ref triangleArray, control.reductionAmount);
                norms = VoxelMeshReducer.removeEntries(norms, verticesRemoved);
                uvs   = VoxelMeshReducer.removeEntries(uvs, verticesRemoved);
            }

            m.vertices = verts;
            m.normals  = norms;
            m.uv       = uvs;

            if (hasGrass)
            {
                m.subMeshCount = 2;
                int[] grassTriangles = new int[triangleArray.Length];
                for (int i = 0; i < grassTriangles.Length; ++i)
                {
                    grassTriangles[i] = triangleArray[i] + vertices.Count;
                }
                m.SetTriangles(grassTriangles, 1);
            }
            else
            {
                m.subMeshCount = 1;
            }

            m.SetTriangles(triangleArray, 0);
            m.RecalculateBounds();
            m.Optimize();
            rend.enabled = true;

            // add a collider for the mesh
            if (control.createColliders)
            {
                MeshCollider collider = meshObject.AddComponent <MeshCollider>();
                collider.material = phyMat;
                if (hasGrass)
                {
                    Mesh      mesh     = new Mesh();
                    Vector3[] colVerts = new Vector3[vertices.Count];
                    Vector3[] colNorms = new Vector3[vertices.Count];
                    Array.Copy(verts, colVerts, colVerts.Length);
                    Array.Copy(norms, colNorms, colNorms.Length);
                    mesh.vertices = colVerts;
                    mesh.normals  = colNorms;
                    mesh.SetTriangles(triangles, 0);
                    mesh.RecalculateBounds();
                    mesh.Optimize();
                    collider.sharedMesh = mesh;
                }
                else
                {
                    collider.sharedMesh = m;
                }
//				collider.hideFlags = /*HideFlags.HideInInspector | */HideFlags.DontSaveInBuild | HideFlags.DontSaveInEditor;
            }
        }
Beispiel #2
0
        public void applyMesh(byte detailLevel, int x, int y, int z)
        {
            applied = true;
            if (TRIS.Length < 1 && (obs == null || obs.Length < 1))
            {
                return;
            }

            // convert the vertexSubstances structure into a more directly usable format
            byte[] substanceToVertices = new byte[VERTS.Length];
            foreach (int index in vertices.Keys)
            {
                if (vertexSubstances.ContainsKey(index))
                {
                    byte substance = vertexSubstances[index];
                    substanceToVertices[(int)vertices[index]] = substance;
                }
            }

            // build triangle and vertex lists for each mesh from the master triangle list
            Dictionary <SubstanceCollection, Dictionary <int, int> > substanceVertices  = new Dictionary <SubstanceCollection, Dictionary <int, int> >();
            Dictionary <SubstanceCollection, List <int> >            substanceTriangles = new Dictionary <SubstanceCollection, List <int> >();

            for (int i = 0; i < TRIS.Length; i += 3)
            {
                SubstanceCollection subs = new SubstanceCollection();
                for (int j = 0; j < 3; ++j)
                {
                    byte sub = substanceToVertices[TRIS[i + j]];
                    subs.add(sub);
                }
                if (!substanceTriangles.ContainsKey(subs))
                {
                    substanceTriangles[subs] = new List <int>(TRIS.Length / substanceToVertices.Length);
                    substanceVertices[subs]  = new Dictionary <int, int>();
                }
                List <int>            specificSubstanceTriangles     = substanceTriangles[subs];
                Dictionary <int, int> specificSubstanceVertexIndices = substanceVertices[subs];
                for (int j = 0; j < 3; ++j)
                {
                    int vertexIndex = TRIS[i + j];
                    if (!specificSubstanceVertexIndices.ContainsKey(vertexIndex))
                    {
                        specificSubstanceVertexIndices[vertexIndex] = specificSubstanceVertexIndices.Count;
                    }
                    specificSubstanceTriangles.Add(specificSubstanceVertexIndices[vertexIndex]);
                }
            }

            // create and initialize the game objects which will have the mesh renderers and colliders attached to them
            removePolyCount();
            GameObject[] oldObs = (obs == null)? new GameObject[0]: obs;
            obs = new GameObject[substanceTriangles.Count];
            if (oldObs.Length > obs.Length)
            {
                Array.Copy(oldObs, obs, obs.Length);
                for (int i = obs.Length; i < oldObs.Length; ++i)
                {
                    GameObject.DestroyImmediate(oldObs[i]);
                }
            }
            else
            {
                Array.Copy(oldObs, obs, oldObs.Length);
                for (int i = oldObs.Length; i < obs.Length; ++i)
                {
                    obs[i] = createRendererGameObject();
                }
            }
            foreach (GameObject ob in obs)
            {
                foreach (MeshCollider col in ob.GetComponents <MeshCollider>())
                {
                    GameObject.DestroyImmediate(col);
                }
            }

            // Assign vertex data to the game object meshes
            int obIndex = 0;

            foreach (SubstanceCollection substances in substanceTriangles.Keys)
            {
                assignMesh(obs[obIndex], substances, substanceVertices[substances], substanceTriangles[substances], substanceToVertices);
                ++obIndex;
            }

            //			// refresh collider
            //			if (control.createColliders) {
            //				collider.enabled = false;
            //				if (VoxelBlock.isRenderSize(size, control))
            //					collider.enabled = true;
            //			}
            addPolyCount();
            ((VoxelBlock)control.getHead().get(this.index)).clearSubRenderers(false, control);
            control.head.clearSuperRenderers(detailLevel, x, y, z, control);
        }