public void Export() { BrgFile brg = this.File; Maxscript.Command("exportStartTime = timeStamp()"); //Maxscript.Command("print heapSize"); BrgMeshFlag flags = brg.Meshes[0].Header.Flags; BrgMeshFormat format = brg.Meshes[0].Header.Format; BrgMeshAnimType animationType = brg.Meshes[0].Header.AnimationType; BrgMeshInterpolationType interpolationType = brg.Meshes[0].Header.InterpolationType; Maxscript.Command("ExportBrgData()"); int totalNumVerts = Maxscript.QueryInteger("brgtotalNumVerts"); int totalNumFaces = Maxscript.QueryInteger("brgtotalNumFaces"); int meshCount = Maxscript.QueryInteger("brgMeshes.count"); if (meshCount == 0) { throw new Exception("No Editable_Mesh objects detected!"); } if (Maxscript.QueryBoolean("keys.Count == 0")) { throw new Exception("Could not acquire animation keys!"); } brg.Header.NumMeshes = Maxscript.QueryInteger("keys.Count"); brg.Animation = new Animation(); for (int i = 1; i <= brg.Header.NumMeshes; ++i) { brg.Animation.MeshKeys.Add(Maxscript.QueryFloat("keys[{0}]", i)); } if (brg.Header.NumMeshes == 1) { brg.Animation.Duration = 0; } else { brg.Animation.Duration = Maxscript.QueryFloat("(animationRange.end.ticks - animationRange.start.ticks) / 4800.0"); } brg.Animation.TimeStep = brg.Animation.Duration / (float)brg.Header.NumMeshes; string mainObject = "mainObject"; brg.Materials = new List <BrgMaterial>(); brg.Meshes = new List <BrgMesh>(brg.Header.NumMeshes); for (int m = 0; m < meshCount; ++m) { Maxscript.Command("{0} = brgMeshes[{1}]", mainObject, m + 1); // Materials Dictionary <int, int> matIdMapping = new Dictionary <int, int>(); if (Maxscript.QueryBoolean("classof {0}.material == Multimaterial", mainObject)) { brg.Header.NumMaterials = Maxscript.QueryInteger("{0}.material.materialList.count", mainObject); for (int i = 0; i < brg.Header.NumMaterials; i++) { BrgMaterial mat = new BrgMaterial(brg); mat.Id = brg.Materials.Count + 1; Maxscript.Command("mat = {0}.material.materialList[{1}]", mainObject, i + 1); this.ExportBrgMaterial(mainObject, mat); int matListIndex = brg.Materials.IndexOf(mat); int actualMatId = Maxscript.QueryInteger("{0}.material.materialIdList[{1}]", mainObject, i + 1); if (matListIndex >= 0) { if (!matIdMapping.ContainsKey(actualMatId)) { matIdMapping.Add(actualMatId, brg.Materials[matListIndex].Id); } } else { brg.Materials.Add(mat); if (matIdMapping.ContainsKey(actualMatId)) { matIdMapping[actualMatId] = mat.Id; } else { matIdMapping.Add(actualMatId, mat.Id); } } } } else if (Maxscript.QueryBoolean("classof {0}.material == Standardmaterial", mainObject)) { BrgMaterial mat = new BrgMaterial(brg); mat.Id = brg.Materials.Count + 1; Maxscript.Command("mat = {0}.material", mainObject); this.ExportBrgMaterial(mainObject, mat); int matListIndex = brg.Materials.IndexOf(mat); if (matListIndex >= 0) { matIdMapping.Add(1, brg.Materials[matListIndex].Id); } else { brg.Materials.Add(mat); matIdMapping.Add(1, mat.Id); } } else { if (flags.HasFlag(BrgMeshFlag.MATERIAL)) { throw new Exception("Not all meshes have a material applied! " + Maxscript.QueryString("{0}.name", mainObject)); } } // Mesh Animations for (int i = 0; i < brg.Header.NumMeshes; i++) { if (i > 0) { if (m == 0) { BrgMesh mesh = new BrgMesh(brg); mesh.Vertices = new List <Vector3>(totalNumVerts); mesh.Normals = new List <Vector3>(totalNumVerts); mesh.TextureCoordinates = new List <Vector3>(totalNumVerts); mesh.Faces = new List <Face>(totalNumFaces); brg.Meshes[0].MeshAnimations.Add(mesh); } brg.UpdateMeshSettings(i, flags, format, animationType, interpolationType); this.ExportBrgMesh(mainObject, (BrgMesh)brg.Meshes[0].MeshAnimations[i - 1], brg.Animation.MeshKeys[i], matIdMapping); } else { if (m == 0) { BrgMesh mesh = new BrgMesh(brg); mesh.Vertices = new List <Vector3>(totalNumVerts); mesh.Normals = new List <Vector3>(totalNumVerts); mesh.TextureCoordinates = new List <Vector3>(totalNumVerts); mesh.Faces = new List <Face>(totalNumFaces); brg.Meshes.Add(mesh); } brg.UpdateMeshSettings(i, flags, format, animationType, interpolationType); this.ExportBrgMesh(mainObject, brg.Meshes[i], brg.Animation.MeshKeys[i], matIdMapping); } } } // Export Attachpoints, and Update some Mesh data HashSet <int> usedFaceMaterials = new HashSet <int>(); string attachDummy = Maxscript.NewArray("attachDummy"); Maxscript.Command("{0} = for helpObj in ($helpers/Dummy_*) where classof helpObj == Dummy collect helpObj", attachDummy);//"$helpers/Dummy_* as array"); for (int i = 0; i < brg.Header.NumMeshes; i++) { BrgMesh mesh; if (i > 0) { mesh = (BrgMesh)brg.Meshes[0].MeshAnimations[i - 1]; } else { mesh = brg.Meshes[i]; } this.ExportAttachpoints(attachDummy, mesh, brg.Animation.MeshKeys[i]); HashSet <int> diffFaceMats = new HashSet <int>(); if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH) && mesh.Header.Flags.HasFlag(BrgMeshFlag.MATERIAL)) { for (int j = 0; j < mesh.Faces.Count; ++j) { diffFaceMats.Add(mesh.Faces[j].MaterialIndex); } if (diffFaceMats.Count > 0) { mesh.ExtendedHeader.NumMaterials = (byte)(diffFaceMats.Count - 1); mesh.ExtendedHeader.NumUniqueMaterials = diffFaceMats.Count; } } usedFaceMaterials.UnionWith(diffFaceMats); mesh.ExtendedHeader.AnimationLength = this.File.Animation.Duration; } List <BrgMaterial> usedMats = new List <BrgMaterial>(brg.Materials.Count); for (int i = 0; i < brg.Materials.Count; ++i) { if (usedFaceMaterials.Contains(brg.Materials[i].Id)) { usedMats.Add(brg.Materials[i]); } } brg.Materials = usedMats; brg.Header.NumMaterials = brg.Materials.Count; //Maxscript.Command("print heapSize"); Maxscript.Command("exportEndTime = timeStamp()"); Maxscript.Format("Export took % seconds\n", "((exportEndTime - exportStartTime) / 1000.0)"); }
private void ImportBrgMesh(string mainObject, BrgMesh mesh, float time) { string vertArray = ""; string normArray = ""; string texVerts = ""; string faceMats = ""; string faceArray = ""; if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH)) { vertArray = Maxscript.NewArray("vertArray"); normArray = Maxscript.NewArray("normArray"); texVerts = Maxscript.NewArray("texVerts"); faceMats = Maxscript.NewArray("faceMats"); faceArray = Maxscript.NewArray("faceArray"); } Maxscript.CommentTitle("Load Vertices/Normals/UVWs"); Maxscript.Command("uvwSetVertPosFunc = {0}.Unwrap_UVW.SetVertexPosition", mainObject); for (int i = 0; i < mesh.Vertices.Count; i++) { if (mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH)) { Maxscript.AnimateAtTime(time, "meshSetVertFunc {0} {1} {2}", mainObject, i + 1, Maxscript.Point3Literal(-mesh.Vertices[i].X, -mesh.Vertices[i].Z, mesh.Vertices[i].Y)); if (mesh.Header.Flags.HasFlag(BrgMeshFlag.ANIMTEXCOORDS) && mesh.Header.Flags.HasFlag(BrgMeshFlag.TEXCOORDSA)) { Maxscript.Animate("uvwSetVertPosFunc {0}s {1} {2}", time, i + 1, Maxscript.Point3Literal(mesh.TextureCoordinates[i].X, mesh.TextureCoordinates[i].Y, 0)); } if (mesh.Header.Flags.HasFlag(BrgMeshFlag.ANIMVERTCOLORALPHA)) { if (mesh.Header.Flags.HasFlag(BrgMeshFlag.COLORALPHACHANNEL)) { Maxscript.AnimateAtTime(time, "meshop.setVertAlpha {0} -2 {1} {2}", mainObject, i + 1, mesh.Colors[i].A); } else if (mesh.Header.Flags.HasFlag(BrgMeshFlag.COLORCHANNEL)) { Maxscript.AnimateAtTime(time, "meshop.setVertColor {0} 0 {1} (color {2} {3} {4})", mainObject, i + 1, mesh.Colors[i].R, mesh.Colors[i].G, mesh.Colors[i].B); } } } else { Maxscript.Append(vertArray, Maxscript.Point3Literal(-mesh.Vertices[i].X, -mesh.Vertices[i].Z, mesh.Vertices[i].Y)); if (mesh.Header.Flags.HasFlag(BrgMeshFlag.TEXCOORDSA)) { Maxscript.Append(texVerts, Maxscript.Point3Literal(mesh.TextureCoordinates[i].X, mesh.TextureCoordinates[i].Y, 0)); } if (mesh.Header.Flags.HasFlag(BrgMeshFlag.COLORALPHACHANNEL)) { //Maxscript.Command("meshop.supportVAlphas {0}", mainObject); Maxscript.Command("meshop.setVertAlpha {0} -2 {1} {2}", mainObject, i + 1, mesh.Colors[i].A); } else if (mesh.Header.Flags.HasFlag(BrgMeshFlag.COLORCHANNEL)) { Maxscript.Command("meshop.setVertColor {0} 0 {1} (color {2} {3} {4})", mainObject, i + 1, mesh.Colors[i].R, mesh.Colors[i].G, mesh.Colors[i].B); } } } if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH)) { if (mesh.Header.Flags.HasFlag(BrgMeshFlag.MATERIAL)) { Maxscript.CommentTitle("Load Face Materials"); foreach (var fMat in mesh.Faces) { Maxscript.Append(faceMats, fMat.MaterialIndex); } } Maxscript.CommentTitle("Load Faces"); foreach (var face in mesh.Faces) { Maxscript.Append(faceArray, Maxscript.Point3Literal(face.Indices[0] + 1, face.Indices[2] + 1, face.Indices[1] + 1)); } int mObjNum = 0; while (Maxscript.QueryInteger("($objects/{0}* as array).count", mainObject + mObjNum) > 0) { ++mObjNum; } Maxscript.Command("{0} = {1}", mainObject, Maxscript.NewMeshLiteral(mainObject + mObjNum, vertArray, faceArray, faceMats, texVerts)); //Maxscript.Command("{0} = getNodeByName \"{0}\"", mainObject); Maxscript.Command("dummy name:\"Dummy_hotspot\" pos:{0} boxsize:[10,10,0]", Maxscript.Point3Literal(-mesh.Header.HotspotPosition.X, -mesh.Header.HotspotPosition.Z, mesh.Header.HotspotPosition.Y)); Maxscript.CommentTitle("TVert Hack"); // Needed <= 3ds Max 2014; idk about 2015+ Maxscript.Command("buildTVFaces {0}", mainObject); for (int i = 1; i <= mesh.Faces.Count; i++) { Maxscript.Command("setTVFace {0} {1} {2}[{1}]", mainObject, i, faceArray); } Maxscript.CommentTitle("Load Normals for first Frame"); Maxscript.Command("max modify mode"); Maxscript.Command("select {0}", mainObject); Maxscript.Command("addModifier {0} (Edit_Normals()) ui:off", mainObject); Maxscript.Command("modPanel.setCurrentObject {0}.modifiers[#edit_normals]", mainObject); Maxscript.Command("{0}.modifiers[#edit_normals].Break selection:#{{1..{1}}}", mainObject, mesh.Normals.Count); Maxscript.Command("meshSetNormalIdFunc = {0}.modifiers[#edit_normals].SetNormalID", mainObject); for (int i = 0; i < mesh.Faces.Count; ++i) { Maxscript.Command("meshSetNormalIdFunc {0} {1} {2}", i + 1, 1, mesh.Faces[i].Indices[0] + 1); Maxscript.Command("meshSetNormalIdFunc {0} {1} {2}", i + 1, 2, mesh.Faces[i].Indices[2] + 1); Maxscript.Command("meshSetNormalIdFunc {0} {1} {2}", i + 1, 3, mesh.Faces[i].Indices[1] + 1); } Maxscript.Command("{0}.modifiers[#edit_normals].MakeExplicit selection:#{{1..{1}}}", mainObject, mesh.Normals.Count); Maxscript.Command("meshSetNormalFunc = {0}.modifiers[#edit_normals].SetNormal", mainObject); for (int i = 0; i < mesh.Normals.Count; i++) { Maxscript.Command("meshSetNormalFunc {0} {1}", i + 1, Maxscript.Point3Literal(-mesh.Normals[i].X, -mesh.Normals[i].Z, mesh.Normals[i].Y)); } Maxscript.Command("collapseStack {0}", mainObject); if (mesh.Header.Flags.HasFlag(BrgMeshFlag.ANIMTEXCOORDS)) { Maxscript.Command("select {0}", mainObject); Maxscript.Command("addModifier {0} (Unwrap_UVW()) ui:off", mainObject); Maxscript.Command("select {0}.verts", mainObject); Maxscript.Animate("{0}.Unwrap_UVW.moveSelected [0,0,0]", mainObject); } } Maxscript.CommentTitle("Load Attachpoints"); string attachDummyArray = "attachDummyArray"; if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH)) { Maxscript.NewArray(attachDummyArray); } for (int i = 0; i < mesh.Attachpoints.Count; ++i) { BrgAttachpoint att = mesh.Attachpoints[i]; if (mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH)) { Maxscript.Command("attachpoint = {0}[{1}]", attachDummyArray, i + 1); Maxscript.AnimateAtTime(time, "attachpoint.rotation = {0}", att.GetMaxTransform()); Maxscript.AnimateAtTime(time, "attachpoint.position = {0}", att.GetMaxPosition()); if (this.uniformAttachpointScale) { Maxscript.AnimateAtTime(time, "attachpoint.scale = [1,1,1]"); } else { Maxscript.AnimateAtTime(time, "attachpoint.scale = {0}", att.GetMaxScale()); } } else { string attachDummy; if (this.uniformAttachpointScale) { attachDummy = Maxscript.NewDummy("attachDummy", att.GetMaxName(), att.GetMaxTransform(), att.GetMaxPosition(), "[0.25,0.25,0.25]", "[1,1,1]"); } else { attachDummy = Maxscript.NewDummy("attachDummy", att.GetMaxName(), att.GetMaxTransform(), att.GetMaxPosition(), att.GetMaxBoxSize(), att.GetMaxScale()); } Maxscript.Command("append {0} {1}", attachDummyArray, attachDummy); } } }