diff --git a/CodeWalker.Core/GameFiles/Resources/Bounds.cs b/CodeWalker.Core/GameFiles/Resources/Bounds.cs index 546495b..b21d3b5 100644 --- a/CodeWalker.Core/GameFiles/Resources/Bounds.cs +++ b/CodeWalker.Core/GameFiles/Resources/Bounds.cs @@ -169,6 +169,13 @@ namespace CodeWalker.GameFiles public YbnFile OwnerYbn { get; set; } public object Owner { get; set; } public string OwnerName { get; set; } + public bool OwnerIsFragment + { + get + { + return ((Owner is FragPhysicsLOD) || (Owner is FragPhysArchetype) || (Owner is FragDrawable)); + } + } public string GetName() { string n = OwnerName; @@ -417,8 +424,11 @@ namespace CodeWalker.GameFiles YbnXml.SelfClosingTag(sb, indent, "CompositePosition " + FloatUtil.GetVector3XmlString(Position)); YbnXml.SelfClosingTag(sb, indent, "CompositeRotation " + FloatUtil.GetVector4XmlString(Orientation.ToVector4())); YbnXml.SelfClosingTag(sb, indent, "CompositeScale " + FloatUtil.GetVector3XmlString(Scale)); - YbnXml.StringTag(sb, indent, "CompositeFlags1", CompositeFlags1.Flags1.ToString()); - YbnXml.StringTag(sb, indent, "CompositeFlags2", CompositeFlags1.Flags2.ToString()); + if (!Parent.OwnerIsFragment) + { + YbnXml.StringTag(sb, indent, "CompositeFlags1", CompositeFlags1.Flags1.ToString()); + YbnXml.StringTag(sb, indent, "CompositeFlags2", CompositeFlags1.Flags2.ToString()); + } } } public virtual void ReadXml(XmlNode node) @@ -444,11 +454,14 @@ namespace CodeWalker.GameFiles Position = Xml.GetChildVector3Attributes(node, "CompositePosition"); Orientation = Xml.GetChildVector4Attributes(node, "CompositeRotation").ToQuaternion(); Scale = Xml.GetChildVector3Attributes(node, "CompositeScale"); - var f = new BoundCompositeChildrenFlags(); - f.Flags1 = Xml.GetChildEnumInnerText(node, "CompositeFlags1"); - f.Flags2 = Xml.GetChildEnumInnerText(node, "CompositeFlags2"); - CompositeFlags1 = f; - CompositeFlags2 = f; + if (!Parent.OwnerIsFragment) + { + var f = new BoundCompositeChildrenFlags(); + f.Flags1 = Xml.GetChildEnumInnerText(node, "CompositeFlags1"); + f.Flags2 = Xml.GetChildEnumInnerText(node, "CompositeFlags2"); + CompositeFlags1 = f; + CompositeFlags2 = f; + } } } public static void WriteXmlNode(Bounds b, StringBuilder sb, int indent, string name = "Bounds") @@ -1206,7 +1219,7 @@ namespace CodeWalker.GameFiles CalculateQuantum(); UpdateEdgeIndices(); UpdateTriangleAreas(); - + UpdateUnknown1Counts(); } public override IResourceBlock[] GetReferences() @@ -1847,6 +1860,17 @@ namespace CodeWalker.GameFiles } } + public void UpdateUnknown1Counts() + { + if (Unknown1Data?.Items != null) + { + Unknown1Counts = new uint[8]; + for (int i = 0; i < 8; i++) + { + Unknown1Counts[i] = (i < Unknown1Data.Items.Length) ? (uint)(Unknown1Data.Items[i]?.Length ?? 0) : 0; + } + } + } public bool DeletePolygon(BoundPolygon p) { @@ -2513,7 +2537,14 @@ namespace CodeWalker.GameFiles YbnXml.OpenTag(sb, indent, "Children"); foreach (var child in c) { - Bounds.WriteXmlNode(child, sb, cind, "Item"); + if (c == null) + { + YbnXml.SelfClosingTag(sb, cind, "Item"); + } + else + { + Bounds.WriteXmlNode(child, sb, cind, "Item"); + } } YbnXml.CloseTag(sb, indent, "Children"); } @@ -2531,8 +2562,15 @@ namespace CodeWalker.GameFiles var blist = new List(); foreach (XmlNode inode in cnodes) { - var b = Bounds.ReadXmlNode(inode, Owner, this); - blist.Add(b); + if (inode.HasChildNodes) + { + var b = Bounds.ReadXmlNode(inode, Owner, this); + blist.Add(b); + } + else + { + blist.Add(null); + } } var arr = blist.ToArray(); Children = new ResourcePointerArray64(); @@ -2651,6 +2689,12 @@ namespace CodeWalker.GameFiles ChildrenFlags2 = null; return; } + if (OwnerIsFragment)//don't use flags in fragments + { + ChildrenFlags1 = null; + ChildrenFlags2 = null; + return; + } var cf1 = new List(); var cf2 = new List(); @@ -3988,7 +4032,7 @@ namespace CodeWalker.GameFiles { var collist = new List(); var rowlist = new List(); - var str = node.InnerText; + var str = node.InnerText.Trim(); var split = str.Split('\n'); for (int i = 0; i < split.Length; i++) { @@ -4110,11 +4154,11 @@ namespace CodeWalker.GameFiles this.Unknown_14h = reader.ReadUInt32(); this.Unknown_18h = reader.ReadUInt32(); this.Unknown_1Ch = reader.ReadUInt32(); - this.BoundingBoxMin = reader.ReadStruct(); - this.BoundingBoxMax = reader.ReadStruct(); - this.BoundingBoxCenter = reader.ReadStruct(); - this.QuantumInverse = reader.ReadStruct(); - this.Quantum = reader.ReadStruct(); + this.BoundingBoxMin = reader.ReadVector4(); + this.BoundingBoxMax = reader.ReadVector4(); + this.BoundingBoxCenter = reader.ReadVector4(); + this.QuantumInverse = reader.ReadVector4(); + this.Quantum = reader.ReadVector4(); this.Trees = reader.ReadBlock>(); } diff --git a/CodeWalker.Core/GameFiles/Resources/Drawable.cs b/CodeWalker.Core/GameFiles/Resources/Drawable.cs index 99a24a1..6b070f2 100644 --- a/CodeWalker.Core/GameFiles/Resources/Drawable.cs +++ b/CodeWalker.Core/GameFiles/Resources/Drawable.cs @@ -465,10 +465,6 @@ namespace CodeWalker.GameFiles foreach (var x in Parameters) { offset += 16; - } - - foreach (var x in Parameters) - { offset += 16 * x.DataType; } @@ -756,7 +752,6 @@ namespace CodeWalker.GameFiles } else if (type == "Array") { - p.DataType = 2; var vecs = new List(); var inodes = pnode.SelectNodes("Value"); foreach (XmlNode inode in inodes) @@ -768,6 +763,7 @@ namespace CodeWalker.GameFiles vecs.Add(new Vector4(fx, fy, fz, fw)); } p.Data = vecs.ToArray(); + p.DataType = (byte)vecs.Count; } plist.Add(p); hlist.Add(h); @@ -3830,10 +3826,10 @@ namespace CodeWalker.GameFiles // read structure data this.ShaderGroupPointer = reader.ReadUInt64(); this.SkeletonPointer = reader.ReadUInt64(); - this.BoundingCenter = reader.ReadStruct(); + this.BoundingCenter = reader.ReadVector3(); this.BoundingSphereRadius = reader.ReadSingle(); - this.BoundingBoxMin = reader.ReadStruct(); - this.BoundingBoxMax = reader.ReadStruct(); + this.BoundingBoxMin = reader.ReadVector4(); + this.BoundingBoxMax = reader.ReadVector4(); this.DrawableModelsHighPointer = reader.ReadUInt64(); this.DrawableModelsMediumPointer = reader.ReadUInt64(); this.DrawableModelsLowPointer = reader.ReadUInt64(); @@ -3879,39 +3875,8 @@ namespace CodeWalker.GameFiles ); - var allModels = new List(); - if (DrawableModelsHigh != null) allModels.AddRange(DrawableModelsHigh.data_items); - if (DrawableModelsMedium != null) allModels.AddRange(DrawableModelsMedium.data_items); - if (DrawableModelsLow != null) allModels.AddRange(DrawableModelsLow.data_items); - if (DrawableModelsVeryLow != null) allModels.AddRange(DrawableModelsVeryLow.data_items); - if ((DrawableModelsX != null) && (DrawableModelsX != DrawableModelsHigh)) - { - allModels.AddRange(DrawableModelsX.data_items); - } - AllModels = allModels.ToArray(); - - - var vds = new Dictionary(); - foreach (DrawableModel model in AllModels) - { - foreach (var geom in model.Geometries.data_items) - { - var info = geom.VertexBuffer.Info; - var declid = info.GetDeclarationId(); - - if (!vds.ContainsKey(declid)) - { - vds.Add(declid, info); - } - //else //debug test - //{ - // if ((VertexDecls[declid].Stride != info.Stride)||(VertexDecls[declid].Types != info.Types)) - // { - // } - //} - } - } - VertexDecls = new Dictionary(vds); + BuildAllModels(); + BuildVertexDecls(); AssignGeometryShaders(ShaderGroup); @@ -4248,6 +4213,8 @@ namespace CodeWalker.GameFiles } BuildRenderMasks(); + BuildAllModels(); + BuildVertexDecls(); } public override IResourceBlock[] GetReferences() @@ -4267,15 +4234,15 @@ namespace CodeWalker.GameFiles public void AssignGeometryShaders(ShaderGroup shaderGrp) { - if (shaderGrp != null) - { - ShaderGroup = shaderGrp; - } + //if (shaderGrp != null) + //{ + // ShaderGroup = shaderGrp; + //} //map the shaders to the geometries - if (ShaderGroup != null) + if (shaderGrp != null) { - var shaders = ShaderGroup.Shaders.data_items; + var shaders = shaderGrp.Shaders.data_items; foreach (DrawableModel model in AllModels) { if (model?.Geometries?.data_items == null) continue; @@ -4296,6 +4263,47 @@ namespace CodeWalker.GameFiles } + + public void BuildAllModels() + { + var allModels = new List(); + if (DrawableModelsHigh != null) allModels.AddRange(DrawableModelsHigh.data_items); + if (DrawableModelsMedium != null) allModels.AddRange(DrawableModelsMedium.data_items); + if (DrawableModelsLow != null) allModels.AddRange(DrawableModelsLow.data_items); + if (DrawableModelsVeryLow != null) allModels.AddRange(DrawableModelsVeryLow.data_items); + if ((DrawableModelsX != null) && (DrawableModelsX != DrawableModelsHigh)) + { + allModels.AddRange(DrawableModelsX.data_items); + } + AllModels = allModels.ToArray(); + } + + public void BuildVertexDecls() + { + var vds = new Dictionary(); + foreach (DrawableModel model in AllModels) + { + foreach (var geom in model.Geometries.data_items) + { + var info = geom.VertexBuffer.Info; + var declid = info.GetDeclarationId(); + + if (!vds.ContainsKey(declid)) + { + vds.Add(declid, info); + } + //else //debug test + //{ + // if ((VertexDecls[declid].Stride != info.Stride)||(VertexDecls[declid].Types != info.Types)) + // { + // } + //} + } + } + VertexDecls = new Dictionary(vds); + } + + public void BuildRenderMasks() { var hmask = BuildRenderMask(DrawableModelsHigh?.data_items); diff --git a/CodeWalker.Core/GameFiles/Resources/Frag.cs b/CodeWalker.Core/GameFiles/Resources/Frag.cs index b576d79..93def0b 100644 --- a/CodeWalker.Core/GameFiles/Resources/Frag.cs +++ b/CodeWalker.Core/GameFiles/Resources/Frag.cs @@ -191,23 +191,8 @@ namespace CodeWalker.GameFiles if (VehicleGlassWindows != null) { } - //for vehicle wheels, the shaderGroup in the model seems to be missing, but have to use the main drawable's shaders. - if ((Drawable != null) && (PhysicsLODGroup != null) && (PhysicsLODGroup.PhysicsLOD1 != null)) - { - var pl1 = PhysicsLODGroup.PhysicsLOD1; - if ((pl1.Children != null) && (pl1.Children.data_items != null)) - { - for (int i = 0; i < pl1.Children.data_items.Length; i++) - { - var pch = pl1.Children.data_items[i]; - if ((pch.Drawable1 != null)) - { - pch.Drawable1.AssignGeometryShaders(Drawable.ShaderGroup); - } - } - } - } + AssignChildrenShaders(); @@ -454,6 +439,7 @@ namespace CodeWalker.GameFiles Unknown_B8h = Xml.GetChildIntAttribute(node, "UnknownB8", "value"); Unknown_BCh = Xml.GetChildIntAttribute(node, "UnknownBC", "value"); Unknown_C0h = Xml.GetChildIntAttribute(node, "UnknownC0", "value"); + Unknown_C4h = Xml.GetChildIntAttribute(node, "UnknownC4", "value"); Unknown_CCh = Xml.GetChildFloatAttribute(node, "UnknownCC", "value"); Unknown_D0h = Xml.GetChildFloatAttribute(node, "UnknownD0", "value"); Unknown_D4h = Xml.GetChildFloatAttribute(node, "UnknownD4", "value"); @@ -512,6 +498,9 @@ namespace CodeWalker.GameFiles LightAttributes.data_items = XmlMeta.ReadItemArray(node, "Lights"); Cloths = new ResourcePointerList64(); Cloths.data_items = XmlMeta.ReadItemArray(node, "Cloths"); + + AssignChildrenSkeletonsAndBounds(); + AssignChildrenShaders(); } public static void WriteXmlNode(FragType f, StringBuilder sb, int indent, string ddsfolder, string name = "Fragment") { @@ -528,6 +517,105 @@ namespace CodeWalker.GameFiles return f; } + + + public void AssignChildrenShaders() + { + if (PhysicsLODGroup == null) return; + + //for things like vehicle wheels, the shaderGroup in the model is missing, so use the main drawable's shaders. + var pdrwbl = Drawable ?? Drawable2; + var pskel = pdrwbl?.Skeleton; + + void assigndr(FragDrawable dr, BoundComposite pbcmp, int i) + { + if (dr == null) return; + if (pdrwbl == null) return; + dr.OwnerDrawable = pdrwbl;//this is also the signal for XML export to skip the skeleton and bounds + dr.AssignGeometryShaders(pdrwbl.ShaderGroup); + + //// just testing + //if (dr.Skeleton != pskel) + //{ }//no hit + //var pbch = pbcmp?.Children?.data_items; + //if (pbch != null) + //{ + // if (i >= pbch.Length) + // { }//no hit + // else + // { + // if (pbch[i] != dr.Bound) + // { }//no hit + // } + //} + //else + //{ }//no hit + }; + void assign(FragPhysicsLOD lod) + { + var children = lod?.Children?.data_items; + var pbcmp1 = (lod?.Archetype1?.Bound ?? pdrwbl?.Bound) as BoundComposite; + var pbcmp2 = (lod?.Archetype2?.Bound ?? pdrwbl?.Bound) as BoundComposite; + + //if (lod?.Archetype1?.Bound != lod?.Bound) + //{ }//no hit! + //if (lod?.Archetype2?.Bound != lod?.Bound) + //{ }//hit + + if (children == null) return; + for (int i = 0; i < children.Length; i++) + { + var child = children[i]; + assigndr(child?.Drawable1, pbcmp1, i); + assigndr(child?.Drawable2, pbcmp2, i); + } + }; + + assign(PhysicsLODGroup.PhysicsLOD1); + assign(PhysicsLODGroup.PhysicsLOD2); + assign(PhysicsLODGroup.PhysicsLOD3); + + } + + public void AssignChildrenSkeletonsAndBounds() + { + if (PhysicsLODGroup == null) return; + + var pdrwbl = Drawable ?? Drawable2; + var pskel = pdrwbl?.Skeleton; + + void assignskb(FragDrawable dr, BoundComposite pbcmp, int i) + { + if (dr == null) return; + if (pdrwbl == null) return; + var pbch = pbcmp?.Children?.data_items; + dr.Skeleton = pskel; + dr.Bound = ((pbch != null) && (i < pbch.Length)) ? pbch[i] : null; + }; + void assign(FragPhysicsLOD lod) + { + if (lod == null) return; + lod.Bound = lod.Archetype1?.Bound; + var children = lod.Children?.data_items; + var pbcmp1 = (lod.Archetype1?.Bound ?? pdrwbl?.Bound) as BoundComposite; + var pbcmp2 = (lod.Archetype2?.Bound ?? pdrwbl?.Bound) as BoundComposite; + if (children == null) return; + for (int i = 0; i < children.Length; i++) + { + var child = children[i]; + assignskb(child?.Drawable1, pbcmp1, i); + assignskb(child?.Drawable2, pbcmp2, i); + } + }; + + assign(PhysicsLODGroup.PhysicsLOD1); + assign(PhysicsLODGroup.PhysicsLOD2); + assign(PhysicsLODGroup.PhysicsLOD3); + + } + + + public override IResourceBlock[] GetReferences() { var list = new List(base.GetReferences()); @@ -592,7 +680,7 @@ namespace CodeWalker.GameFiles public FragType OwnerFragment { get; set; } //for handy use public EnvironmentCloth OwnerCloth { get; set; } public FragPhysTypeChild OwnerFragmentPhys { get; set; } - + public FragDrawable OwnerDrawable { get; set; } //if inheriting shaders, skeletons and bounds private ResourceSystemStructBlock FragMatricesIndsBlock = null; //used for saving only private ResourceSystemStructBlock FragMatricesBlock = null; @@ -604,7 +692,7 @@ namespace CodeWalker.GameFiles // read structure data this.Unknown_0A8h = reader.ReadUInt64(); - this.FragMatrix = reader.ReadStruct(); + this.FragMatrix = reader.ReadMatrix(); this.BoundPointer = reader.ReadUInt64(); this.FragMatricesIndsPointer = reader.ReadUInt64(); this.FragMatricesIndsCount = reader.ReadUInt16(); @@ -633,6 +721,12 @@ namespace CodeWalker.GameFiles Bound.Owner = this; } + //if (Bound is BoundComposite bcmp) + //{//no hit + // if ((bcmp.ChildrenFlags1 != null) || (bcmp.ChildrenFlags2 != null)) + // { }//no hit + //} + if (FragMatricesInds != null) @@ -720,13 +814,25 @@ namespace CodeWalker.GameFiles YftXml.CloseTag(sb, indent, "Matrices"); } + + var skel = Skeleton; + var bnds = Bound; + if (OwnerDrawable != null) //don't export skeleton or bounds if this is a frag child! + { + Skeleton = null; + Bound = null; + } + base.WriteXml(sb, indent, ddsfolder); Bounds.WriteXmlNode(Bound, sb, indent); + + Skeleton = skel; + Bound = bnds; } public override void ReadXml(XmlNode node, string ddsfolder) { - Name = Xml.GetChildInnerText(node, "Name"); + Name = Xml.GetChildInnerText(node, "Name"); if (string.IsNullOrEmpty(Name)) Name = null; FragMatrix = Xml.GetChildMatrix(node, "Matrix"); var msnode = node.SelectSingleNode("Matrices"); @@ -914,13 +1020,13 @@ namespace CodeWalker.GameFiles public override void Read(ResourceDataReader reader, params object[] parameters) { // read structure data - this.Matrix = reader.ReadStruct(); + this.Matrix = reader.ReadMatrix(); this.VertexDeclaration.Read(reader); this.Unknown_50h = reader.ReadSingle(); this.Unknown_54h = reader.ReadUInt16(); this.Flags = reader.ReadUInt16(); - this.Vector1 = reader.ReadStruct(); - this.Vector2 = reader.ReadStruct(); + this.Vector1 = reader.ReadVector3(); + this.Vector2 = reader.ReadVector3(); //if (Unknown_50h > 1.0f) //{ }//no hit @@ -1026,7 +1132,7 @@ namespace CodeWalker.GameFiles public void Read(ResourceDataReader reader) { - Matrix = reader.ReadStruct(); + Matrix = reader.ReadMatrix(); UnkUint1 = reader.ReadUInt32(); //0x56475743 "VGWC" ItemID = reader.ReadUInt16(); UnkUshort1 = reader.ReadUInt16(); @@ -1381,8 +1487,8 @@ namespace CodeWalker.GameFiles } public void ReadXml(XmlNode node) { - Data1 = Xml.GetChildRawByteArray(node, "Data1", 10); - Data2 = Xml.GetChildRawByteArray(node, "Data2", 10); + Data1 = Xml.GetChildRawByteArray(node, "Data1", 10); if ((Data1?.Length ?? 0) == 0) Data1 = null; + Data2 = Xml.GetChildRawByteArray(node, "Data2", 10); if ((Data2?.Length ?? 0) == 0) Data2 = null; Start1 = (byte)Xml.GetChildUIntAttribute(node, "Start1", "value"); End1 = (byte)(Start1 + (Data1?.Length ?? 0) - 1); if (Data2 != null) @@ -1449,7 +1555,7 @@ namespace CodeWalker.GameFiles //{ }//no hit //// just testing - //BuildOffsets(); + BuildOffsets(); } public override void Write(ResourceDataWriter writer, params object[] parameters) { @@ -1508,6 +1614,7 @@ namespace CodeWalker.GameFiles } } Items = ilist.ToArray(); + ItemCount = (ushort)ilist.Count; BuildOffsets(); } @@ -1517,7 +1624,7 @@ namespace CodeWalker.GameFiles public void BuildOffsets() { var offs = new List(); - var bc = 16u + (uint)ItemOffsets.Length*8u; + var bc = 16u; if (Items != null) { foreach (var item in Items) @@ -1533,6 +1640,7 @@ namespace CodeWalker.GameFiles { offs.Add(new ItemOffsetStruct()); } + bc += (uint)offs.Count * 8u; } //// just testing @@ -1755,15 +1863,15 @@ namespace CodeWalker.GameFiles this.Unknown_1Ch = reader.ReadSingle(); this.ArticulatedBodyTypePointer = reader.ReadUInt64(); this.ChildrenUnkFloatsPointer = reader.ReadUInt64(); - this.Unknown_30h = reader.ReadStruct(); - this.Unknown_40h = reader.ReadStruct(); - this.Unknown_50h = reader.ReadStruct(); - this.Unknown_60h = reader.ReadStruct(); - this.Unknown_70h = reader.ReadStruct(); - this.Unknown_80h = reader.ReadStruct(); - this.Unknown_90h = reader.ReadStruct(); - this.Unknown_A0h = reader.ReadStruct(); - this.Unknown_B0h = reader.ReadStruct(); + this.Unknown_30h = reader.ReadVector4(); + this.Unknown_40h = reader.ReadVector4(); + this.Unknown_50h = reader.ReadVector4(); + this.Unknown_60h = reader.ReadVector4(); + this.Unknown_70h = reader.ReadVector4(); + this.Unknown_80h = reader.ReadVector4(); + this.Unknown_90h = reader.ReadVector4(); + this.Unknown_A0h = reader.ReadVector4(); + this.Unknown_B0h = reader.ReadVector4(); this.GroupNamesPointer = reader.ReadUInt64(); this.GroupsPointer = reader.ReadUInt64(); this.ChildrenPointer = reader.ReadUInt64(); @@ -1829,6 +1937,12 @@ namespace CodeWalker.GameFiles Bound.Owner = this; } + //if (Bound is BoundComposite bcmp) + //{ + // if ((bcmp.ChildrenFlags1 != null) || (bcmp.ChildrenFlags2 != null)) + // { }//no hit + //} + //if (Unknown_04h != 1) //{ }//no hit @@ -1901,6 +2015,16 @@ namespace CodeWalker.GameFiles this.ChildrenCount = (byte)(this.Children != null ? this.Children.Count : 0); this.ChildrenCount2 = this.ChildrenCount; + if ((Groups?.data_items != null) && (GroupNames != null)) + { + var gnplist = new List(); + foreach (var grp in Groups?.data_items) + { + gnplist.Add((ulong)grp.FilePosition + 128);//manually write group names pointers as offsets to the groups + } + GroupNames.data_pointers = gnplist.ToArray(); + } + // write structure data writer.Write(this.VFT); @@ -2005,10 +2129,10 @@ namespace CodeWalker.GameFiles } YftXml.CloseTag(sb, indent, "Children"); } - if (Bound != null) - { - Bounds.WriteXmlNode(Bound, sb, indent); - } + //if (Bound != null) + //{ + // Bounds.WriteXmlNode(Bound, sb, indent); + //} if (UnknownData1 != null) { YftXml.WriteRawArray(sb, UnknownData1, indent, "UnknownData1", ""); @@ -2086,17 +2210,16 @@ namespace CodeWalker.GameFiles Children = new ResourcePointerArray64(); Children.data_items = clist.ToArray(); } - var bnode = node.SelectSingleNode("Bounds"); - if (bnode != null) - { - Bound = Bounds.ReadXmlNode(bnode, this); - } + //var bnode = node.SelectSingleNode("Bounds"); + //if (bnode != null) + //{ + // Bound = Bounds.ReadXmlNode(bnode, this); + //} var ud1 = Xml.GetChildRawByteArray(node, "UnknownData1", 10); var ud2 = Xml.GetChildRawByteArray(node, "UnknownData2", 10); UnknownData1 = ((ud1?.Length ?? 0) > 0) ? ud1 : null; UnknownData2 = ((ud2?.Length ?? 0) > 0) ? ud2 : null; - BuildChildrenData(); BuildGroupsData(); } @@ -2193,7 +2316,11 @@ namespace CodeWalker.GameFiles UnknownData2Block = new ResourceSystemStructBlock(UnknownData2); list.Add(UnknownData2Block); } - if (GroupNames != null) list.Add(GroupNames); + if (GroupNames != null) + { + GroupNames.ManualPointerOverride = (Groups != null); //we'll just write a set of pointers into the Groups + list.Add(GroupNames); + } return list.ToArray(); } } @@ -2820,14 +2947,14 @@ namespace CodeWalker.GameFiles this.Unknown_50h = reader.ReadSingle(); this.Unknown_54h = reader.ReadSingle(); this.Unknown_58h = reader.ReadUInt64(); - this.Unknown_60h = reader.ReadStruct(); - this.Unknown_70h = reader.ReadStruct(); - this.Unknown_80h = reader.ReadStruct(); - this.Unknown_90h = reader.ReadStruct(); - this.Unknown_A0h = reader.ReadStruct(); - this.Unknown_B0h = reader.ReadStruct(); - this.Unknown_C0h = reader.ReadStruct(); - this.Unknown_D0h = reader.ReadStruct(); + this.Unknown_60h = reader.ReadVector4(); + this.Unknown_70h = reader.ReadVector4(); + this.Unknown_80h = reader.ReadVector4(); + this.Unknown_90h = reader.ReadVector4(); + this.Unknown_A0h = reader.ReadVector4(); + this.Unknown_B0h = reader.ReadVector4(); + this.Unknown_C0h = reader.ReadVector4(); + this.Unknown_D0h = reader.ReadVector4(); // read reference data this.Name = reader.ReadStringAt(this.NamePointer); @@ -2838,6 +2965,12 @@ namespace CodeWalker.GameFiles Bound.Owner = this; } + //if (Bound is BoundComposite bcmp) + //{ + // if ((bcmp.ChildrenFlags1 != null) || (bcmp.ChildrenFlags2 != null)) + // { }//no hit + //} + //switch (VFT) //{ // case 0x4062a988: diff --git a/CodeWalker.Core/GameFiles/Resources/ResourceBaseTypes.cs b/CodeWalker.Core/GameFiles/Resources/ResourceBaseTypes.cs index 8b15ae6..bb9f789 100644 --- a/CodeWalker.Core/GameFiles/Resources/ResourceBaseTypes.cs +++ b/CodeWalker.Core/GameFiles/Resources/ResourceBaseTypes.cs @@ -1490,9 +1490,10 @@ namespace CodeWalker.GameFiles } - public ulong[] data_pointers { get; private set; } + public ulong[] data_pointers { get; set; } public T[] data_items { get; set; } + public bool ManualPointerOverride { get; set; } = false;//use this to manually write data_pointers private ResourceSystemStructBlock[] data_blocks = null; @@ -1518,20 +1519,23 @@ namespace CodeWalker.GameFiles public override void Write(ResourceDataWriter writer, params object[] parameters) { // update... - var list = new List(); - if (data_blocks != null) + if (ManualPointerOverride == false) { - foreach (var x in data_blocks) + var list = new List(); + if (data_blocks != null) { - list.Add((ulong)x.FilePosition); + foreach (var x in data_blocks) + { + list.Add((ulong)x.FilePosition); + } } + //foreach (var x in data_items) + // if (x != null) + // data_pointers.Add((uint)x.Position); + // else + // data_pointers.Add((uint)0); + data_pointers = list.ToArray(); } - //foreach (var x in data_items) - // if (x != null) - // data_pointers.Add((uint)x.Position); - // else - // data_pointers.Add((uint)0); - data_pointers = list.ToArray(); // write... foreach (var x in data_pointers) @@ -1543,19 +1547,22 @@ namespace CodeWalker.GameFiles { var list = new List(); - var blocks = new List>(); - if (data_items != null) + if (ManualPointerOverride == false) { - foreach (var x in data_items) + var blocks = new List>(); + if (data_items != null) { - var block = new ResourceSystemStructBlock(new[] { x }); - blocks.Add(block); - list.Add(block); + foreach (var x in data_items) + { + var block = new ResourceSystemStructBlock(new[] { x }); + blocks.Add(block); + list.Add(block); + } } + data_blocks = blocks.ToArray(); + //foreach (var x in data_items) + // list.Add(x); } - data_blocks = blocks.ToArray(); - //foreach (var x in data_items) - // list.Add(x); return list.ToArray(); } diff --git a/Forms/ModelForm.cs b/Forms/ModelForm.cs index b7d2c83..c4c0cdf 100644 --- a/Forms/ModelForm.cs +++ b/Forms/ModelForm.cs @@ -678,7 +678,7 @@ namespace CodeWalker.Forms MoveCameraToView(dr.BoundingCenter, dr.BoundingSphereRadius); } - UpdateModelsUI(yft.Fragment.Drawable); + UpdateModelsUI(yft.Fragment?.Drawable, yft.Fragment); } public void LoadModel(YbnFile ybn) { @@ -952,54 +952,9 @@ namespace CodeWalker.Forms - private void UpdateModelsUI(DrawableBase drawable) + private void UpdateModelsUI(DrawableBase drawable, object detailsObject = null) { - DetailsPropertyGrid.SelectedObject = drawable; - - DrawableDrawFlags.Clear(); - Renderer.SelectionModelDrawFlags.Clear(); - Renderer.SelectionGeometryDrawFlags.Clear(); - ModelsTreeView.Nodes.Clear(); - ModelsTreeView.ShowRootLines = false; - TexturesTreeView.Nodes.Clear(); - if (drawable != null) - { - AddDrawableModelsTreeNodes(drawable.DrawableModelsHigh, "High Detail", true); - AddDrawableModelsTreeNodes(drawable.DrawableModelsMedium, "Medium Detail", false); - AddDrawableModelsTreeNodes(drawable.DrawableModelsLow, "Low Detail", false); - AddDrawableModelsTreeNodes(drawable.DrawableModelsVeryLow, "Very Low Detail", false); - //AddSelectionDrawableModelsTreeNodes(item.Drawable.DrawableModelsX, "X Detail", false); - - var fdrawable = drawable as FragDrawable; - if (fdrawable != null) - { - var plod1 = fdrawable.OwnerFragment?.PhysicsLODGroup?.PhysicsLOD1; - if ((plod1 != null) && (plod1.Children?.data_items != null)) - { - foreach (var child in plod1.Children.data_items) - { - var cdrwbl = child.Drawable1; - if ((cdrwbl != null) && (cdrwbl.AllModels?.Length > 0)) - { - if (cdrwbl.Owner is FragDrawable) continue; //it's a copied drawable... eg a wheel - - var dname = child.GroupName; - AddDrawableModelsTreeNodes(cdrwbl.DrawableModelsHigh, dname + " - High Detail", true); - AddDrawableModelsTreeNodes(cdrwbl.DrawableModelsMedium, dname + " - Medium Detail", false); - AddDrawableModelsTreeNodes(cdrwbl.DrawableModelsLow, dname + " - Low Detail", false); - AddDrawableModelsTreeNodes(cdrwbl.DrawableModelsVeryLow, dname + " - Very Low Detail", false); - } - } - } - } - - } - } - private void UpdateModelsUI(FragType frag) - { - DetailsPropertyGrid.SelectedObject = frag; - - var drawable = frag.Drawable; + DetailsPropertyGrid.SelectedObject = detailsObject ?? drawable; DrawableDrawFlags.Clear(); Renderer.SelectionModelDrawFlags.Clear();