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."); } }
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(); }
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); }