diff --git a/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs index 3e86c68..d8f47b3 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs @@ -40,5 +40,13 @@ namespace CodeWalker.GameFiles Loaded = true; } + + public byte[] Save() + { + byte[] data = ResourceBuilder.Build(Bounds, 43); //ybn is type/version 43... + + return data; + } + } } diff --git a/CodeWalker.Core/GameFiles/GameFileCache.cs b/CodeWalker.Core/GameFiles/GameFileCache.cs index 4f51144..1ad9ec5 100644 --- a/CodeWalker.Core/GameFiles/GameFileCache.cs +++ b/CodeWalker.Core/GameFiles/GameFileCache.cs @@ -178,6 +178,7 @@ namespace CodeWalker.GameFiles //TestPsos(); //TestYcds(); //TestYtds(); + //TestYbns(); //TestYmaps(); //TestPlacements(); //TestDrawables(); @@ -2911,6 +2912,156 @@ namespace CodeWalker.GameFiles + } + } + } + //catch (Exception ex) + //{ + // UpdateStatus("Error! " + ex.ToString()); + //} + } + } + if (errorfiles.Count > 0) + { } + } + public void TestYbns() + { + var errorfiles = new List(); + foreach (RpfFile file in AllRpfs) + { + foreach (RpfEntry entry in file.AllEntries) + { + //try + { + if (entry.NameLower.EndsWith(".ybn")) + { + UpdateStatus(string.Format(entry.Path)); + YbnFile ybn = null; + try + { + ybn = RpfMan.GetFile(entry); + } + catch (Exception ex) + { + UpdateStatus("Error! " + ex.ToString()); + errorfiles.Add(entry); + } + if ((ybn != null) && (ybn.Bounds != null)) + { + var fentry = entry as RpfFileEntry; + if (fentry == null) + { continue; } //shouldn't happen + + var bytes = ybn.Save(); + + string origlen = TextUtil.GetBytesReadable(fentry.FileSize); + string bytelen = TextUtil.GetBytesReadable(bytes.Length); + + + var ybn2 = new YbnFile(); + RpfFile.LoadResourceFile(ybn2, bytes, 43); + + if (ybn2.Bounds == null) + { continue; } + if (ybn2.Bounds.Type != ybn.Bounds.Type) + { continue; } + + //quick check of roundtrip + switch (ybn2.Bounds.Type) + { + case 0: //return new BoundSphere(); + { + var a = ybn.Bounds as BoundSphere; + var b = ybn2.Bounds as BoundSphere; + if (b == null) + { continue; } + break; + } + case 1: //return new BoundCapsule(); + { + var a = ybn.Bounds as BoundCapsule; + var b = ybn2.Bounds as BoundCapsule; + if (b == null) + { continue; } + break; + } + case 3: //return new BoundBox(); + { + var a = ybn.Bounds as BoundBox; + var b = ybn2.Bounds as BoundBox; + if (b == null) + { continue; } + break; + } + case 4: //return new BoundGeometry(); + { + var a = ybn.Bounds as BoundGeometry; + var b = ybn2.Bounds as BoundGeometry; + if (b == null) + { continue; } + if (a.Polygons?.Length != b.Polygons?.Length) + { continue; } + for (int i = 0; i < a.Polygons.Length; i++) + { + var pa = a.Polygons[i]; + var pb = b.Polygons[i]; + if (pa.Type != pb.Type) + { } + } + break; + } + case 8: //return new BoundBVH(); + { + var a = ybn.Bounds as BoundBVH; + var b = ybn2.Bounds as BoundBVH; + if (b == null) + { continue; } + if (a.BVH?.Nodes?.data_items?.Length != b.BVH?.Nodes?.data_items?.Length) + { } + if (a.Polygons?.Length != b.Polygons?.Length) + { continue; } + for (int i = 0; i < a.Polygons.Length; i++) + { + var pa = a.Polygons[i]; + var pb = b.Polygons[i]; + if (pa.Type != pb.Type) + { } + } + break; + } + case 10: //return new BoundComposite(); + { + var a = ybn.Bounds as BoundComposite; + var b = ybn2.Bounds as BoundComposite; + if (b == null) + { continue; } + if (a.Children?.data_items?.Length != b.Children?.data_items?.Length) + { } + break; + } + case 12: //return new BoundDisc(); + { + var a = ybn.Bounds as BoundDisc; + var b = ybn2.Bounds as BoundDisc; + if (b == null) + { continue; } + break; + } + case 13: //return new BoundCylinder(); + { + var a = ybn.Bounds as BoundCylinder; + var b = ybn2.Bounds as BoundCylinder; + if (b == null) + { continue; } + break; + } + case 15: //return null; //TODO: find out what this is! + default: //return null; // throw new Exception("Unknown bound type"); + break; + } + + + } } } diff --git a/CodeWalker.Core/GameFiles/Resources/Bounds.cs b/CodeWalker.Core/GameFiles/Resources/Bounds.cs index dea2416..a85b03f 100644 --- a/CodeWalker.Core/GameFiles/Resources/Bounds.cs +++ b/CodeWalker.Core/GameFiles/Resources/Bounds.cs @@ -277,6 +277,88 @@ namespace CodeWalker.GameFiles } [TC(typeof(EXP))] public class BoundBox : Bounds { } + [TC(typeof(EXP))] public class BoundDisc : Bounds + { + public override long BlockLength + { + get { return 128; } + } + + // structure data + public uint Unknown_70h { get; set; } // 0x00000000 + public uint Unknown_74h { get; set; } // 0x00000000 + public uint Unknown_78h { get; set; } // 0x00000000 + public uint Unknown_7Ch { get; set; } // 0x00000000 + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + base.Read(reader, parameters); + + // read structure data + this.Unknown_70h = reader.ReadUInt32(); + this.Unknown_74h = reader.ReadUInt32(); + this.Unknown_78h = reader.ReadUInt32(); + this.Unknown_7Ch = reader.ReadUInt32(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + base.Write(writer, parameters); + + // write structure data + writer.Write(this.Unknown_70h); + writer.Write(this.Unknown_74h); + writer.Write(this.Unknown_78h); + writer.Write(this.Unknown_7Ch); + } + } + [TC(typeof(EXP))] public class BoundCylinder : Bounds + { + public override long BlockLength + { + get { return 128; } + } + + // structure data + public uint Unknown_70h { get; set; } // 0x00000000 + public uint Unknown_74h { get; set; } // 0x00000000 + public uint Unknown_78h { get; set; } // 0x00000000 + public uint Unknown_7Ch { get; set; } // 0x00000000 + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + base.Read(reader, parameters); + + // read structure data + this.Unknown_70h = reader.ReadUInt32(); + this.Unknown_74h = reader.ReadUInt32(); + this.Unknown_78h = reader.ReadUInt32(); + this.Unknown_7Ch = reader.ReadUInt32(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + base.Write(writer, parameters); + + // write structure data + writer.Write(this.Unknown_70h); + writer.Write(this.Unknown_74h); + writer.Write(this.Unknown_78h); + writer.Write(this.Unknown_7Ch); + } + } [TC(typeof(EXP))] public class BoundGeometry : Bounds { public override long BlockLength @@ -329,11 +411,20 @@ namespace CodeWalker.GameFiles public Vector3[] Vertices { get; set; } public uint[] Unknown_B8h_Data { get; set; } public uint[] Unknown_C0h_Data { get; set; } - public uint[][] Unknown_C8h_Data { get; set; } + public BoundUnknown1 Unknown_C8h_Data { get; set; } public BoundMaterial_s[] Materials { get; set; } public BoundMaterialColour[] MaterialColours { get; set; } public byte[] PolygonMaterialIndices { get; set; } + private ResourceSystemStructBlock p1dataBlock = null; + private ResourceSystemDataBlock PolygonsBlock = null; + private ResourceSystemStructBlock VerticesBlock = null; + private ResourceSystemStructBlock Unknown_B8h_Block = null; + private ResourceSystemStructBlock Unknown_C0h_Block = null; + private ResourceSystemStructBlock MaterialsBlock = null; + private ResourceSystemStructBlock MaterialColoursBlock = null; + private ResourceSystemStructBlock PolygonMaterialIndicesBlock = null; + /// /// Reads the data-block from a stream. /// @@ -398,16 +489,11 @@ namespace CodeWalker.GameFiles } this.Unknown_B8h_Data = reader.ReadUintsAt(this.Unknown_B8h_Pointer, this.VerticesCount); - this.Unknown_C0h_Data = reader.ReadUintsAt(this.Unknown_C0h_Pointer, 8); + this.Unknown_C0h_Data = reader.ReadUintsAt(this.Unknown_C0h_Pointer, 8);//item counts if (this.Unknown_C0h_Data != null) { - ulong[] ptrlist = reader.ReadUlongsAt(this.Unknown_C8h_Pointer, 8);//(uint)Unknown_C0h_Data.Length - Unknown_C8h_Data = new uint[8][]; //Unknown_C0h_Data.Length - for (int i = 0; i < 8; i++) //Unknown_C0h_Data.Length - { - Unknown_C8h_Data[i] = reader.ReadUintsAt(ptrlist[i], Unknown_C0h_Data[i]); - } + this.Unknown_C8h_Data = reader.ReadBlockAt(this.Unknown_C8h_Pointer, this.Unknown_C0h_Data); } this.Materials = reader.ReadStructsAt(this.MaterialsPointer, this.MaterialsCount); @@ -430,7 +516,7 @@ namespace CodeWalker.GameFiles { var offset = i * 16; byte b0 = polygonData[offset]; - polygonData[offset] = (byte)(b0 & 0x7F);//mask it off + polygonData[offset] = (byte)(b0 & 0xF8);//mask it off BoundPolygonType type = (BoundPolygonType)(b0 & 7); BoundPolygon p = null; switch (type) @@ -475,20 +561,20 @@ namespace CodeWalker.GameFiles base.Write(writer, parameters); // update structure data - //this.Unknown_78h_Pointer = (ulong)(this.p1data != null ? this.p1data.Position : 0); - //this.PolygonsPointer = (ulong)(this.Polygons != null ? this.Polygons.Position : 0); - //this.VerticesPointer = (ulong)(this.Vertices != null ? this.Vertices.Position : 0); - //this.Unknown_B8h_Pointer = (ulong)(this.Unknown_B8h_Data != null ? this.Unknown_B8h_Data.Position : 0); - //this.Unknown_C0h_Pointer = (ulong)(this.Unknown_C0h_Data != null ? this.Unknown_C0h_Data.Position : 0); - //this.Unknown_C8h_Pointer = (ulong)(this.Unknown_C8h_Data != null ? this.Unknown_C8h_Data.Position : 0); - //this.VerticesCount = (uint)(this.Vertices != null ? this.Vertices.Count : 0); - //this.PolygonsCount = (uint)(this.Polygons != null ? this.Polygons.Count : 0); - //this.MaterialsPointer = (ulong)(this.Materials != null ? this.Materials.Position : 0); - //this.Unknown_F8h_Pointer = (ulong)(this.Unknown_F8h_Data != null ? this.Unknown_F8h_Data.Position : 0); - //this.PolygonMaterialIndicesPointer = (ulong)(this.PolygonMaterialIndices != null ? this.PolygonMaterialIndices.Position : 0); - //this.MaterialsCount = (byte)(this.Materials != null ? this.Materials.Count : 0); - //this.Count2 = (byte)(this.Unknown_F8h_Data != null ? this.Unknown_F8h_Data.Count : 0); - //TODO: fix all this + this.Unknown_78h_Pointer = (ulong)(this.p1dataBlock != null ? this.p1dataBlock.FilePosition : 0); + this.PolygonsPointer = (ulong)(this.PolygonsBlock != null ? this.PolygonsBlock.FilePosition : 0); + this.VerticesPointer = (ulong)(this.VerticesBlock != null ? this.VerticesBlock.FilePosition : 0); + this.Unknown_B8h_Pointer = (ulong)(this.Unknown_B8h_Block != null ? this.Unknown_B8h_Block.FilePosition : 0); + this.Unknown_C0h_Pointer = (ulong)(this.Unknown_C0h_Block != null ? this.Unknown_C0h_Block.FilePosition : 0); + this.Unknown_C8h_Pointer = (ulong)(this.Unknown_C8h_Data != null ? this.Unknown_C8h_Data.FilePosition : 0); + this.VerticesCount = (uint)(this.VerticesBlock != null ? this.VerticesBlock.ItemCount : 0); + this.PolygonsCount = (uint)(this.Polygons != null ? this.Polygons.Length : 0); + this.MaterialsPointer = (ulong)(this.MaterialsBlock != null ? this.MaterialsBlock.FilePosition : 0); + this.MaterialColoursPointer = (ulong)(this.MaterialColoursBlock != null ? this.MaterialColoursBlock.FilePosition : 0); + this.PolygonMaterialIndicesPointer = (ulong)(this.PolygonMaterialIndicesBlock != null ? this.PolygonMaterialIndicesBlock.FilePosition : 0); + this.MaterialsCount = (byte)(this.MaterialsBlock != null ? this.MaterialsBlock.ItemCount : 0); + this.MaterialColoursCount = (byte)(this.MaterialColoursBlock != null ? this.MaterialColoursBlock.ItemCount : 0); + // write structure data writer.Write(this.Unknown_70h); @@ -540,16 +626,151 @@ namespace CodeWalker.GameFiles public override IResourceBlock[] GetReferences() { var list = new List(base.GetReferences()); - //if (p1data != null) list.Add(p1data); - //if (Polygons != null) list.Add(Polygons); - //if (Vertices != null) list.Add(Vertices); - //if (Unknown_B8h_Data != null) list.Add(Unknown_B8h_Data); - //if (Unknown_C0h_Data != null) list.Add(Unknown_C0h_Data); - //if (Unknown_C8h_Data != null) list.Add(Unknown_C8h_Data); - //if (Materials != null) list.Add(Materials); - //if (Unknown_F8h_Data != null) list.Add(Unknown_F8h_Data); - //if (PolygonMaterialIndices != null) list.Add(PolygonMaterialIndices); - //TODO: fix all these! + if (p1data != null) + { + p1dataBlock = new ResourceSystemStructBlock(p1data); + list.Add(p1dataBlock); + } + if (Polygons != null) + { + MemoryStream ms = new MemoryStream(); + BinaryWriter bw = new BinaryWriter(ms); + foreach (var poly in Polygons) + { + poly.Write(bw); + } + var polydata = new byte[ms.Length]; + ms.Position = 0; + ms.Read(polydata, 0, polydata.Length); + for (int i = 0; i < Polygons.Length; i++) + { + var o = i * 16; + var t = (byte)Polygons[i].Type; + var b = polydata[o]; + polydata[o] = (byte)((b & 0xF8) | (t & 7)); //add the poly types back in! + } + + if (polydata.Length != (Polygons.Length * 16)) + { } + + PolygonsBlock = new ResourceSystemDataBlock(polydata); + list.Add(PolygonsBlock); + } + if (Vertices != null) + { + var verts = new List(); + foreach (var v in Vertices) + { + var vq = v / Quantum; //Vertices[i] = new Vector3(bv.X, bv.Y, bv.Z) * Quantum; + var vs = new BoundVertex_s(vq); + verts.Add(vs); + } + VerticesBlock = new ResourceSystemStructBlock(verts.ToArray()); + list.Add(VerticesBlock); + } + if (Unknown_B8h_Data != null) + { + Unknown_B8h_Block = new ResourceSystemStructBlock(Unknown_B8h_Data); + list.Add(Unknown_B8h_Block); + } + if (Unknown_C0h_Data != null) + { + Unknown_C0h_Block = new ResourceSystemStructBlock(Unknown_C0h_Data); + list.Add(Unknown_C0h_Block); + } + if (Unknown_C8h_Data != null) + { + list.Add(Unknown_C8h_Data);//this one is already a resource block! + } + if (Materials != null) + { + MaterialsBlock = new ResourceSystemStructBlock(Materials); + list.Add(MaterialsBlock); + } + if (MaterialColours != null) + { + MaterialColoursBlock = new ResourceSystemStructBlock(MaterialColours); + list.Add(MaterialColoursBlock); + } + if (PolygonMaterialIndices != null) + { + PolygonMaterialIndicesBlock = new ResourceSystemStructBlock(PolygonMaterialIndices); + list.Add(PolygonMaterialIndicesBlock); + } + return list.ToArray(); + } + } + + [TC(typeof(EXP))] public class BoundUnknown1 : ResourceSystemBlock + { + public uint[][] Items { get; private set; } + + private ResourceSystemStructBlock[] ItemBlocks = null; + + + public override long BlockLength + { + get + { + return Items != null ? (Items.Length*8) : 0; //main pointer array has 8 items, 8 bytes each + } + } + + public BoundUnknown1() { } + public BoundUnknown1(uint[][] items) + { + Items = items; + } + + public override void Read(ResourceDataReader reader, params object[] parameters) + { + if (parameters?.Length < 1) + { return; } //shouldn't happen! + + var itemcounts = (uint[])parameters[0]; + ulong ptr = (ulong)reader.Position; //pointer array pointer + + if (itemcounts != null) + { + ulong[] ptrlist = reader.ReadUlongsAt(ptr, (uint)itemcounts.Length); + Items = new uint[itemcounts.Length][]; + for (int i = 0; i < itemcounts.Length; i++) + { + Items[i] = reader.ReadUintsAt(ptrlist[i], itemcounts[i]); + } + } + } + + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + + //just write the pointer array. + if (ItemBlocks != null) + { + foreach (var item in ItemBlocks) + { + writer.Write((ulong)item.FilePosition); + } + } + + } + + public override IResourceBlock[] GetReferences() + { + var list = new List(base.GetReferences()); + + var ilist = new List>(); + if (Items != null) + { + foreach (var item in Items) + { + var block = new ResourceSystemStructBlock(item); + ilist.Add(block); + list.Add(block); + } + } + ItemBlocks = ilist.ToArray(); + return list.ToArray(); } } @@ -586,8 +807,16 @@ namespace CodeWalker.GameFiles public short X { get; set; } public short Y { get; set; } public short Z { get; set; } + + public BoundVertex_s(Vector3 v) + { + X = (short)v.X; + Y = (short)v.Y; + Z = (short)v.Z; + } } - public enum BoundPolygonType + + public enum BoundPolygonType : byte { Triangle = 0, Sphere = 1, @@ -599,7 +828,7 @@ namespace CodeWalker.GameFiles { public BoundPolygonType Type { get; set; } public abstract void Read(byte[] bytes, int offset); - + public abstract void Write(BinaryWriter bw); public override string ToString() { return Type.ToString(); @@ -637,7 +866,16 @@ namespace CodeWalker.GameFiles edgeIndex2 = BitConverter.ToInt16(bytes, offset + 12); edgeIndex3 = BitConverter.ToInt16(bytes, offset + 14); } - + public override void Write(BinaryWriter bw) + { + bw.Write(triArea); + bw.Write(triIndex1); + bw.Write(triIndex2); + bw.Write(triIndex3); + bw.Write(edgeIndex1); + bw.Write(edgeIndex2); + bw.Write(edgeIndex3); + } public override string ToString() { return base.ToString() + ": " + vertIndex1.ToString() + ", " + vertIndex2.ToString() + ", " + vertIndex3.ToString(); @@ -663,7 +901,14 @@ namespace CodeWalker.GameFiles unused0 = BitConverter.ToUInt32(bytes, offset + 8); unused1 = BitConverter.ToUInt32(bytes, offset + 12); } - + public override void Write(BinaryWriter bw) + { + bw.Write(sphereType); + bw.Write(sphereIndex); + bw.Write(sphereRadius); + bw.Write(unused0); + bw.Write(unused1); + } public override string ToString() { return base.ToString() + ": " + sphereIndex.ToString() + ", " + sphereRadius.ToString(); @@ -691,7 +936,15 @@ namespace CodeWalker.GameFiles unused0 = BitConverter.ToUInt16(bytes, offset + 10); unused1 = BitConverter.ToUInt32(bytes, offset + 12); } - + public override void Write(BinaryWriter bw) + { + bw.Write(capsuleType); + bw.Write(capsuleIndex1); + bw.Write(capsuleRadius); + bw.Write(capsuleIndex2); + bw.Write(unused0); + bw.Write(unused1); + } public override string ToString() { return base.ToString() + ": " + capsuleIndex1.ToString() + ", " + capsuleIndex2.ToString() + ", " + capsuleRadius.ToString(); @@ -719,7 +972,15 @@ namespace CodeWalker.GameFiles boxIndex4 = BitConverter.ToInt16(bytes, offset + 10); unused0 = BitConverter.ToUInt32(bytes, offset + 12); } - + public override void Write(BinaryWriter bw) + { + bw.Write(boxType); + bw.Write(boxIndex1); + bw.Write(boxIndex2); + bw.Write(boxIndex3); + bw.Write(boxIndex4); + bw.Write(unused0); + } public override string ToString() { return base.ToString() + ": " + boxIndex1.ToString() + ", " + boxIndex2.ToString() + ", " + boxIndex3.ToString() + ", " + boxIndex4.ToString(); @@ -747,12 +1008,21 @@ namespace CodeWalker.GameFiles unused0 = BitConverter.ToUInt16(bytes, offset + 10); unused1 = BitConverter.ToUInt32(bytes, offset + 12); } - + public override void Write(BinaryWriter bw) + { + bw.Write(cylinderType); + bw.Write(cylinderIndex1); + bw.Write(cylinderRadius); + bw.Write(cylinderIndex2); + bw.Write(unused0); + bw.Write(unused1); + } public override string ToString() { return base.ToString() + ": " + cylinderIndex1.ToString() + ", " + cylinderIndex2.ToString() + ", " + cylinderRadius.ToString(); } } + [TC(typeof(EXP))] public class BoundBVH : BoundGeometry { public override long BlockLength @@ -855,11 +1125,6 @@ namespace CodeWalker.GameFiles // reference data public ResourcePointerArray64 Children { get; set; } - //public ResourceSimpleArray ChildrenTransformation1 { get; set; } - //public ResourceSimpleArray ChildrenTransformation2 { get; set; } - //public ResourceSimpleArray ChildrenBoundingBoxes { get; set; } - //public ResourceSimpleArray Unknown_90h_Data { get; set; } - //public ResourceSimpleArray Unknown_98h_Data { get; set; } public Matrix[] ChildrenTransformation1 { get; set; } public Matrix[] ChildrenTransformation2 { get; set; } public AABB_s[] ChildrenBoundingBoxes { get; set; } @@ -868,6 +1133,14 @@ namespace CodeWalker.GameFiles public BVH BVH { get; set; } + + private ResourceSystemStructBlock ChildrenTransformation1Block = null; + private ResourceSystemStructBlock ChildrenTransformation2Block = null; + private ResourceSystemStructBlock ChildrenBoundingBoxesBlock = null; + private ResourceSystemStructBlock Unknown_90h_Block = null; + private ResourceSystemStructBlock Unknown_98h_Block = null; + + /// /// Reads the data-block from a stream. /// @@ -901,35 +1174,12 @@ namespace CodeWalker.GameFiles } } - //this.ChildrenTransformation1 = reader.ReadBlockAt>( - // this.ChildrenTransformation1Pointer, // offset - // this.ChildrenCount1 - //); - //this.ChildrenTransformation2 = reader.ReadBlockAt>( - // this.ChildrenTransformation2Pointer, // offset - // this.ChildrenCount1 - //); - //this.ChildrenBoundingBoxes = reader.ReadBlockAt>( - // this.ChildrenBoundingBoxesPointer, // offset - // this.ChildrenCount1 - //); - //this.Unknown_90h_Data = reader.ReadBlockAt>( - // this.Unknown_90h_Pointer, // offset - // this.ChildrenCount1 - //); - //this.Unknown_98h_Data = reader.ReadBlockAt>( - // this.Unknown_98h_Pointer, // offset - // this.ChildrenCount1 - //); - - this.ChildrenTransformation1 = reader.ReadStructsAt(this.ChildrenTransformation1Pointer, this.ChildrenCount1); this.ChildrenTransformation2 = reader.ReadStructsAt(this.ChildrenTransformation2Pointer, this.ChildrenCount1); this.ChildrenBoundingBoxes = reader.ReadStructsAt(this.ChildrenBoundingBoxesPointer, this.ChildrenCount1); this.Unknown_90h_Data = reader.ReadStructsAt(this.Unknown_90h_Pointer, this.ChildrenCount1); this.Unknown_98h_Data = reader.ReadStructsAt(this.Unknown_98h_Pointer, this.ChildrenCount1); - this.BVH = reader.ReadBlockAt( this.BVHPointer // offset ); @@ -944,12 +1194,11 @@ namespace CodeWalker.GameFiles // update structure data this.ChildrenPointer = (ulong)(this.Children != null ? this.Children.FilePosition : 0); - //this.ChildrenTransformation1Pointer = (ulong)(this.ChildrenTransformation1 != null ? this.ChildrenTransformation1.Position : 0); - //this.ChildrenTransformation2Pointer = (ulong)(this.ChildrenTransformation2 != null ? this.ChildrenTransformation2.Position : 0); - //this.ChildrenBoundingBoxesPointer = (ulong)(this.ChildrenBoundingBoxes != null ? this.ChildrenBoundingBoxes.Position : 0); - //this.Unknown_90h_Pointer = (ulong)(this.Unknown_90h_Data != null ? this.Unknown_90h_Data.Position : 0); - //this.Unknown_98h_Pointer = (ulong)(this.Unknown_98h_Data != null ? this.Unknown_98h_Data.Position : 0); - //TODO: fix + this.ChildrenTransformation1Pointer = (ulong)(this.ChildrenTransformation1Block != null ? this.ChildrenTransformation1Block.FilePosition : 0); + this.ChildrenTransformation2Pointer = (ulong)(this.ChildrenTransformation2Block != null ? this.ChildrenTransformation2Block.FilePosition : 0); + this.ChildrenBoundingBoxesPointer = (ulong)(this.ChildrenBoundingBoxesBlock != null ? this.ChildrenBoundingBoxesBlock.FilePosition : 0); + this.Unknown_90h_Pointer = (ulong)(this.Unknown_90h_Block != null ? this.Unknown_90h_Block.FilePosition : 0); + this.Unknown_98h_Pointer = (ulong)(this.Unknown_98h_Block != null ? this.Unknown_98h_Block.FilePosition : 0); this.ChildrenCount1 = (ushort)(this.Children != null ? this.Children.Count : 0); this.ChildrenCount2 = (ushort)(this.Children != null ? this.Children.Count : 0); this.BVHPointer = (ulong)(this.BVH != null ? this.BVH.FilePosition : 0); @@ -974,11 +1223,31 @@ namespace CodeWalker.GameFiles { var list = new List(base.GetReferences()); if (Children != null) list.Add(Children); - //if (ChildrenTransformation1 != null) list.Add(ChildrenTransformation1); //TODO: fix - //if (ChildrenTransformation2 != null) list.Add(ChildrenTransformation2); - //if (ChildrenBoundingBoxes != null) list.Add(ChildrenBoundingBoxes); - //if (Unknown_90h_Data != null) list.Add(Unknown_90h_Data); - //if (Unknown_98h_Data != null) list.Add(Unknown_98h_Data); + if (ChildrenTransformation1 != null) + { + ChildrenTransformation1Block = new ResourceSystemStructBlock(ChildrenTransformation1); + list.Add(ChildrenTransformation1Block); + } + if (ChildrenTransformation2 != null) + { + ChildrenTransformation2Block = new ResourceSystemStructBlock(ChildrenTransformation2); + list.Add(ChildrenTransformation2Block); + } + if (ChildrenBoundingBoxes != null) + { + ChildrenBoundingBoxesBlock = new ResourceSystemStructBlock(ChildrenBoundingBoxes); + list.Add(ChildrenBoundingBoxesBlock); + } + if (Unknown_90h_Data != null) + { + Unknown_90h_Block = new ResourceSystemStructBlock(Unknown_90h_Data); + list.Add(Unknown_90h_Block); + } + if (Unknown_98h_Data != null) + { + Unknown_98h_Block = new ResourceSystemStructBlock(Unknown_98h_Data); + list.Add(Unknown_98h_Block); + } if (BVH != null) list.Add(BVH); return list.ToArray(); } @@ -993,88 +1262,6 @@ namespace CodeWalker.GameFiles } } - [TC(typeof(EXP))] public class BoundDisc : Bounds - { - public override long BlockLength - { - get { return 128; } - } - - // structure data - public uint Unknown_70h { get; set; } // 0x00000000 - public uint Unknown_74h { get; set; } // 0x00000000 - public uint Unknown_78h { get; set; } // 0x00000000 - public uint Unknown_7Ch { get; set; } // 0x00000000 - - /// - /// Reads the data-block from a stream. - /// - public override void Read(ResourceDataReader reader, params object[] parameters) - { - base.Read(reader, parameters); - - // read structure data - this.Unknown_70h = reader.ReadUInt32(); - this.Unknown_74h = reader.ReadUInt32(); - this.Unknown_78h = reader.ReadUInt32(); - this.Unknown_7Ch = reader.ReadUInt32(); - } - - /// - /// Writes the data-block to a stream. - /// - public override void Write(ResourceDataWriter writer, params object[] parameters) - { - base.Write(writer, parameters); - - // write structure data - writer.Write(this.Unknown_70h); - writer.Write(this.Unknown_74h); - writer.Write(this.Unknown_78h); - writer.Write(this.Unknown_7Ch); - } - } - [TC(typeof(EXP))] public class BoundCylinder : Bounds - { - public override long BlockLength - { - get { return 128; } - } - - // structure data - public uint Unknown_70h { get; set; } // 0x00000000 - public uint Unknown_74h { get; set; } // 0x00000000 - public uint Unknown_78h { get; set; } // 0x00000000 - public uint Unknown_7Ch { get; set; } // 0x00000000 - - /// - /// Reads the data-block from a stream. - /// - public override void Read(ResourceDataReader reader, params object[] parameters) - { - base.Read(reader, parameters); - - // read structure data - this.Unknown_70h = reader.ReadUInt32(); - this.Unknown_74h = reader.ReadUInt32(); - this.Unknown_78h = reader.ReadUInt32(); - this.Unknown_7Ch = reader.ReadUInt32(); - } - - /// - /// Writes the data-block to a stream. - /// - public override void Write(ResourceDataWriter writer, params object[] parameters) - { - base.Write(writer, parameters); - - // write structure data - writer.Write(this.Unknown_70h); - writer.Write(this.Unknown_74h); - writer.Write(this.Unknown_78h); - writer.Write(this.Unknown_7Ch); - } - } [TC(typeof(EXP))] public class BVH : ResourceSystemBlock { @@ -1084,9 +1271,6 @@ namespace CodeWalker.GameFiles } // structure data - //public ulong NodesPointer { get; set; } - //public uint NodesCount { get; set; } - //public uint Count2 { get; set; } public ResourceSimpleList64b_s Nodes { get; set; } public uint Unknown_10h { get; set; } // 0x00000000 public uint Unknown_14h { get; set; } // 0x00000000 @@ -1099,10 +1283,6 @@ namespace CodeWalker.GameFiles public Vector4 Quantum { get; set; } // bounding box dimension / 2^16 public ResourceSimpleList64_s Trees { get; set; } - // reference data - ////public ResourceSimpleArray2 Nodes; - //public BVHNode_s[] Nodes { get; set; } - //public BVHNode_s[] Nodes_Unk1 { get; set; } /// /// Reads the data-block from a stream. @@ -1110,9 +1290,6 @@ namespace CodeWalker.GameFiles public override void Read(ResourceDataReader reader, params object[] parameters) { // read structure data - //this.NodesPointer = reader.ReadUInt64(); - //this.NodesCount = reader.ReadUInt32(); - //this.Count2 = reader.ReadUInt32(); this.Nodes = reader.ReadBlock>(); this.Unknown_10h = reader.ReadUInt32(); this.Unknown_14h = reader.ReadUInt32(); @@ -1123,21 +1300,8 @@ namespace CodeWalker.GameFiles this.BoundingBoxCenter = reader.ReadStruct(); this.QuantumInverse = reader.ReadStruct(); this.Quantum = reader.ReadStruct(); - this.Trees = reader.ReadBlock>(); - // read reference data - ////this.Nodes = reader.ReadBlockAt>( - //// this.NodesPointer, // offset - //// this.NodesCount, - //// this.Count2 - this.NodesCount - ////); - - //this.Nodes = reader.ReadStructsAt(this.NodesPointer, this.NodesCount); - //this.Nodes_Unk1 = reader.ReadStructsAt(this.NodesPointer + NodesCount * 16 /*sizeof(BVHNode_s)*/, Count2 - NodesCount); - - //if (Nodes_Unk1 != null) - //{ } } /// @@ -1145,16 +1309,8 @@ namespace CodeWalker.GameFiles /// public override void Write(ResourceDataWriter writer, params object[] parameters) { - // update structure data - //this.NodesPointer = (ulong)(this.Nodes != null ? this.Nodes.Position : 0); - //this.NodesCount = (uint)(this.Nodes != null ? this.Nodes.Array1.Count : 0); - //this.Count2 = (uint)(this.Nodes != null ? this.Nodes.Array1.Count + this.Nodes.Array2.Count : 0); - //TODO: fix // write structure data - //writer.Write(this.NodesPointer); - //writer.Write(this.NodesCount); - //writer.Write(this.Count2); writer.WriteBlock(this.Nodes); writer.Write(this.Unknown_10h); writer.Write(this.Unknown_14h); @@ -1174,7 +1330,7 @@ namespace CodeWalker.GameFiles public override IResourceBlock[] GetReferences() { var list = new List(); - //if (Nodes != null) list.Add(Nodes); //TODO: fix! + //if (Nodes != null) list.Add(Nodes); //if (Trees != null) list.Add(Trees); return list.ToArray(); } @@ -1183,11 +1339,6 @@ namespace CodeWalker.GameFiles { return new Tuple[] { new Tuple(0x0, Nodes), - //new Tuple(0x20, BoundingBoxMin), - //new Tuple(0x30, BoundingBoxMax), - //new Tuple(0x40, BoundingBoxCenter), - //new Tuple(0x50, QuantumInverse), - //new Tuple(0x60, Quantum), new Tuple(0x70, Trees) }; } diff --git a/CodeWalker.Core/GameFiles/Resources/ResourceBaseTypes.cs b/CodeWalker.Core/GameFiles/Resources/ResourceBaseTypes.cs index 8712c4a..17ff40c 100644 --- a/CodeWalker.Core/GameFiles/Resources/ResourceBaseTypes.cs +++ b/CodeWalker.Core/GameFiles/Resources/ResourceBaseTypes.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; @@ -1747,8 +1748,8 @@ namespace CodeWalker.GameFiles get { long len = 8 * Data.Count; - foreach (var f in Data) - len += f.BlockLength; + //foreach (var f in Data) + // len += f.BlockLength; return len; } } @@ -1936,4 +1937,78 @@ namespace CodeWalker.GameFiles + + public class ResourceSystemDataBlock : ResourceSystemBlock //used for writing resources. + { + public byte[] Data { get; set; } + public int DataLength { get; set; } + + public override long BlockLength + { + get + { + return (Data != null) ? Data.Length : DataLength; + } + } + + + public ResourceSystemDataBlock(byte[] data) + { + Data = data; + DataLength = (Data != null) ? Data.Length : 0; + } + + + public override void Read(ResourceDataReader reader, params object[] parameters) + { + Data = reader.ReadBytes(DataLength); + } + + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + writer.Write(Data); + } + } + + public class ResourceSystemStructBlock : ResourceSystemBlock where T : struct //used for writing resources. + { + public T[] Items { get; set; } + public int ItemCount { get; set; } + public int StructureSize { get; set; } + + public override long BlockLength + { + get + { + return ((Items != null) ? Items.Length : ItemCount) * StructureSize; + } + } + + public ResourceSystemStructBlock(T[] items) + { + Items = items; + ItemCount = (Items != null) ? Items.Length : 0; + StructureSize = Marshal.SizeOf(typeof(T)); + } + + public override void Read(ResourceDataReader reader, params object[] parameters) + { + int datalength = ItemCount * StructureSize; + byte[] data = reader.ReadBytes(datalength); + Items = MetaTypes.ConvertDataArray(data, 0, ItemCount); + } + + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + + byte[] data = MetaTypes.ConvertArrayToBytes(Items); + if (data != null) + { + writer.Write(data); + } + } + } + + + } diff --git a/CodeWalker.Core/GameFiles/Resources/ResourceData.cs b/CodeWalker.Core/GameFiles/Resources/ResourceData.cs index 53e2b20..8818724 100644 --- a/CodeWalker.Core/GameFiles/Resources/ResourceData.cs +++ b/CodeWalker.Core/GameFiles/Resources/ResourceData.cs @@ -684,80 +684,6 @@ namespace CodeWalker.GameFiles - - - public class ResourceSystemDataBlock : ResourceSystemBlock //used for writing resources. - { - public byte[] Data { get; set; } - public int DataLength { get; set; } - - public override long BlockLength - { - get - { - return (Data != null) ? Data.Length : DataLength; - } - } - - - public ResourceSystemDataBlock(byte[] data) - { - Data = data; - DataLength = (Data != null) ? Data.Length : 0; - } - - - public override void Read(ResourceDataReader reader, params object[] parameters) - { - Data = reader.ReadBytes(DataLength); - } - - public override void Write(ResourceDataWriter writer, params object[] parameters) - { - writer.Write(Data); - } - } - - public class ResourceSystemStructBlock : ResourceSystemBlock where T : struct //used for writing resources. - { - public T[] Items { get; set; } - public int ItemCount { get; set; } - public int StructureSize { get; set; } - - public override long BlockLength - { - get - { - return ((Items != null) ? Items.Length : ItemCount) * StructureSize; - } - } - - public ResourceSystemStructBlock(T[] items) - { - Items = items; - ItemCount = (Items != null) ? Items.Length : 0; - StructureSize = Marshal.SizeOf(typeof(T)); - } - - public override void Read(ResourceDataReader reader, params object[] parameters) - { - int datalength = ItemCount * StructureSize; - byte[] data = reader.ReadBytes(datalength); - Items = MetaTypes.ConvertDataArray(data, 0, ItemCount); - } - - public override void Write(ResourceDataWriter writer, params object[] parameters) - { - - byte[] data = MetaTypes.ConvertArrayToBytes(Items); - if (data != null) - { - writer.Write(data); - } - } - } - - //public interface ResourceDataStruct //{ // void Read(ResourceDataReader reader);