Changed Skeleton Bones into array and added SkeletonBonesBlock

This commit is contained in:
dexy 2020-03-15 00:52:36 +11:00
parent 1f516a87b3
commit 38bb3ebb16
4 changed files with 155 additions and 66 deletions

View File

@ -902,7 +902,7 @@ namespace CodeWalker.GameFiles
// reference data
public ResourcePointerArray64<SkeletonBoneTag> BoneTags { get; set; }
public ResourceSimpleArray<Bone> 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<ResourcePointerArray64<SkeletonBoneTag>>(
this.BoneTagsPointer, // offset
this.BoneTagsCapacity
);
this.Bones = reader.ReadBlockAt<ResourceSimpleArray<Bone>>(
this.BonesPointer, // offset
this.BonesCount
);
this.BoneTags = reader.ReadBlockAt<ResourcePointerArray64<SkeletonBoneTag>>(this.BoneTagsPointer, this.BoneTagsCapacity);
this.Bones = reader.ReadBlockAt<SkeletonBonesBlock>((this.BonesPointer != 0) ? (BonesPointer - 16) : 0, (uint)this.BonesCount);
this.TransformationsInverted = reader.ReadStructsAt<Matrix>(this.TransformationsInvertedPointer, this.BonesCount);
this.Transformations = reader.ReadStructsAt<Matrix>(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<ResourcePointerListHeader>((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<Bone>(node, "Bones");
if (bones != null)
{
Bones = new ResourceSimpleArray<Bone>();
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<ushort, Bone>();
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<short>();
var childs = new List<short>();
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<SkeletonBoneTag>();
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<Matrix>();
var transformsinv = new List<Matrix>();
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<Bone>();
if (Bones.Data != null)
skel.Bones = new SkeletonBonesBlock();
if (Bones.Items != null)
{
skel.Bones.Data = new List<Bone>();
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<Bone>();
}
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<long, IResourceBlock>[] GetParts()
{
var list = new List<Tuple<long, IResourceBlock>>();
long length = 16;
if (Items != null)
{
foreach (var b in Items)
{
list.Add(new Tuple<long, IResourceBlock>(length, b));
length += b.BlockLength;
}
}
return list.ToArray();
}
}
[TypeConverter(typeof(ExpandableObjectConverter))] public class SkeletonBoneTag : ResourceSystemBlock
{
public override long BlockLength

View File

@ -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;

View File

@ -170,7 +170,7 @@ namespace CodeWalker.Rendering
Matrix[] fragtransforms = null;
Vector4 fragoffset = Vector4.Zero;
int fragtransformid = 0;
List<Bone> 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();

View File

@ -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,19 +3172,22 @@ 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];
for (int b = 0; b < skel.Bones.Items.Length; b++)
{
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[dstbone.Index] = srcbone;
dskel.Bones.Items[dstbone.Index] = srcbone;
dskel.BonesMap[srcbone.Tag] = srcbone;
}
}
}
}
}
bool drawFlag = true;