public EventEntity(byte[] file, int address, uint imageBase, bool battle, Dictionary <string, NJS_OBJECT> models, List <NJS_MOTION> motions) { Model = Event.GetModel(file, address, imageBase, models); if (battle) { Motion = motions[ByteConverter.ToInt32(file, address + 4)]; ShapeMotion = motions[ByteConverter.ToInt32(file, address + 8)]; GCModel = Event.GetGCModel(file, address + 12, imageBase, models); ShadowModel = Event.GetModel(file, address + 16, imageBase, models); Position = new Vertex(file, address + 24); Flags = ByteConverter.ToUInt32(file, address + 36); Layer = ByteConverter.ToUInt32(file, address + 40); } else { int ptr = file.GetPointer(address + 4, imageBase); if (ptr != 0) { Motion = new NJS_MOTION(file, ptr, imageBase, Model.CountAnimated()); } ptr = file.GetPointer(address + 8, imageBase); if (ptr != 0) { ShapeMotion = new NJS_MOTION(file, ptr, imageBase, Model.CountMorph()); } Position = new Vertex(file, address + 16); Flags = ByteConverter.ToUInt32(file, address + 28); } }
public static List <NJS_MOTION> ReadMotionFile(string filename) { List <NJS_MOTION> motions = new List <NJS_MOTION>(); byte[] fc = File.ReadAllBytes(filename); int addr = 0; while (ByteConverter.ToInt64(fc, addr) != 0) { int ptr = ByteConverter.ToInt32(fc, addr); if (ptr == -1) { motions.Add(null); } else { motions.Add(new NJS_MOTION(fc, ptr, 0, ByteConverter.ToInt32(fc, addr + 4))); } addr += 8; } return(motions); }
public EventScene(byte[] file, int address, uint imageBase, bool battle, Dictionary <string, NJS_OBJECT> models, List <NJS_MOTION> motions) { int ptr = file.GetPointer(address, imageBase); if (ptr != 0) { int cnt = ByteConverter.ToInt32(file, address + 4); Entities = new List <EventEntity>(cnt); for (int i = 0; i < cnt; i++) { Entities.Add(new EventEntity(file, ptr, imageBase, battle, models, motions)); ptr += EventEntity.Size(battle); } } ptr = file.GetPointer(address + 8, imageBase); if (ptr != 0) { int cnt = ByteConverter.ToInt32(file, address + 12); CameraMotions = new List <NJS_MOTION>(cnt); for (int i = 0; i < cnt; i++) { if (battle) { CameraMotions.Add(motions[ByteConverter.ToInt32(file, ptr)]); } else { CameraMotions.Add(new NJS_MOTION(file, file.GetPointer(ptr, imageBase), imageBase, 1)); } ptr += sizeof(int); } } ptr = file.GetPointer(address + 24, imageBase); if (ptr != 0) { Big = new EventBig(file, ptr, imageBase, battle, models, motions); } FrameCount = ByteConverter.ToInt32(file, address + 28); }
public Event(string filename) { byte[] fc; if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase)) { fc = Prs.Decompress(filename); } else { fc = File.ReadAllBytes(filename); } bool battle = false; bool dcbeta = false; uint key; if (fc[0] == 0x81) { if (fc[0x2B] <= 0x01 && fc[0x2A] == 0) { ByteConverter.BigEndian = true; key = 0x8125FE60; battle = true; } else { ByteConverter.BigEndian = true; key = 0x812FFE60; } } else { if ((fc[37] == 0x25) || (fc[38] == 0x22) || ((fc[36] == 0) && ((fc[1] == 0xFE) || (fc[1] == 0xF2) || ((fc[1] == 0x27) && fc[2] == 0x9F)))) { ByteConverter.BigEndian = false; key = 0xC600000; dcbeta = true; } else { ByteConverter.BigEndian = false; key = 0xC600000; } } List <NJS_MOTION> motions = null; if (battle) { motions = ReadMotionFile(Path.ChangeExtension(filename, null) + "motion.bin"); } Dictionary <string, NJS_OBJECT> models = new Dictionary <string, NJS_OBJECT>(); int ptr = fc.GetPointer(0x20, key); if (ptr != 0) { if (!dcbeta) { int cnt = battle ? 18 : 16; Upgrades = new EventUpgrade[cnt]; for (int i = 0; i < cnt; i++) { Upgrades[i] = new EventUpgrade(fc, ptr, key, models); ptr += EventUpgrade.Size; } } else { int cnt = 14; Upgrades = new EventUpgrade[cnt]; for (int i = 0; i < cnt; i++) { Upgrades[i] = new EventUpgrade(fc, ptr, key, models); ptr += EventUpgrade.Size; } } } int gcnt = ByteConverter.ToInt32(fc, 8); ptr = fc.GetPointer(0, key); if (ptr != 0) { Scenes = new List <EventScene>(); for (int gn = 0; gn <= gcnt; gn++) { Scenes.Add(new EventScene(fc, ptr, key, battle, models, motions)); ptr += EventScene.Size; } } }
public LandTable(byte[] file, int address, uint imageBase, LandTableFormat format, Dictionary <int, string> labels) { Format = format; if (labels.ContainsKey(address)) { Name = labels[address]; } else { Name = "landtable_" + address.ToString("X8"); } short colcnt = ByteConverter.ToInt16(file, address); Dictionary <int, Attach> attaches = new Dictionary <int, Attach>(); switch (format) { case LandTableFormat.SA1: case LandTableFormat.SADX: short anicnt = ByteConverter.ToInt16(file, address + 2); Attributes = (SA1LandtableAttributes)ByteConverter.ToInt16(file, address + 4); Flags = ByteConverter.ToInt16(file, address + 6); FarClipping = ByteConverter.ToSingle(file, address + 8); COL = new List <COL>(); int tmpaddr = ByteConverter.ToInt32(file, address + 0xC); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); if (labels.ContainsKey(tmpaddr)) { COLName = labels[tmpaddr]; } else { COLName = "collist_" + tmpaddr.ToString("X8"); } for (int i = 0; i < colcnt; i++) { COL.Add(new COL(file, tmpaddr, imageBase, format, labels, attaches)); tmpaddr += SAModel.COL.Size(format); } } else { COLName = "collist_" + Extensions.GenerateIdentifier(); } Anim = new List <GeoAnimData>(); tmpaddr = ByteConverter.ToInt32(file, address + 0x10); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); if (labels.ContainsKey(tmpaddr)) { AnimName = labels[tmpaddr]; } else { AnimName = "animlist_" + tmpaddr.ToString("X8"); } for (int i = 0; i < anicnt; i++) { Anim.Add(new GeoAnimData(file, tmpaddr, imageBase, format, labels, attaches)); tmpaddr += GeoAnimData.Size; } } else { AnimName = "animlist_" + Extensions.GenerateIdentifier(); } tmpaddr = ByteConverter.ToInt32(file, address + 0x14); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); TextureFileName = file.GetCString(tmpaddr, Encoding.ASCII); } TextureList = ByteConverter.ToUInt32(file, address + 0x18); BinaryFilename = ByteConverter.ToInt32(file, address + 0x1C); BinaryLoadFunction = ByteConverter.ToInt32(file, address + 0x20); break; case LandTableFormat.SA2: case LandTableFormat.SA2B: short cnkcnt = ByteConverter.ToInt16(file, address + 2); FarClipping = ByteConverter.ToSingle(file, address + 0xC); COL = new List <COL>(); tmpaddr = ByteConverter.ToInt32(file, address + 0x10); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); if (labels.ContainsKey(tmpaddr)) { COLName = labels[tmpaddr]; } else { COLName = "collist_" + tmpaddr.ToString("X8"); } for (int i = 0; i < colcnt; i++) { COL.Add(new COL(file, tmpaddr, imageBase, format, labels, cnkcnt < 0 ? null : (bool?)(i >= cnkcnt), attaches)); tmpaddr += SAModel.COL.Size(format); } } else { COLName = "collist_" + Extensions.GenerateIdentifier(); } Anim = new List <GeoAnimData>(); AnimName = "animlist_" + Extensions.GenerateIdentifier(); tmpaddr = ByteConverter.ToInt32(file, address + 0x18); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); TextureFileName = file.GetCString(tmpaddr, Encoding.ASCII); } TextureList = ByteConverter.ToUInt32(file, address + 0x1C); break; } Metadata = new Dictionary <uint, byte[]>(); }
// Scan for Motions static void ScanMotions() { CurrentStep++; CurrentScanData = "Motions" + (ModelParts > 0 ? " with " + ModelParts.ToString() + " or more nodes" : ""); Console.WriteLine("Step {0}: Scanning for motions with at least {1} model parts... ", CurrentStep, ModelParts); if (ShortRot) { Console.WriteLine("Using short rotations"); } ByteConverter.BigEndian = BigEndian; if (!SingleOutputFolder) { Directory.CreateDirectory(Path.Combine(OutputFolder, "actions")); } for (uint address = StartAddress; address < EndAddress; address += 1) { if (CancelScan) { break; } if (ConsoleMode && address % 1000 == 0) { Console.Write("\r{0} ", address.ToString("X8")); } CurrentAddress = address; // Check for a valid MDATA pointer uint mdatap = ByteConverter.ToUInt32(datafile, (int)address); if (mdatap < ImageBase || mdatap >= datafile.Length - 12 + ImageBase || mdatap == 0) { //Console.WriteLine("Mdatap {0} fail", mdatap.ToString("X8")); continue; } uint frames = ByteConverter.ToUInt32(datafile, (int)address + 4); if (frames > 2000 || frames < 1) { //Console.WriteLine("Frames {0} fail", frames.ToString()); continue; } AnimFlags animtype = (AnimFlags)ByteConverter.ToUInt16(datafile, (int)address + 8); if (animtype == 0) { continue; } int mdata = 0; //Console.WriteLine("Flags: {0}", animtype.ToString()); if (animtype.HasFlag(AnimFlags.Position)) { mdata++; } if (animtype.HasFlag(AnimFlags.Rotation)) { mdata++; } if (animtype.HasFlag(AnimFlags.Scale)) { mdata++; } if (animtype.HasFlag(AnimFlags.Vector)) { mdata++; } if (animtype.HasFlag(AnimFlags.Vertex)) { mdata++; } if (animtype.HasFlag(AnimFlags.Normal)) { mdata++; } if (animtype.HasFlag(AnimFlags.Color)) { continue; } if (animtype.HasFlag(AnimFlags.Intensity)) { continue; } if (animtype.HasFlag(AnimFlags.Target)) { continue; } if (animtype.HasFlag(AnimFlags.Spot)) { continue; } if (animtype.HasFlag(AnimFlags.Point)) { continue; } if (animtype.HasFlag(AnimFlags.Roll)) { continue; } int mdatasize = 0; bool lost = false; switch (mdata) { case 1: case 2: mdatasize = 16; break; case 3: mdatasize = 24; break; case 4: mdatasize = 32; break; case 5: mdatasize = 40; break; default: lost = true; break; } if (lost) { continue; } // Check MKEY pointers int mdatas = 0; for (int u = 0; u < 255; u++) { for (int m = 0; m < mdata; m++) { if (lost) { continue; } uint pointer = ByteConverter.ToUInt32(datafile, (int)(mdatap - ImageBase) + mdatasize * u + 4 * m); if (pointer < ImageBase || pointer >= datafile.Length - 8 + ImageBase) { if (pointer != 0) { lost = true; //Console.WriteLine("Mkey pointer {0} lost", pointer.ToString("X8")); } } if (!lost) { // Read frame count int framecount = ByteConverter.ToInt32(datafile, (int)(mdatap - ImageBase) + mdatasize * u + 4 * mdata + 4 * m); if (framecount < 0 || framecount > 2000) { //Console.WriteLine("Framecount lost: {0}", framecount.ToString("X8")); lost = true; } if (pointer == 0 && framecount != 0) { //Console.WriteLine("Framecount non zero"); lost = true; } //if (!lost) Console.WriteLine("Mdata size: {0}, MkeyP: {1}, Frames: {2}", mdatasize, pointer.ToString("X8"), framecount.ToString()); } } if (!lost) { mdatas++; //Console.WriteLine("Mdata {0}, total {1}", u, mdatas); } } if (mdatas > 0 && mdatas >= ModelParts) { try { Console.WriteLine("\rAdding motion at {0}: {1} nodes", address.ToString("X8"), mdatas); //Console.WriteLine("trying Address: {0}, MdataP: {1}, mdatas: {2}", address.ToString("X8"), mdatap.ToString("X8"), mdata); NJS_MOTION mot = NJS_MOTION.ReadDirect(datafile, mdatas, (int)address, ImageBase, new Dictionary <int, Attach>(), ShortRot); if (mot.ModelParts <= 0) { continue; } if (mot.Frames <= 0) { continue; } if (mot.Models.Count == 0) { continue; } string fileOutputPath = Path.Combine(OutputFolder, "actions", address.ToString("X8") + ".saanim"); if (SingleOutputFolder) { fileOutputPath = Path.Combine(OutputFolder, address.ToString("X8") + ".saanim"); } mot.Save(fileOutputPath, NoMeta); FoundMotions++; addresslist.Add(address, "NJS_MOTION"); uint[] arr = new uint[2]; arr[0] = address; arr[1] = (uint)mot.ModelParts; actionlist.Add(address, arr); } catch (Exception ex) { Console.WriteLine("\rError adding motion at {0}: {1}", address.ToString("X8"), ex.Message); } } } Console.WriteLine("\rFound {0} motions", FoundMotions); }
public static LandTable LoadFromFile(string filename) { bool be = ByteConverter.BigEndian; ByteConverter.BigEndian = false; byte[] file = File.ReadAllBytes(filename); ulong magic = ByteConverter.ToUInt64(file, 0) & FormatMask; byte version = file[7]; if (version > CurrentVersion) { throw new FormatException("Not a valid SA1LVL/SA2LVL file."); } Dictionary <int, string> labels = new Dictionary <int, string>(); string author = null, description = null; Dictionary <uint, byte[]> meta = new Dictionary <uint, byte[]>(); if (version < 2) { if (version == 1) { int tmpaddr = ByteConverter.ToInt32(file, 0xC); if (tmpaddr != 0) { int addr = ByteConverter.ToInt32(file, tmpaddr); while (addr != -1) { labels.Add(addr, file.GetCString(ByteConverter.ToInt32(file, tmpaddr + 4))); tmpaddr += 8; addr = ByteConverter.ToInt32(file, tmpaddr); } } } } else { int tmpaddr = ByteConverter.ToInt32(file, 0xC); if (tmpaddr != 0) { bool finished = false; while (!finished) { ChunkTypes type = (ChunkTypes)ByteConverter.ToUInt32(file, tmpaddr); int chunksz = ByteConverter.ToInt32(file, tmpaddr + 4); int nextchunk = tmpaddr + 8 + chunksz; tmpaddr += 8; if (version == 2) { switch (type) { case ChunkTypes.Label: while (ByteConverter.ToInt64(file, tmpaddr) != -1) { labels.Add(ByteConverter.ToInt32(file, tmpaddr), file.GetCString(ByteConverter.ToInt32(file, tmpaddr + 4))); tmpaddr += 8; } break; case ChunkTypes.Author: author = file.GetCString(tmpaddr); break; case ChunkTypes.Tool: break; case ChunkTypes.Description: description = file.GetCString(tmpaddr); break; case ChunkTypes.End: finished = true; break; } } else { byte[] chunk = new byte[chunksz]; Array.Copy(file, tmpaddr, chunk, 0, chunksz); int chunkaddr = 0; switch (type) { case ChunkTypes.Label: while (ByteConverter.ToInt64(chunk, chunkaddr) != -1) { labels.Add(ByteConverter.ToInt32(chunk, chunkaddr), chunk.GetCString(ByteConverter.ToInt32(chunk, chunkaddr + 4))); chunkaddr += 8; } break; case ChunkTypes.Author: author = chunk.GetCString(0); break; case ChunkTypes.Tool: break; case ChunkTypes.Description: description = chunk.GetCString(0); break; case ChunkTypes.End: finished = true; break; default: meta.Add((uint)type, chunk); break; } } tmpaddr = nextchunk; } } } if (magic == SA1LVL) { LandTable table = new LandTable(file, ByteConverter.ToInt32(file, 8), 0, LandTableFormat.SA1, labels) { Author = author, Description = description, Metadata = meta }; ByteConverter.BigEndian = be; return(table); } if (magic == SA2LVL) { LandTable table = new LandTable(file, ByteConverter.ToInt32(file, 8), 0, LandTableFormat.SA2, labels) { Author = author, Description = description, Metadata = meta }; ByteConverter.BigEndian = be; return(table); } if (magic == SA2BLVL) { LandTable table = new LandTable(file, ByteConverter.ToInt32(file, 8), 0, LandTableFormat.SA2B, labels) { Author = author, Description = description, Metadata = meta }; ByteConverter.BigEndian = be; return(table); } ByteConverter.BigEndian = be; throw new FormatException("Not a valid SA1LVL/SA2LVL file."); }
public COL(byte[] file, int address, uint imageBase, LandTableFormat format, Dictionary <int, string> labels, bool?forceBasic, Dictionary <int, Attach> attaches) { Bounds = new BoundingSphere(file, address); ModelFormat mfmt = 0; switch (format) { case LandTableFormat.SA1: mfmt = ModelFormat.Basic; break; case LandTableFormat.SADX: mfmt = ModelFormat.BasicDX; break; case LandTableFormat.SA2: if (forceBasic.HasValue && forceBasic.Value) { mfmt = ModelFormat.Basic; } else { mfmt = ModelFormat.Chunk; } break; case LandTableFormat.SA2B: if (forceBasic.HasValue && forceBasic.Value) { mfmt = ModelFormat.Basic; } else { mfmt = ModelFormat.GC; } break; } switch (format) { case LandTableFormat.SA1: case LandTableFormat.SADX: WidthY = ByteConverter.ToSingle(file, address + 0x10); WidthZ = ByteConverter.ToSingle(file, address + 0x14); uint tmpaddr = ByteConverter.ToUInt32(file, address + 0x18) - imageBase; Model = new NJS_OBJECT(file, (int)tmpaddr, imageBase, mfmt, labels, attaches); BlockBits = ByteConverter.ToUInt32(file, address + 0x1C); Flags = ByteConverter.ToInt32(file, address + 0x20); break; case LandTableFormat.SA2: case LandTableFormat.SA2B: Flags = ByteConverter.ToInt32(file, address + 0x1C); if (!forceBasic.HasValue && Flags >= 0) { mfmt = ModelFormat.Basic; } tmpaddr = ByteConverter.ToUInt32(file, address + 0x10) - imageBase; Model = new NJS_OBJECT(file, (int)tmpaddr, imageBase, mfmt, labels, attaches); WidthZ = ByteConverter.ToInt32(file, address + 0x14); BlockBits = ByteConverter.ToUInt32(file, address + 0x18); break; } }
public BasicAttach(byte[] file, int address, uint imageBase, bool DX, Dictionary <int, string> labels) : this() { if (labels.ContainsKey(address)) { Name = labels[address]; } else { Name = "attach_" + address.ToString("X8"); } Vertex = new Vertex[ByteConverter.ToInt32(file, address + 8)]; Normal = new Vertex[Vertex.Length]; int tmpaddr = (int)(ByteConverter.ToUInt32(file, address) - imageBase); if (labels.ContainsKey(tmpaddr)) { VertexName = labels[tmpaddr]; } else { VertexName = "vertex_" + tmpaddr.ToString("X8"); } for (int i = 0; i < Vertex.Length; i++) { Vertex[i] = new Vertex(file, tmpaddr); tmpaddr += SAModel.Vertex.Size; } tmpaddr = ByteConverter.ToInt32(file, address + 4); if (tmpaddr != 0) { tmpaddr = (int)((uint)tmpaddr - imageBase); if (labels.ContainsKey(tmpaddr)) { NormalName = labels[tmpaddr]; } else { NormalName = "normal_" + tmpaddr.ToString("X8"); } for (int i = 0; i < Vertex.Length; i++) { Normal[i] = new Vertex(file, tmpaddr); tmpaddr += SAModel.Vertex.Size; } } else { for (int i = 0; i < Vertex.Length; i++) { Normal[i] = new Vertex(0, 1, 0); } } int maxmat = -1; int meshcnt = ByteConverter.ToInt16(file, address + 0x14); tmpaddr = ByteConverter.ToInt32(file, address + 0xC); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); if (labels.ContainsKey(tmpaddr)) { MeshName = labels[tmpaddr]; } else { MeshName = "meshlist_" + tmpaddr.ToString("X8"); } for (int i = 0; i < meshcnt; i++) { Mesh.Add(new NJS_MESHSET(file, tmpaddr, imageBase, labels)); maxmat = Math.Max(maxmat, Mesh[i].MaterialID); tmpaddr += NJS_MESHSET.Size(DX); } } // fixes case where model declares material array as shorter than it really is int matcnt = Math.Max(ByteConverter.ToInt16(file, address + 0x16), maxmat + 1); tmpaddr = ByteConverter.ToInt32(file, address + 0x10); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); if (labels.ContainsKey(tmpaddr)) { MaterialName = labels[tmpaddr]; } else { MaterialName = "matlist_" + tmpaddr.ToString("X8"); } for (int i = 0; i < matcnt; i++) { Material.Add(new NJS_MATERIAL(file, tmpaddr, labels)); tmpaddr += NJS_MATERIAL.Size; } } Bounds = new BoundingSphere(file, address + 0x18); }
private NJS_OBJECT(byte[] file, int address, uint imageBase, ModelFormat format, NJS_OBJECT parent, Dictionary <int, string> labels, Dictionary <int, Attach> attaches) { if (labels.ContainsKey(address)) { Name = labels[address]; } else { Name = "object_" + address.ToString("X8"); } if (address > file.Length - 52) { Position = new Vertex(); Rotation = new Rotation(); Scale = new Vertex(1, 1, 1); children = new List <NJS_OBJECT>(); Children = new ReadOnlyCollection <NJS_OBJECT>(children); return; } ObjectFlags flags = (ObjectFlags)ByteConverter.ToInt32(file, address); RotateZYX = (flags & ObjectFlags.RotateZYX) == ObjectFlags.RotateZYX; SkipDraw = (flags & ObjectFlags.NoDisplay) == ObjectFlags.NoDisplay; SkipChildren = (flags & ObjectFlags.NoChildren) == ObjectFlags.NoChildren; IgnorePosition = (flags & ObjectFlags.NoPosition) == ObjectFlags.NoPosition; IgnoreRotation = (flags & ObjectFlags.NoRotate) == ObjectFlags.NoRotate; IgnoreScale = (flags & ObjectFlags.NoScale) == ObjectFlags.NoScale; Animate = (flags & ObjectFlags.NoAnimate) == 0; Morph = (flags & ObjectFlags.NoMorph) == 0; int tmpaddr = ByteConverter.ToInt32(file, address + 4); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); if (attaches != null && attaches.ContainsKey(tmpaddr)) { Attach = attaches[tmpaddr]; } else { Attach = Attach.Load(file, tmpaddr, imageBase, format, labels); if (attaches != null) { attaches.Add(tmpaddr, Attach); } } } Position = new Vertex(file, address + 8); Rotation = new Rotation(file, address + 0x14); Scale = new Vertex(file, address + 0x20); Parent = parent; children = new List <NJS_OBJECT>(); Children = new ReadOnlyCollection <NJS_OBJECT>(children); NJS_OBJECT child = null; tmpaddr = ByteConverter.ToInt32(file, address + 0x2C); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); child = new NJS_OBJECT(file, tmpaddr, imageBase, format, this, labels, attaches); } while (child != null) { children.Add(child); child = child.Sibling; } tmpaddr = ByteConverter.ToInt32(file, address + 0x30); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); Sibling = new NJS_OBJECT(file, tmpaddr, imageBase, format, parent, labels, attaches); } //Assimp.AssimpContext context = new AssimpContext(); //Scene scene = context.ImportFile("F:\\untitled.obj", PostProcessSteps.Triangulate); //AssimpLoad(scene, scene.RootNode); }
public NJS_MESHSET(byte[] file, int address, uint imageBase, Dictionary <int, string> labels) { MaterialID = ByteConverter.ToUInt16(file, address); PolyType = (Basic_PolyType)(MaterialID >> 0xE); MaterialID &= 0x3FFF; Poly[] polys = new Poly[ByteConverter.ToInt16(file, address + 2)]; int tmpaddr = (int)(ByteConverter.ToUInt32(file, address + 4) - imageBase); if (labels.ContainsKey(tmpaddr)) { PolyName = labels[tmpaddr]; } else { PolyName = "poly_" + tmpaddr.ToString("X8"); } int striptotal = 0; for (int i = 0; i < polys.Length; i++) { polys[i] = SAModel.Poly.CreatePoly(PolyType, file, tmpaddr); striptotal += polys[i].Indexes.Length; tmpaddr += polys[i].Size; } Poly = new ReadOnlyCollection <Poly>(polys); PAttr = ByteConverter.ToInt32(file, address + 8); tmpaddr = ByteConverter.ToInt32(file, address + 0xC); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); if (labels.ContainsKey(tmpaddr)) { PolyNormalName = labels[tmpaddr]; } else { PolyNormalName = "polynormal_" + tmpaddr.ToString("X8"); } PolyNormal = new Vertex[polys.Length]; for (int i = 0; i < polys.Length; i++) { PolyNormal[i] = new Vertex(file, tmpaddr); tmpaddr += Vertex.Size; } } else { PolyNormalName = "polynormal_" + Extensions.GenerateIdentifier(); } tmpaddr = ByteConverter.ToInt32(file, address + 0x10); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); if (labels.ContainsKey(tmpaddr)) { VColorName = labels[tmpaddr]; } else { VColorName = "vcolor_" + tmpaddr.ToString("X8"); } VColor = new Color[striptotal]; for (int i = 0; i < striptotal; i++) { VColor[i] = SAModel.VColor.FromBytes(file, tmpaddr); tmpaddr += SAModel.VColor.Size(ColorType.ARGB8888_32); } } else { VColorName = "vcolor_" + Extensions.GenerateIdentifier(); } tmpaddr = ByteConverter.ToInt32(file, address + 0x14); if (tmpaddr != 0) { tmpaddr = (int)unchecked ((uint)tmpaddr - imageBase); if (labels.ContainsKey(tmpaddr)) { UVName = labels[tmpaddr]; } else { UVName = "uv_" + tmpaddr.ToString("X8"); } UV = new UV[striptotal]; for (int i = 0; i < striptotal; i++) { UV[i] = new UV(file, tmpaddr); tmpaddr += SAModel.UV.Size; } } else { UVName = "uv_" + Extensions.GenerateIdentifier(); } }