diff --git a/CodeWalker.Core/GameFiles/Resources/Drawable.cs b/CodeWalker.Core/GameFiles/Resources/Drawable.cs index 602c2b7..af604ed 100644 --- a/CodeWalker.Core/GameFiles/Resources/Drawable.cs +++ b/CodeWalker.Core/GameFiles/Resources/Drawable.cs @@ -902,7 +902,7 @@ namespace CodeWalker.GameFiles // reference data public ResourcePointerArray64 BoneTags { get; set; } - public ResourceSimpleArray Bones { get; set; } + public SkeletonBonesBlock Bones { get; set; } public Matrix[] TransformationsInverted { get; set; } public Matrix[] Transformations { get; set; } @@ -948,14 +948,8 @@ namespace CodeWalker.GameFiles this.Unknown_68h = reader.ReadUInt64(); // read reference data - this.BoneTags = reader.ReadBlockAt>( - this.BoneTagsPointer, // offset - this.BoneTagsCapacity - ); - this.Bones = reader.ReadBlockAt>( - this.BonesPointer, // offset - this.BonesCount - ); + this.BoneTags = reader.ReadBlockAt>(this.BoneTagsPointer, this.BoneTagsCapacity); + this.Bones = reader.ReadBlockAt((this.BonesPointer != 0) ? (BonesPointer - 16) : 0, (uint)this.BonesCount); this.TransformationsInverted = reader.ReadStructsAt(this.TransformationsInvertedPointer, this.BonesCount); this.Transformations = reader.ReadStructsAt(this.TransformationsPointer, this.BonesCount); this.ParentIndices = reader.ReadShortsAt(this.ParentIndicesPointer, this.BonesCount); @@ -972,6 +966,15 @@ namespace CodeWalker.GameFiles //if (BoneTagsCount != Math.Min(BonesCount, BoneTagsCapacity)) //{ }//no hits + //if (BonesPointer != 0) + //{ + // var bhdr = reader.ReadStructAt((long)BonesPointer - 16); + // if (bhdr.Pointer != BonesCount) + // { }//no hit + // if ((bhdr.Count != 0) || (bhdr.Capacity != 0) || (bhdr.Unknown != 0)) + // { }//no hit + //} + //if (Unknown_8h != 0) //{ } //if (Unknown_48h != 0) @@ -988,12 +991,12 @@ namespace CodeWalker.GameFiles // update structure data this.BoneTagsPointer = (ulong)(this.BoneTags != null ? this.BoneTags.FilePosition : 0); this.BoneTagsCapacity = (ushort)(this.BoneTags != null ? this.BoneTags.Count : 0); - this.BonesPointer = (ulong)(this.Bones != null ? this.Bones.FilePosition : 0); + this.BonesPointer = (ulong)(this.Bones != null ? this.Bones.FilePosition+16 : 0); this.TransformationsInvertedPointer = (ulong)(this.TransformationsInvertedBlock != null ? this.TransformationsInvertedBlock.FilePosition : 0); this.TransformationsPointer = (ulong)(this.TransformationsBlock != null ? this.TransformationsBlock.FilePosition : 0); this.ParentIndicesPointer = (ulong)(this.ParentIndicesBlock != null ? this.ParentIndicesBlock.FilePosition : 0); this.ChildIndicesPointer = (ulong)(this.ChildIndicesBlock != null ? this.ChildIndicesBlock.FilePosition : 0); - this.BonesCount = (ushort)(this.Bones != null ? this.Bones.Count : 0); + this.BonesCount = (ushort)(this.Bones?.Items != null ? this.Bones.Items.Length : 0); this.ChildIndicesCount = (ushort)(this.ChildIndicesBlock != null ? this.ChildIndicesBlock.ItemCount : 0); this.BoneTagsCount = Math.Min(BonesCount, BoneTagsCapacity); @@ -1029,9 +1032,9 @@ namespace CodeWalker.GameFiles YdrXml.ValueTag(sb, indent, "Unknown54", Unknown_54h.Hash.ToString()); YdrXml.ValueTag(sb, indent, "Unknown58", Unknown_58h.Hash.ToString()); - if (Bones?.Data != null) + if (Bones?.Items != null) { - YdrXml.WriteItemArray(sb, Bones.Data.ToArray(), indent, "Bones"); + YdrXml.WriteItemArray(sb, Bones.Items, indent, "Bones"); } } @@ -1045,8 +1048,8 @@ namespace CodeWalker.GameFiles var bones = XmlMeta.ReadItemArray(node, "Bones"); if (bones != null) { - Bones = new ResourceSimpleArray(); - Bones.Data = bones.ToList(); + Bones = new SkeletonBonesBlock(); + Bones.Items = bones; } BuildIndices(); @@ -1093,16 +1096,16 @@ namespace CodeWalker.GameFiles public void AssignBoneParents() { - if ((Bones != null) && (ParentIndices != null)) + if ((Bones?.Items != null) && (ParentIndices != null)) { - var maxcnt = Math.Min(Bones.Count, ParentIndices.Length); + var maxcnt = Math.Min(Bones.Items.Length, ParentIndices.Length); for (int i = 0; i < maxcnt; i++) { - var bone = Bones[i]; + var bone = Bones.Items[i]; var pind = ParentIndices[i]; - if ((pind >= 0) && (pind < Bones.Count)) + if ((pind >= 0) && (pind < Bones.Items.Length)) { - bone.Parent = Bones[pind]; + bone.Parent = Bones.Items[pind]; } } } @@ -1111,11 +1114,11 @@ namespace CodeWalker.GameFiles public void BuildBonesMap() { BonesMap = new Dictionary(); - if (Bones != null) + if (Bones?.Items != null) { - for (int i = 0; i < Bones.Count; i++) + for (int i = 0; i < Bones.Items.Length; i++) { - var bone = Bones[i]; + var bone = Bones.Items[i]; BonesMap[bone.Tag] = bone; bone.UpdateAnimTransform(); @@ -1131,12 +1134,12 @@ namespace CodeWalker.GameFiles { var parents = new List(); var childs = new List(); - if (Bones != null) + if (Bones?.Items != null) { Bone lastbone = null; - for (int i = 0; i < Bones.Count; i++) + for (int i = 0; i < Bones.Items.Length; i++) { - var bone = Bones[i]; + var bone = Bones.Items[i]; var pind = bone.ParentIndex; parents.Add(pind); if (pind >= 0) @@ -1187,11 +1190,11 @@ namespace CodeWalker.GameFiles public void BuildBoneTags() { var tags = new List(); - if (Bones?.Data != null) + if (Bones?.Items != null) { - for (int i = 0; i < Bones.Count; i++) + for (int i = 0; i < Bones.Items.Length; i++) { - var bone = Bones[i]; + var bone = Bones.Items[i]; var tag = new SkeletonBoneTag(); tag.BoneTag = bone.Tag; tag.BoneIndex = (uint)i; @@ -1277,9 +1280,9 @@ namespace CodeWalker.GameFiles { var transforms = new List(); var transformsinv = new List(); - if (Bones?.Data != null) + if (Bones?.Items != null) { - foreach (var bone in Bones.Data) + foreach (var bone in Bones.Items) { var pos = bone.Translation; var ori = bone.Rotation; @@ -1367,8 +1370,8 @@ namespace CodeWalker.GameFiles public void ResetBoneTransforms() { - if (Bones?.Data == null) return; - foreach (var bone in Bones.Data) + if (Bones?.Items == null) return; + foreach (var bone in Bones.Items) { bone.ResetAnimTransform(); } @@ -1376,14 +1379,14 @@ namespace CodeWalker.GameFiles } public void UpdateBoneTransforms() { - if (Bones?.Data == null) return; - if ((BoneTransforms == null) || (BoneTransforms.Length != Bones.Data.Count)) + if (Bones?.Items == null) return; + if ((BoneTransforms == null) || (BoneTransforms.Length != Bones.Items.Length)) { - BoneTransforms = new Matrix3_s[Bones.Data.Count]; + BoneTransforms = new Matrix3_s[Bones.Items.Length]; } - for (int i = 0; i < Bones.Data.Count; i++) + for (int i = 0; i < Bones.Items.Length; i++) { - var bone = Bones.Data[i]; + var bone = Bones.Items[i]; Matrix b = bone.SkinTransform; Matrix3_s bt = new Matrix3_s(); bt.Row1 = b.Column1; @@ -1439,13 +1442,13 @@ namespace CodeWalker.GameFiles } if (Bones != null) { - skel.Bones = new ResourceSimpleArray(); - if (Bones.Data != null) + skel.Bones = new SkeletonBonesBlock(); + if (Bones.Items != null) { - skel.Bones.Data = new List(); - for (int i = 0; i < Bones.Data.Count; i++) + skel.Bones.Items = new Bone[Bones.Items.Length]; + for (int i = 0; i < Bones.Items.Length; i++) { - var ob = Bones.Data[i]; + var ob = Bones.Items[i]; var nb = new Bone(); nb.Rotation = ob.Rotation; nb.Translation = ob.Translation; @@ -1463,7 +1466,7 @@ namespace CodeWalker.GameFiles nb.AnimTransform = ob.AnimTransform; nb.BindTransformInv = ob.BindTransformInv; nb.SkinTransform = ob.SkinTransform; - skel.Bones.Data.Add(nb); + skel.Bones.Items[i] = nb; } } } @@ -1483,6 +1486,89 @@ namespace CodeWalker.GameFiles } + [TypeConverter(typeof(ExpandableObjectConverter))] public class SkeletonBonesBlock : ResourceSystemBlock + { + public override long BlockLength + { + get + { + long length = 16; + if (Items != null) + { + foreach (var b in Items) + { + length += b.BlockLength; + } + } + return length; + } + } + + public uint Count { get; set; } + public uint Unk0; // 0 + public uint Unk1; // 0 + public uint Unk2; // 0 + public Bone[] Items { get; set; } + + + public override void Read(ResourceDataReader reader, params object[] parameters) + { + Count = reader.ReadUInt32(); + Unk0 = reader.ReadUInt32(); + Unk1 = reader.ReadUInt32(); + Unk2 = reader.ReadUInt32(); + + var count = (uint)parameters[0]; + var items = new Bone[count]; + for (uint i = 0; i < count; i++) + { + items[i] = reader.ReadBlock(); + } + Items = items; + + + //if (Count != count) + //{ }//no hit + //if (Unk0 != 0) + //{ }//no hit + //if (Unk1 != 0) + //{ }//no hit + //if (Unk2 != 0) + //{ }//no hit + + } + + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + Count = (uint)(Items?.Length ?? 0); + + writer.Write(Count); + writer.Write(Unk0); + writer.Write(Unk1); + writer.Write(Unk2); + + foreach (var b in Items) + { + b.Write(writer); + } + } + + public override Tuple[] GetParts() + { + var list = new List>(); + long length = 16; + if (Items != null) + { + foreach (var b in Items) + { + list.Add(new Tuple(length, b)); + length += b.BlockLength; + } + } + return list.ToArray(); + } + } + [TypeConverter(typeof(ExpandableObjectConverter))] public class SkeletonBoneTag : ResourceSystemBlock { public override long BlockLength diff --git a/CodeWalker/Project/Panels/GenerateLODLightsPanel.cs b/CodeWalker/Project/Panels/GenerateLODLightsPanel.cs index a039d35..7ca5ccc 100644 --- a/CodeWalker/Project/Panels/GenerateLODLightsPanel.cs +++ b/CodeWalker/Project/Panels/GenerateLODLightsPanel.cs @@ -149,11 +149,11 @@ namespace CodeWalker.Project.Panels Matrix xform = Matrix.Identity; int boneidx = 0; var skeleton = dwbl.Skeleton; - if (skeleton?.Bones?.Data != null) + if (skeleton?.Bones?.Items != null) { - for (int j = 0; j < skeleton.Bones.Data.Count; j++) + for (int j = 0; j < skeleton.Bones.Items.Length; j++) { - var tbone = skeleton.Bones.Data[j]; + var tbone = skeleton.Bones.Items[j]; if (tbone.Tag == la.BoneId) { boneidx = j; diff --git a/CodeWalker/Rendering/Renderable.cs b/CodeWalker/Rendering/Renderable.cs index ae732c7..f107405 100644 --- a/CodeWalker/Rendering/Renderable.cs +++ b/CodeWalker/Rendering/Renderable.cs @@ -170,7 +170,7 @@ namespace CodeWalker.Rendering Matrix[] fragtransforms = null; Vector4 fragoffset = Vector4.Zero; int fragtransformid = 0; - List bones = null; + Bone[] bones = null; bool usepose = false; if (skeleton != null) { @@ -246,8 +246,8 @@ namespace CodeWalker.Rendering } hastransforms = (modeltransforms != null) || (fragtransforms != null); - hasbones = ((skeleton.Bones != null) && (skeleton.Bones.Data != null)); - bones = hasbones ? skeleton.Bones.Data : null; + hasbones = ((skeleton.Bones != null) && (skeleton.Bones.Items != null)); + bones = hasbones ? skeleton.Bones.Items : null; } HasSkeleton = hasskeleton; @@ -268,7 +268,7 @@ namespace CodeWalker.Rendering int boneidx = model.BoneIndex; Matrix trans = (boneidx < modeltransforms.Length) ? modeltransforms[boneidx] : Matrix.Identity; - Bone bone = (hasbones && (boneidx < bones.Count)) ? bones[boneidx] : null; + Bone bone = (hasbones && (boneidx < bones.Length)) ? bones[boneidx] : null; if (mi < HDModels.Length) //populate bone links map for hd models { @@ -398,11 +398,11 @@ namespace CodeWalker.Rendering } private void UpdateBoneTransforms() { - if (Skeleton?.Bones?.Data == null) return; + if (Skeleton?.Bones?.Items == null) return; Skeleton.UpdateBoneTransforms(); - var bones = Skeleton.Bones?.Data; + var bones = Skeleton.Bones?.Items; var bonetransforms = Skeleton.BoneTransforms; var drawbl = Key; @@ -416,7 +416,7 @@ namespace CodeWalker.Rendering var geom = model.Geometries[g]; var boneids = geom?.DrawableGeom?.BoneIds; if (boneids == null) continue; - if (boneids.Length != bones.Count) + if (boneids.Length != bones.Length) { var idc = boneids.Length; if (geom.BoneTransforms == null) @@ -511,7 +511,7 @@ namespace CodeWalker.Rendering var dwbl = this.Key; var skel = Skeleton; - var bones = skel?.Bones; + var bones = skel?.Bones?.Items; if (bones == null) { return; } @@ -615,7 +615,7 @@ namespace CodeWalker.Rendering } } - for (int i = 0; i < bones.Count; i++) + for (int i = 0; i < bones.Length; i++) { var bone = bones[i]; var tag = bone.Tag; @@ -636,7 +636,7 @@ namespace CodeWalker.Rendering } } - for (int i = 0; i < bones.Count; i++) + for (int i = 0; i < bones.Length; i++) { var bone = bones[i]; bone.UpdateAnimTransform(); diff --git a/CodeWalker/Rendering/Renderer.cs b/CodeWalker/Rendering/Renderer.cs index 5241a92..f2c2e69 100644 --- a/CodeWalker/Rendering/Renderer.cs +++ b/CodeWalker/Rendering/Renderer.cs @@ -1263,11 +1263,11 @@ namespace CodeWalker.Rendering Vector3 campos = camera.Position - (entity?.Position ?? Vector3.Zero); var pinds = skeleton.ParentIndices; - var bones = skeleton.Bones; + var bones = skeleton.Bones?.Items; if ((pinds == null) || (bones == null)) continue; var xforms = skeleton.Transformations; - int cnt = Math.Min(pinds.Length, bones.Count); + int cnt = Math.Min(pinds.Length, bones.Length); for (int i = 0; i < cnt; i++) { var pind = pinds[i]; @@ -3172,15 +3172,18 @@ namespace CodeWalker.Rendering else if (drawable.Skeleton != skel) { var dskel = drawable.Skeleton; //put the bones of the fragment into the drawable. drawable's bones in this case seem messed up! - for (int b = 0; b < skel.Bones.Count; b++) + if (skel.Bones?.Items != null) { - var srcbone = skel.Bones[b]; - var dstbone = srcbone; - if (dskel.BonesMap.TryGetValue(srcbone.Tag, out dstbone)) + for (int b = 0; b < skel.Bones.Items.Length; b++) { - if (srcbone == dstbone) break; //bone reassignment already done! - dskel.Bones[dstbone.Index] = srcbone; - dskel.BonesMap[srcbone.Tag] = srcbone; + var srcbone = skel.Bones.Items[b]; + var dstbone = srcbone; + if (dskel.BonesMap.TryGetValue(srcbone.Tag, out dstbone)) + { + if (srcbone == dstbone) break; //bone reassignment already done! + dskel.Bones.Items[dstbone.Index] = srcbone; + dskel.BonesMap[srcbone.Tag] = srcbone; + } } } }