예제 #1
0
        private void ExportMesh(int meshIndex)
        {
            GrnMesh mesh = this.File.Meshes[meshIndex];
            string mainObject = "mainObject";
            Maxscript.Command("{0} = grnMeshes[{1}]", mainObject, meshIndex + 1);
            string mainMesh = Maxscript.SnapshotAsMesh("mainMesh", mainObject);
            mesh.DataExtensionIndex = this.File.AddDataExtension(Maxscript.QueryString("{0}.name", mainObject));

            Dictionary<int, int> matIdMapping = this.ExportMeshMaterial(mainObject);

            // Setup Normals
            Maxscript.Command("max modify mode");
            string tempObject = "tempObject";
            Maxscript.Command("{0} = Editable_Mesh()", tempObject);
            Maxscript.Command("{0}.mesh = {1}", tempObject, mainMesh);
            Maxscript.Command("addModifier {0} (Edit_Normals()) ui:off", tempObject);
            Maxscript.Command("modPanel.setCurrentObject {0}.modifiers[#edit_normals] ui:true", tempObject);

            int numVertices = Maxscript.QueryInteger("meshop.getnumverts {0}", mainMesh);
            int numFaces = Maxscript.QueryInteger("meshop.getnumfaces {0}", mainMesh);

            for (int i = 0; i < numVertices; i++)
            {
                try
                {
                    Maxscript.Command("vertex = meshGetVertFunc {0} {1}", mainMesh, i + 1);
                    mesh.Vertices.Add(new Vector3D(
                        Maxscript.QueryFloat("vertex.x"),
                        Maxscript.QueryFloat("vertex.y"),
                        Maxscript.QueryFloat("vertex.z")));
                }
                catch (Exception ex)
                {
                    throw new Exception("Error importing vertex at index " + (i + 1) + ".", ex);
                }
            }

            int numNorms = Maxscript.QueryInteger("{0}.modifiers[#edit_normals].GetNumNormals()", tempObject);
            Maxscript.Command("getVertNormalFunc = {0}.modifiers[#edit_normals].GetNormal", tempObject);
            for (int i = 0; i < numNorms; ++i)
            {
                try
                {
                    Maxscript.Command("currentNormal = getVertNormalFunc {0}", i + 1);
                    mesh.Normals.Add(new Vector3D(
                        Maxscript.QueryFloat("currentNormal.x"),
                        Maxscript.QueryFloat("currentNormal.y"),
                        Maxscript.QueryFloat("currentNormal.z")));
                }
                catch (Exception ex)
                {
                    throw new Exception("Error importing normal at index " + (i + 1) + ".", ex);
                }
            }

            int numTexVertices = Maxscript.QueryInteger("meshop.getnumtverts {0}", mainMesh);
            for (int i = 0; i < numTexVertices; i++)
            {
                try
                {
                Maxscript.Command("tVert = meshGetMapVertFunc {0} 1 {1}", mainMesh, i + 1);
                mesh.TextureCoordinates.Add(new Vector3D(
                    Maxscript.QueryFloat("tVert.x"),
                    1f-Maxscript.QueryFloat("tVert.y"),
                    Maxscript.QueryFloat("tVert.z")));
                }
                catch (Exception ex)
                {
                    throw new Exception("Error importing texture vertex at index " + (i + 1) + ".", ex);
                }
            }

            Maxscript.Command("meshGetNormalIdFunc = {0}.modifiers[#edit_normals].GetNormalID", tempObject);
            for (int i = 0; i < numFaces; ++i)
            {
                Face f = new Face();
                Int32 matIndex = Maxscript.QueryInteger("getFaceMatID {0} {1}", mainMesh, i + 1);
                if (matIdMapping.ContainsKey(matIndex))
                {
                    f.MaterialIndex = (Int16)(matIdMapping[matIndex]);
                }
                else
                {
                    throw new Exception("In mesh " + mesh.Name + " face index " + (i + 1) + " has an invalid material id " + matIndex + ".");
                }

                Maxscript.Command("face = getFace {0} {1}", mainMesh, i + 1);
                f.Indices.Add((Int16)(Maxscript.QueryInteger("face.x") - 1));
                f.Indices.Add((Int16)(Maxscript.QueryInteger("face.y") - 1));
                f.Indices.Add((Int16)(Maxscript.QueryInteger("face.z") - 1));

                f.NormalIndices.Add(Maxscript.QueryInteger("meshGetNormalIdFunc {0} {1}", i + 1, 1) - 1);
                f.NormalIndices.Add(Maxscript.QueryInteger("meshGetNormalIdFunc {0} {1}", i + 1, 2) - 1);
                f.NormalIndices.Add(Maxscript.QueryInteger("meshGetNormalIdFunc {0} {1}", i + 1, 3) - 1);

                Maxscript.Command("tFace = getTVFace {0} {1}", mainMesh, i + 1);
                f.TextureIndices.Add(Maxscript.QueryInteger("tFace.x") - 1);
                f.TextureIndices.Add(Maxscript.QueryInteger("tFace.y") - 1);
                f.TextureIndices.Add(Maxscript.QueryInteger("tFace.z") - 1);
                mesh.Faces.Add(f);
            }
            // Delete temporary object
            Maxscript.Command("delete {0}", tempObject);

            if (Maxscript.QueryBoolean("{0}.modifiers[#skin] != undefined", mainObject))
            {
                Maxscript.Command("skinMod = {0}.modifiers[#skin]", mainObject);
                Maxscript.Command("modPanel.setCurrentObject skinMod ui:true");
                Maxscript.Command("ExportSkinData()");

                int numBVerts = Maxscript.QueryInteger("grnSkinWeights.count");
                for (int i = 0; i < numBVerts; ++i)
                {
                    mesh.VertexWeights.Add(new VertexWeight());
                    Maxscript.Command("skinWeightArray = grnSkinWeights[{0}]", i + 1);
                    int numVWs = Maxscript.QueryInteger("skinWeightArray.count");
                    for (int j = 0; j < numVWs; ++j)
                    {
                        mesh.VertexWeights[i].BoneIndices.Add(Maxscript.QueryInteger("skinWeightArray[{0}][1]", j + 1));
                        mesh.VertexWeights[i].Weights.Add(Maxscript.QueryFloat("skinWeightArray[{0}][2]", j + 1));
                    }
                }

                int numSkinBBs = Maxscript.QueryInteger("grnSkinBBMaxs.count");
                for (int i = 0; i < numSkinBBs; ++i)
                {
                    Maxscript.Command("bbMax = grnSkinBBMaxs[{0}]", i + 1);
                    Maxscript.Command("bbMin = grnSkinBBMins[{0}]", i + 1);
                    mesh.BoneBindings.Add(new GrnBoneBinding());
                    mesh.BoneBindings[i].BoneIndex = Maxscript.QueryInteger("grnSkinBBIndices[{0}]", i + 1);
                    mesh.BoneBindings[i].OBBMax = new Vector3D(
                        Maxscript.QueryFloat("bbMax.x"),
                        Maxscript.QueryFloat("bbMax.y"),
                        Maxscript.QueryFloat("bbMax.z"));
                    mesh.BoneBindings[i].OBBMin = new Vector3D(
                        Maxscript.QueryFloat("bbMin.x"),
                        Maxscript.QueryFloat("bbMin.y"),
                        Maxscript.QueryFloat("bbMin.z"));
                }

                if (numBVerts == 0 || numSkinBBs == 0)
                {
                    throw new Exception("Failed to export skin vertices in mesh " + mesh.Name + ".");
                }
            }
            else
            {
                throw new Exception("Mesh " + mesh.Name + " has no skin.");
            }
        }
예제 #2
0
        public void Import(string fileName)
        {
            // Only need to Update the HEADER, and Animation.Duration, ASETHEADER is auto handled
            this.File = new BrgFile();
            BrgFile model = this.File; // just ref here so I don't have to rename model to this.File
            Grendgine_Collada cModel = Grendgine_Collada.Grendgine_Load_File(fileName);

            //Materials
            BrgMaterial mat = new BrgMaterial(model);
            model.Materials.Add(mat);
            mat.AmbientColor = new Color3D();
            mat.DiffuseColor = new Color3D();
            mat.SpecularColor = new Color3D(0.5f);
            mat.SpecularExponent = 5;
            mat.Id = 100;
            mat.Opacity = 1f;
            mat.Flags |= BrgMatFlag.HasTexture | BrgMatFlag.SpecularExponent;

            model.Header.NumMaterials = model.Materials.Count();

            //Meshes
            foreach (Grendgine_Collada_Geometry geo in cModel.Library_Geometries.Geometry)
            {
                BrgMesh mesh = new BrgMesh(model);
                model.Meshes.Add(mesh);

                mesh.Header.Flags |= BrgMeshFlag.MATERIAL;
                mesh.Header.Flags |= model.Meshes.Count == 1 ? 0 : BrgMeshFlag.SECONDARYMESH;
                mesh.Header.AnimationType |= BrgMeshAnimType.KeyFrame;
                mesh.Header.Format |= 0;
                mesh.ExtendedHeader.NumMaterials = (byte)model.Header.NumMaterials;
                mesh.ExtendedHeader.AnimationLength = 30;
                mesh.ExtendedHeader.NumUniqueMaterials = 0;

                string polyVertSourceID;
                string polyNormalsSourceID;
                string materialID;
                int[] vertCountPerPoly;
                int[] vertLinkPerPoly;
                int[] vertNormalBindings;

                //Locate the vertices and convert them
                string vertexPosSourceID = geo.Mesh.Vertices.Input.First<Grendgine_Collada_Input_Unshared>(x => x.Semantic == Grendgine_Collada_Input_Semantic.POSITION).source;
                Grendgine_Collada_Float_Array vertsArray = FindSourceByID(geo.Mesh, vertexPosSourceID).Float_Array;

                mesh.Vertices = FloatToVectorArray(vertsArray);
                mesh.Header.NumVertices = (short)mesh.Vertices.Count;

                //Check for polygons otherwise skip mesh
                if (geo.Mesh.Polylist != null || geo.Mesh.Polylist.Length > 0)
                {
                    mesh.Header.NumFaces = (short)geo.Mesh.Polylist[0].Count;
                    polyVertSourceID = geo.Mesh.Polylist[0].Input.First<Grendgine_Collada_Input_Unshared>(x => x.Semantic == Grendgine_Collada_Input_Semantic.VERTEX).source;
                    polyNormalsSourceID = geo.Mesh.Polylist[0].Input.First<Grendgine_Collada_Input_Unshared>(x => x.Semantic == Grendgine_Collada_Input_Semantic.NORMAL).source;
                    vertCountPerPoly = geo.Mesh.Polylist[0].VCount.Value();
                    materialID = geo.Mesh.Polylist[0].Material;
                    vertLinkPerPoly = geo.Mesh.Polylist[0].P.Value();

                    mesh.Faces = new List<Face>(mesh.Header.NumFaces);

                    vertNormalBindings = new int[mesh.Header.NumVertices];

                    int polyindex = 0;
                    Face ff;
                    foreach (int count in vertCountPerPoly)
                    {
                        if (count == 3) //If triangle
                        {
                            ff = new Face();
                            ff.Indices = new List<short>(3);
                            ff.Indices.Add((short)vertLinkPerPoly[polyindex]);
                            ff.Indices.Add((short)vertLinkPerPoly[polyindex + 4]);
                            ff.Indices.Add((short)vertLinkPerPoly[polyindex + 2]);
                            //List correct normal bindings
                            vertNormalBindings[ff.Indices[0]] = vertLinkPerPoly[polyindex + 1];
                            vertNormalBindings[ff.Indices[1]] = vertLinkPerPoly[polyindex + 5];
                            vertNormalBindings[ff.Indices[2]] = vertLinkPerPoly[polyindex + 3];
                            //Bind materials
                            if (mesh.Header.Flags.HasFlag(BrgMeshFlag.MATERIAL))
                                ff.MaterialIndex = (short)mat.Id;
                            mesh.Faces.Add(ff);
                        }
                        polyindex += count * 2; //Including face normal bindings
                    }
                }
                else
                {
                    break;
                }

                //Locate the vertex normals
                Grendgine_Collada_Float_Array normalsArray = FindSourceByID(geo.Mesh, polyNormalsSourceID).Float_Array;
                if (normalsArray.Count != vertsArray.Count)
                {
                    System.Windows.Forms.MessageBox.Show("The mesh hash only face normals instead of vertex normals. Be sure to export only smooth shaded models.", "Model Import Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
                }
                List<Vector3D> unsortedNormals = FloatToVectorArray(normalsArray);
                mesh.Normals = new List<Vector3D>(mesh.Header.NumVertices);
                for (int i = 0; i < mesh.Header.NumVertices; i++)
                {
                    mesh.Normals.Add(unsortedNormals[vertNormalBindings[i]]);
                }

                mesh.VertexMaterials = new List<short>(mesh.Header.NumVertices);
                for (int i = 0; i < mesh.Header.NumVertices; i++)
                {
                    mesh.VertexMaterials.Add((short)mat.Id);
                }
            }

            model.Header.NumMeshes = model.Meshes.Count();
        }
예제 #3
0
        private void ExportBrgMesh(string mainObject, BrgMesh mesh, float time, Dictionary<int, int> matIdMapping)
        {
            time += Maxscript.QueryFloat("animationRange.start.ticks / 4800.0");

            string mainMesh = "mainMesh";
            string mainObjectName = Maxscript.QueryString("{0}.name", mainObject);
            // Figure out the proper data to import
            if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH))
            {
                Maxscript.Command("{0} = ExportPreservedTexCoordData (GetMeshSnapshotAtTime {1} {2})", mainMesh, mainObject, time);
            }
            else
            {
                Maxscript.Command("{0} = GetMeshSnapshotAtTime {1} {2}", mainMesh, mainObject, time);
            }
            Maxscript.Command("ExportBrgVertNormals {0}", time);

            Maxscript.SetVarAtTime(time, "meshCenter", "{0}.center", mainObject);
            mesh.Header.CenterPosition = new Vector3D
            (
                -Maxscript.QueryFloat("meshCenter.x"),
                Maxscript.QueryFloat("meshCenter.z"),
                -Maxscript.QueryFloat("meshCenter.y")
            );

            Maxscript.Command("grnd = getNodeByName \"Dummy_hotspot\"");
            if (!Maxscript.QueryBoolean("grnd == undefined"))
            {
                mesh.Header.HotspotPosition = new Vector3D
                (
                    -Maxscript.QueryFloat("grnd.position.x"),
                    Maxscript.QueryFloat("grnd.position.z"),
                    -Maxscript.QueryFloat("grnd.position.y")
                );
            }

            Maxscript.SetVarAtTime(time, "{0}BBMax", "{0}.max", mainObject);
            Maxscript.SetVarAtTime(time, "{0}BBMin", "{0}.min", mainObject);
            Vector3D bBoxMax = new Vector3D(Maxscript.QueryFloat("{0}BBMax.X", mainObject), Maxscript.QueryFloat("{0}BBMax.Y", mainObject), Maxscript.QueryFloat("{0}BBMax.Z", mainObject));
            Vector3D bBoxMin = new Vector3D(Maxscript.QueryFloat("{0}BBMin.X", mainObject), Maxscript.QueryFloat("{0}BBMin.Y", mainObject), Maxscript.QueryFloat("{0}BBMin.Z", mainObject));
            Vector3D bBox = (bBoxMax - bBoxMin) / 2;
            mesh.Header.MinimumExtent = new Vector3D(-bBox.X, -bBox.Z, -bBox.Y);
            mesh.Header.MaximumExtent = new Vector3D(bBox.X, bBox.Z, bBox.Y);

            int numVertices = Maxscript.QueryInteger("brgVertIndices.count");
            int numFaces = Maxscript.QueryInteger("brgFaceArray.count");
            int currNumVertices = mesh.Vertices.Count;

            //System.Windows.Forms.MessageBox.Show("1 " + numVertices);
            for (int i = 0; i < numVertices; i++)
            {
                //System.Windows.Forms.MessageBox.Show("1.1");
                try
                {
                    Maxscript.Command("vertex = getVert {0} brgVertIndices[{1}]", mainMesh, i + 1);
                    //System.Windows.Forms.MessageBox.Show("1.4");
                    mesh.Vertices.Add(new Vector3D(-Maxscript.QueryFloat("vertex.x"), Maxscript.QueryFloat("vertex.z"), -Maxscript.QueryFloat("vertex.y")));

                    //System.Windows.Forms.MessageBox.Show("1.5");
                    mesh.Normals.Add(new Vector3D(
                        -Maxscript.QueryFloat("{0}[{1}].x", "averagedNormals", i + 1),
                        Maxscript.QueryFloat("{0}[{1}].z", "averagedNormals", i + 1),
                        -Maxscript.QueryFloat("{0}[{1}].y", "averagedNormals", i + 1)));
                    //System.Windows.Forms.MessageBox.Show("1.7");
                }
                catch (Exception ex)
                {
                    throw new Exception("In mesh " + mainObjectName + " error exporting verts/normals index " + (i + 1) + ".", ex);
                }
            }

            //System.Windows.Forms.MessageBox.Show("2");
            if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH) || mesh.Header.Flags.HasFlag(BrgMeshFlag.ANIMTEXCOORDS))
            {
                if (mesh.Header.Flags.HasFlag(BrgMeshFlag.TEXCOORDSA))
                {
                    for (int i = 0; i < numVertices; i++)
                    {
                        Maxscript.Command("tVert = getTVert {0} brgVertTVIndices[{1}]", mainMesh, i + 1);
                        mesh.TextureCoordinates.Add(new Vector3D(Maxscript.QueryFloat("tVert.x"), Maxscript.QueryFloat("tVert.y"), 0f));
                    }
                }
            }

            //System.Windows.Forms.MessageBox.Show("3");
            if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH))
            {
                if (mesh.Header.Flags.HasFlag(BrgMeshFlag.MATERIAL))
                {
                    mesh.VertexMaterials.AddRange(new Int16[numVertices]);
                }
                for (int i = 0; i < numFaces; ++i)
                {
                    Face f = new Face();
                    mesh.Faces.Add(f);

                    if (mesh.Header.Flags.HasFlag(BrgMeshFlag.MATERIAL))
                    {
                        int faceMatId = Maxscript.QueryInteger("getFaceMatId {0} {1}", mainMesh, i + 1);
                        if (matIdMapping.ContainsKey(faceMatId))
                        {
                            f.MaterialIndex = (Int16)matIdMapping[faceMatId];
                        }
                        else
                        {
                            throw new Exception("In mesh " + mainObjectName + " face index " + (i + 1) + " has an invalid material id " + faceMatId + ".");
                        }
                    }

                    //System.Windows.Forms.MessageBox.Show("3.1");
                    Maxscript.Command("face = brgFaceArray[{0}]", i + 1);
                    f.Indices.Add((Int16)(Maxscript.QueryInteger("face.x") - 1 + currNumVertices));
                    f.Indices.Add((Int16)(Maxscript.QueryInteger("face.z") - 1 + currNumVertices));
                    f.Indices.Add((Int16)(Maxscript.QueryInteger("face.y") - 1 + currNumVertices));

                    //System.Windows.Forms.MessageBox.Show("3.2");
                    if (mesh.Header.Flags.HasFlag(BrgMeshFlag.MATERIAL))
                    {
                        mesh.VertexMaterials[f.Indices[0]] = f.MaterialIndex;
                        mesh.VertexMaterials[f.Indices[1]] = f.MaterialIndex;
                        mesh.VertexMaterials[f.Indices[2]] = f.MaterialIndex;
                    }
                }
            }

            Maxscript.Command("delete {0}", mainMesh);
        }