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)"); }
public void Write(BrgBinaryWriter writer) { writer.Write(magic); writer.Write(meshFormat); writer.Write(unknown01b); writer.Write(numVertices); writer.Write(numFaces); writer.Write(unknown02); for (int i = 0; i < 9; i++) { writer.Write(unknown03[i]); } writer.Write(unknown04); writer.Write((Int16)flags); for (int i = 0; i < 3; i++) { writer.Write(unknown07[i]); } writer.Write(meshX); writer.Write(meshY); writer.Write(meshZ); for (int i = 0; i < numVertices; i++) { writer.WriteVector3(ref vertices[i], true, true); } for (int i = 0; i < numVertices; i++) { writer.WriteVector3(ref normals[i], true, true); } if (!flags.HasFlag(BrgMeshFlag.NOTFIRSTMESH) || flags.HasFlag(BrgMeshFlag.MOVINGTEX)) { if (flags.HasFlag(BrgMeshFlag.TEXTURE)) { for (int i = 0; i < numVertices; i++) { writer.WriteVector2(ref texVertices[i], true); } } } if (!flags.HasFlag(BrgMeshFlag.NOTFIRSTMESH)) { if (flags.HasFlag(BrgMeshFlag.MATERIALS)) { for (int i = 0; i < numFaces; i++) { writer.Write(faceMaterials[i]); } } for (int i = 0; i < numFaces; i++) { writer.WriteVector3(ref faceVertices[i]); } if (flags.HasFlag(BrgMeshFlag.MATERIALS)) { for (int i = 0; i < numVertices; i++) { writer.Write(vertMaterials[i]); } } } for (int i = 0; i < 12; i++) { writer.WriteHalf(unknown09[i]); } writer.Write(checkSpace); writer.Write(unknown09e); if (checkSpace == 0) { writer.Write(unknown09b); writer.Write(lenSpace); writer.Write(unknown09d); } // Implement this later //if (unknown05 == 97 || unknown06 == 200 || unknown06 == 204 || unknown06 == 72 || (unknown06 == 76 && unknown05 != 98)) { // byte unknown0a[4 * numVertices]; //} if (flags.HasFlag(BrgMeshFlag.ATTACHPOINTS)) { numMatrix = (Int16)attachpoints.Count; writer.Write(numMatrix); List <int> nameId = new List <int>(); int maxNameId = 0; for (int i = 0; i < numMatrix; i++) { nameId.Add(attachpoints[i].NameId); if (attachpoints[i].NameId > maxNameId) { maxNameId = attachpoints[i].NameId; } } numIndex = (Int16)(55 - maxNameId); writer.Write(numIndex); writer.Write(unknown10); for (int i = 0; i < numMatrix; i++) { writer.WriteVector3(ref attachpoints[i].x, true, true); } for (int i = 0; i < numMatrix; i++) { writer.WriteVector3(ref attachpoints[i].y, true, true); } for (int i = 0; i < numMatrix; i++) { writer.WriteVector3(ref attachpoints[i].z, true, true); } for (int i = 0; i < numMatrix; i++) { writer.WriteVector3(ref attachpoints[i].position, true, true); } for (int i = 0; i < numMatrix; i++) { writer.WriteVector3(ref attachpoints[i].unknown11a, true, true); } for (int i = 0; i < numMatrix; i++) { writer.WriteVector3(ref attachpoints[i].unknown11b, true, true); } int[] dup = new int[numIndex]; for (int i = 0; i < nameId.Count; i++) { dup[nameId[i]] += 1; } int countId = 0; for (int i = 0; i < numIndex; i++) { writer.Write(dup[i]); if (dup[i] == 0) { writer.Write(0); } else { writer.Write(countId); } countId += dup[i]; } List <int> nameId2 = new List <int>(nameId); nameId.Sort(); for (int i = 0; i < numMatrix; i++) { for (int j = 0; j < numMatrix; j++) { if (nameId[i] == nameId2[j]) { nameId2[j] = -1; writer.Write((byte)j); break; } } } if (checkSpace == 0 && lenSpace > 0) { for (int i = 0; i < lenSpace; i++) { writer.Write(unknown14[i]); } } } }
public void ReadBr3(BrgBinaryReader reader) { numVertices = reader.ReadInt16(); numFaces = reader.ReadInt16(); flags = (BrgMeshFlag)reader.ReadInt16(); vertices = new Vector3 <float> [numVertices]; for (int i = 0; i < numVertices; i++) { reader.ReadVector3(out vertices[i], false); } normals = new Vector3 <float> [numVertices]; for (int i = 0; i < numVertices; i++) { reader.ReadVector3(out normals[i], false); } if (!flags.HasFlag(BrgMeshFlag.NOTFIRSTMESH) || flags.HasFlag(BrgMeshFlag.MOVINGTEX)) { if (flags.HasFlag(BrgMeshFlag.TEXTURE)) { texVertices = new Vector2 <float> [numVertices]; for (int i = 0; i < numVertices; i++) { reader.ReadVector2(out texVertices[i]); } } } if (!flags.HasFlag(BrgMeshFlag.NOTFIRSTMESH)) { if (flags.HasFlag(BrgMeshFlag.MATERIALS)) { faceMaterials = new Int16[numFaces]; for (int i = 0; i < numFaces; i++) { faceMaterials[i] = (Int16)reader.ReadInt32(); } } faceVertices = new Vector3 <Int16> [numFaces]; for (int i = 0; i < numFaces; i++) { reader.ReadVector3(out faceVertices[i]); faceVertices[i].X -= 1; faceVertices[i].Y -= 1; faceVertices[i].Z -= 1; } if (flags.HasFlag(BrgMeshFlag.MATERIALS)) { vertMaterials = new Int16[numVertices]; for (int i = 0; i < numFaces; i++) { vertMaterials[faceVertices[i].X] = faceMaterials[i]; vertMaterials[faceVertices[i].Y] = faceMaterials[i]; vertMaterials[faceVertices[i].Z] = faceMaterials[i]; } } } if (flags.HasFlag(BrgMeshFlag.ATTACHPOINTS)) { numMatrix = (Int16)reader.ReadInt32(); attachpoints = new List <BrgAttachpoint>(numMatrix); for (int i = 0; i < attachpoints.Count; i++) { attachpoints.Add(new BrgAttachpoint()); attachpoints[i].NameId = BrgAttachpoint.GetIdByName(reader.ReadString()); Vector3 <float> x3, y3, z3; reader.ReadVector3(out x3); reader.ReadVector3(out y3); reader.ReadVector3(out z3); reader.ReadVector3(out attachpoints[i].position, false); attachpoints[i].x.X = x3.Z; attachpoints[i].x.Y = z3.Z; attachpoints[i].x.Z = y3.Z; attachpoints[i].y.X = x3.Y; attachpoints[i].y.Y = z3.Y; attachpoints[i].y.Z = y3.Y; attachpoints[i].z.X = x3.X; attachpoints[i].z.Y = z3.X; attachpoints[i].z.Z = y3.X; } } }
public BrgMesh(BrgBinaryReader reader) { magic = reader.ReadInt32(); if (magic != EndianBitConverter.Little.ToInt32(Encoding.UTF8.GetBytes("MESI"), 0)) { throw new Exception("Improper mesh header!"); } meshFormat = reader.ReadInt16(); unknown01b = reader.ReadInt16(); numVertices = reader.ReadInt16(); numFaces = reader.ReadInt16(); unknown02 = reader.ReadInt32(); unknown03 = new float[9]; for (int i = 0; i < 9; i++) { unknown03[i] = reader.ReadSingle(); } unknown04 = new byte[6]; unknown04 = reader.ReadBytes(6); flags = (BrgMeshFlag)reader.ReadInt16(); unknown07 = new float[3]; for (int i = 0; i < 3; i++) { unknown07[i] = reader.ReadSingle(); } meshX = reader.ReadSingle(); meshY = reader.ReadSingle(); meshZ = reader.ReadSingle(); vertices = new Vector3 <float> [numVertices]; for (int i = 0; i < numVertices; i++) { reader.ReadVector3(out vertices[i], true, true); } normals = new Vector3 <float> [numVertices]; for (int i = 0; i < numVertices; i++) { reader.ReadVector3(out normals[i], true, true); } if (!flags.HasFlag(BrgMeshFlag.NOTFIRSTMESH) || flags.HasFlag(BrgMeshFlag.MOVINGTEX)) { if (flags.HasFlag(BrgMeshFlag.TEXTURE)) { texVertices = new Vector2 <float> [numVertices]; for (int i = 0; i < numVertices; i++) { reader.ReadVector2(out texVertices[i], true); } } } if (!flags.HasFlag(BrgMeshFlag.NOTFIRSTMESH)) { if (flags.HasFlag(BrgMeshFlag.MATERIALS)) { faceMaterials = new Int16[numFaces]; for (int i = 0; i < numFaces; i++) { faceMaterials[i] = reader.ReadInt16(); } } faceVertices = new Vector3 <Int16> [numFaces]; for (int i = 0; i < numFaces; i++) { reader.ReadVector3(out faceVertices[i]); } if (flags.HasFlag(BrgMeshFlag.MATERIALS)) { vertMaterials = new Int16[numVertices]; for (int i = 0; i < numVertices; i++) { vertMaterials[i] = reader.ReadInt16(); } } } unknown09 = new float[12]; for (int i = 0; i < 12; i++) { unknown09[i] = reader.ReadHalf(); } checkSpace = reader.ReadInt16(); unknown09e = reader.ReadInt16(); if (checkSpace == 0) { unknown09b = reader.ReadSingle(); lenSpace = reader.ReadInt32(); //09c unknown09d = reader.ReadInt32(); } // Implement this later //if (unknown05 == 97 || unknown06 == 200 || unknown06 == 204 || unknown06 == 72 || (unknown06 == 76 && unknown05 != 98)) { // byte unknown0a[4 * numVertices]; //} if (flags.HasFlag(BrgMeshFlag.ATTACHPOINTS)) { numMatrix = reader.ReadInt16(); numIndex = reader.ReadInt16(); unknown10 = reader.ReadInt16(); BrgAttachpoint[] attpts = new BrgAttachpoint[numMatrix]; for (int i = 0; i < numMatrix; i++) { attpts[i] = new BrgAttachpoint(); } for (int i = 0; i < numMatrix; i++) { reader.ReadVector3(out attpts[i].x, true, true); } for (int i = 0; i < numMatrix; i++) { reader.ReadVector3(out attpts[i].y, true, true); } for (int i = 0; i < numMatrix; i++) { reader.ReadVector3(out attpts[i].z, true, true); } for (int i = 0; i < numMatrix; i++) { reader.ReadVector3(out attpts[i].position, true, true); } for (int i = 0; i < numMatrix; i++) { reader.ReadVector3(out attpts[i].unknown11a, true, true); } for (int i = 0; i < numMatrix; i++) { reader.ReadVector3(out attpts[i].unknown11b, true, true); } List <int> nameId = new List <int>(); for (int i = 0; i < numIndex; i++) { int duplicate = reader.ReadInt32(); // have yet to find a model with duplicates reader.ReadInt32(); // Skip the id (at least I think its an ID) for (int j = 0; j < duplicate; j++) { nameId.Add(i); } } attachpoints = new List <BrgAttachpoint>(nameId.Count); for (int i = 0; i < nameId.Count; i++) { attachpoints.Add(new BrgAttachpoint(attpts[reader.ReadByte()])); attachpoints[i].NameId = nameId[i]; } if (checkSpace == 0 && lenSpace > 0) { unknown14 = new float[lenSpace]; for (int i = 0; i < lenSpace; i++) { unknown14[i] = reader.ReadSingle(); } } } }