Changed DrawableModel.Geometries to array

This commit is contained in:
dexy 2020-03-14 01:30:56 +11:00
parent 4941f86193
commit e48503e130
10 changed files with 160 additions and 80 deletions

View File

@ -2044,21 +2044,21 @@ namespace CodeWalker.GameFiles
get get
{ {
var off = (long)48; var off = (long)48;
//off += (GeometriesCount1 * 2); //ShaderMapping off += (GeometriesCount1 * 2); //ShaderMapping
//if (GeometriesCount1 == 1) off += 6; if (GeometriesCount1 == 1) off += 6;
//else off += ((16 - (off % 16)) % 16); else off += ((16 - (off % 16)) % 16);
//off += (GeometriesCount1 * 8); //Geometries pointers off += (GeometriesCount1 * 8); //Geometries pointers
//off += ((16 - (off % 16)) % 16); off += ((16 - (off % 16)) % 16);
//off += (GeometriesCount1 + ((GeometriesCount1 > 1) ? 1 : 0)) * 32; //BoundsData off += (GeometriesCount1 + ((GeometriesCount1 > 1) ? 1 : 0)) * 32; //BoundsData
//for (int i = 0; i < GeometriesCount1; i++) for (int i = 0; i < GeometriesCount1; i++)
//{ {
// var geom = Geometries?.data_items[i]; var geom = (Geometries != null) ? Geometries[i] : null;
// if (geom != null) if (geom != null)
// { {
// off += ((16 - (off % 16)) % 16); off += ((16 - (off % 16)) % 16);
// off += geom.BlockLength; //Geometries off += geom.BlockLength; //Geometries
// } }
//} }
return off; return off;
} }
} }
@ -2075,6 +2075,10 @@ namespace CodeWalker.GameFiles
public uint SkeletonBinding { get; set; }//4th byte is bone index, 2nd byte for skin meshes public uint SkeletonBinding { get; set; }//4th byte is bone index, 2nd byte for skin meshes
public ushort RenderMaskFlags { get; set; } //First byte is called "Mask" in GIMS EVO public ushort RenderMaskFlags { get; set; } //First byte is called "Mask" in GIMS EVO
public ushort GeometriesCount3 { get; set; } //always equal to GeometriesCount1, is it ShaderMappingCount? public ushort GeometriesCount3 { get; set; } //always equal to GeometriesCount1, is it ShaderMappingCount?
public ushort[] ShaderMapping { get; set; }
public ulong[] GeometryPointers { get; set; }
public AABB_s[] BoundsData { get; set; }
public DrawableGeometry[] Geometries { get; set; }
public byte BoneIndex public byte BoneIndex
{ {
@ -2110,14 +2114,6 @@ namespace CodeWalker.GameFiles
// reference data
public ResourcePointerArray64<DrawableGeometry> Geometries { get; set; }
public AABB_s[] BoundsData { get; set; }
public ushort[] ShaderMapping { get; set; }
private ResourceSystemStructBlock<AABB_s> BoundsDataBlock = null; //for saving only
private ResourceSystemStructBlock<ushort> ShaderMappingBlock = null;
@ -2126,9 +2122,9 @@ namespace CodeWalker.GameFiles
get get
{ {
long val = 0; long val = 0;
if ((Geometries != null) && (Geometries.data_items != null)) if (Geometries != null)
{ {
foreach(var geom in Geometries.data_items) foreach(var geom in Geometries)
{ {
if (geom == null) continue; if (geom == null) continue;
if (geom.VertexData != null) if (geom.VertexData != null)
@ -2175,17 +2171,16 @@ namespace CodeWalker.GameFiles
this.RenderMaskFlags = reader.ReadUInt16(); this.RenderMaskFlags = reader.ReadUInt16();
this.GeometriesCount3 = reader.ReadUInt16(); this.GeometriesCount3 = reader.ReadUInt16();
this.ShaderMapping = reader.ReadUshortsAt(this.ShaderMappingPointer, this.GeometriesCount1, false);
this.GeometryPointers = reader.ReadUlongsAt(this.GeometriesPointer, this.GeometriesCount1, false);
this.BoundsData = reader.ReadStructsAt<AABB_s>(this.BoundsPointer, (uint)(this.GeometriesCount1 > 1 ? this.GeometriesCount1 + 1 : this.GeometriesCount1), false);
this.Geometries = reader.ReadBlocks<DrawableGeometry>(this.GeometryPointers);
// read reference data if (Geometries != null)
this.Geometries = reader.ReadBlockAt<ResourcePointerArray64<DrawableGeometry>>(this.GeometriesPointer, this.GeometriesCount1);
this.BoundsData = reader.ReadStructsAt<AABB_s>(this.BoundsPointer, (uint)(this.GeometriesCount1 > 1 ? this.GeometriesCount1 + 1 : this.GeometriesCount1));
this.ShaderMapping = reader.ReadUshortsAt(this.ShaderMappingPointer, this.GeometriesCount1);
if (Geometries?.data_items != null)
{ {
for (int i = 0; i < Geometries.data_items.Length; i++) for (int i = 0; i < Geometries.Length; i++)
{ {
var geom = Geometries.data_items[i]; var geom = Geometries[i];
if (geom != null) if (geom != null)
{ {
geom.ShaderID = ((ShaderMapping != null) && (i < ShaderMapping.Length)) ? ShaderMapping[i] : (ushort)0; geom.ShaderID = ((ShaderMapping != null) && (i < ShaderMapping.Length)) ? ShaderMapping[i] : (ushort)0;
@ -2258,12 +2253,33 @@ namespace CodeWalker.GameFiles
public override void Write(ResourceDataWriter writer, params object[] parameters) public override void Write(ResourceDataWriter writer, params object[] parameters)
{ {
// update structure data // update structure data
this.GeometriesPointer = (ulong)(this.Geometries != null ? this.Geometries.FilePosition : 0); this.GeometriesCount1 = (ushort)(this.Geometries != null ? this.Geometries.Length : 0);
this.GeometriesCount1 = (ushort)(this.Geometries != null ? this.Geometries.Count : 0);
this.GeometriesCount2 = this.GeometriesCount1;//is this correct? this.GeometriesCount2 = this.GeometriesCount1;//is this correct?
this.GeometriesCount3 = this.GeometriesCount1;//is this correct? this.GeometriesCount3 = this.GeometriesCount1;//is this correct?
this.BoundsPointer = (ulong)(this.BoundsDataBlock != null ? this.BoundsDataBlock.FilePosition : 0);
this.ShaderMappingPointer = (ulong)(this.ShaderMappingBlock != null ? this.ShaderMappingBlock.FilePosition : 0); long pad(long o) => ((16 - (o % 16)) % 16);
var off = writer.Position + 48;
this.ShaderMappingPointer = (ulong)off;
off += (GeometriesCount1 * 2); //ShaderMapping
if (GeometriesCount1 == 1) off += 6;
else off += pad(off);
this.GeometriesPointer = (ulong)off;
off += (GeometriesCount1 * 8); //Geometries pointers
off += pad(off);
this.BoundsPointer = (ulong)off;
off += (BoundsData.Length) * 32; //BoundsData
this.GeometryPointers = new ulong[GeometriesCount1];
for (int i = 0; i < GeometriesCount1; i++)
{
var geom = (Geometries != null) ? Geometries[i] : null;
if (geom != null)
{
off += pad(off);
this.GeometryPointers[i] = (ulong)off;
off += geom.BlockLength; //Geometries
}
}
// write structure data // write structure data
@ -2278,6 +2294,39 @@ namespace CodeWalker.GameFiles
writer.Write(this.SkeletonBinding); writer.Write(this.SkeletonBinding);
writer.Write(this.RenderMaskFlags); writer.Write(this.RenderMaskFlags);
writer.Write(this.GeometriesCount3); writer.Write(this.GeometriesCount3);
for (int i = 0; i < GeometriesCount1; i++)
{
writer.Write(ShaderMapping[i]);
}
if (GeometriesCount1 == 1)
{
writer.Write(new byte[6]);
}
else
{
writer.WritePadding(16);
}
for (int i = 0; i < GeometriesCount1; i++)
{
writer.Write(GeometryPointers[i]);
}
writer.WritePadding(16);
for (int i = 0; i < BoundsData.Length; i++)
{
writer.WriteStruct(BoundsData[i]);
}
for (int i = 0; i < GeometriesCount1; i++)
{
var geom = (Geometries != null) ? Geometries[i] : null;
if (geom != null)
{
writer.WritePadding(16);
writer.WriteBlock(geom);
}
}
} }
public void WriteXml(StringBuilder sb, int indent) public void WriteXml(StringBuilder sb, int indent)
{ {
@ -2287,9 +2336,9 @@ namespace CodeWalker.GameFiles
YdrXml.ValueTag(sb, indent, "BoneIndex", BoneIndex.ToString()); YdrXml.ValueTag(sb, indent, "BoneIndex", BoneIndex.ToString());
YdrXml.ValueTag(sb, indent, "Unknown1", SkeletonBindUnk1.ToString()); YdrXml.ValueTag(sb, indent, "Unknown1", SkeletonBindUnk1.ToString());
if (Geometries?.data_items != null) if (Geometries != null)
{ {
YdrXml.WriteItemArray(sb, Geometries.data_items, indent, "Geometries"); YdrXml.WriteItemArray(sb, Geometries, indent, "Geometries");
} }
} }
@ -2308,8 +2357,7 @@ namespace CodeWalker.GameFiles
var geoms = XmlMeta.ReadItemArray<DrawableGeometry>(node, "Geometries"); var geoms = XmlMeta.ReadItemArray<DrawableGeometry>(node, "Geometries");
if (geoms != null) if (geoms != null)
{ {
Geometries = new ResourcePointerArray64<DrawableGeometry>(); Geometries = geoms;
Geometries.data_items = geoms;
foreach (var geom in geoms) foreach (var geom in geoms)
{ {
aabbs.Add(geom.AABB); aabbs.Add(geom.AABB);
@ -2330,26 +2378,35 @@ namespace CodeWalker.GameFiles
} }
public override IResourceBlock[] GetReferences() public override Tuple<long, IResourceBlock>[] GetParts()
{ {
var list = new List<IResourceBlock>(); var parts = new List<Tuple<long, IResourceBlock>>();
if (Geometries != null) list.Add(Geometries); parts.AddRange(base.GetParts());
if (BoundsData != null)
var off = (long)48;
off += (GeometriesCount1 * 2); //ShaderMapping
if (GeometriesCount1 == 1) off += 6;
else off += ((16 - (off % 16)) % 16);
off += (GeometriesCount1 * 8); //Geometries pointers
off += ((16 - (off % 16)) % 16);
off += (GeometriesCount1 + ((GeometriesCount1 > 1) ? 1 : 0)) * 32; //BoundsData
for (int i = 0; i < GeometriesCount1; i++)
{ {
BoundsDataBlock = new ResourceSystemStructBlock<AABB_s>(BoundsData); var geom = (Geometries != null) ? Geometries[i] : null;
list.Add(BoundsDataBlock); if (geom != null)
{
off += ((16 - (off % 16)) % 16);
parts.Add(new Tuple<long, IResourceBlock>(off, geom));
off += geom.BlockLength; //Geometries
} }
if (ShaderMapping != null)
{
ShaderMappingBlock = new ResourceSystemStructBlock<ushort>(ShaderMapping);
list.Add(ShaderMappingBlock);
} }
return list.ToArray();
return parts.ToArray();
} }
public override string ToString() public override string ToString()
{ {
return "(" + Geometries.Count + " geometr" + (Geometries.Count != 1 ? "ies)" : "y)"); return "(" + (Geometries?.Length ?? 0).ToString() + " geometr" + ((Geometries?.Length ?? 0) != 1 ? "ies)" : "y)");
} }
} }
@ -4376,12 +4433,12 @@ namespace CodeWalker.GameFiles
var shaders = shaderGrp.Shaders.data_items; var shaders = shaderGrp.Shaders.data_items;
foreach (DrawableModel model in AllModels) foreach (DrawableModel model in AllModels)
{ {
if (model?.Geometries?.data_items == null) continue; if (model?.Geometries == null) continue;
int geomcount = model.Geometries.data_items.Length; int geomcount = model.Geometries.Length;
for (int i = 0; i < geomcount; i++) for (int i = 0; i < geomcount; i++)
{ {
var geom = model.Geometries.data_items[i]; var geom = model.Geometries[i];
var sid = geom.ShaderID; var sid = geom.ShaderID;
geom.Shader = (sid < shaders.Length) ? shaders[sid] : null; geom.Shader = (sid < shaders.Length) ? shaders[sid] : null;
} }
@ -4414,7 +4471,8 @@ namespace CodeWalker.GameFiles
var vds = new Dictionary<ulong, VertexDeclaration>(); var vds = new Dictionary<ulong, VertexDeclaration>();
foreach (DrawableModel model in AllModels) foreach (DrawableModel model in AllModels)
{ {
foreach (var geom in model.Geometries.data_items) if (model.Geometries == null) continue;
foreach (var geom in model.Geometries)
{ {
var info = geom.VertexBuffer.Info; var info = geom.VertexBuffer.Info;
var declid = info.GetDeclarationId(); var declid = info.GetDeclarationId();

View File

@ -234,6 +234,18 @@ namespace CodeWalker.GameFiles
} }
} }
public T[] ReadBlocks<T>(ulong[] pointers) where T : IResourceBlock, new()
{
if (pointers == null) return null;
var count = pointers.Length;
var items = new T[count];
for (int i = 0; i < count; i++)
{
items[i] = ReadBlockAt<T>(pointers[i]);
}
return items;
}
public byte[] ReadBytesAt(ulong position, uint count, bool cache = true) public byte[] ReadBytesAt(ulong position, uint count, bool cache = true)
{ {
@ -549,6 +561,17 @@ namespace CodeWalker.GameFiles
} }
/// <summary>
/// Write enough bytes to the stream to get to the specified alignment.
/// </summary>
/// <param name="alignment">value to align to</param>
public void WritePadding(int alignment)
{
var pad = ((alignment - (Position % alignment)) % alignment);
if (pad > 0) Write(new byte[pad]);
}
} }

View File

@ -102,8 +102,8 @@ namespace CodeWalker
var bsRad = 0.0f; var bsRad = 0.0f;
foreach (var m in mlistall) foreach (var m in mlistall)
{ {
if (m?.Model?.Geometries?.data_items == null) continue; if (m?.Model?.Geometries == null) continue;
foreach (var g in m.Model.Geometries.data_items) foreach (var g in m.Model.Geometries)
{ {
var vb = g.VertexData.VertexBytes; var vb = g.VertexData.VertexBytes;
var vs = g.VertexData.VertexStride; var vs = g.VertexData.VertexStride;
@ -135,9 +135,9 @@ namespace CodeWalker
var smapp = new List<ushort>(); var smapp = new List<ushort>();
foreach (var m in mlAll) foreach (var m in mlAll)
{ {
if (m?.Geometries?.data_items == null) continue; if (m?.Geometries == null) continue;
smapp.Clear(); smapp.Clear();
foreach (var g in m.Geometries.data_items) foreach (var g in m.Geometries)
{ {
smapp.Add((ushort)slist.Count); smapp.Add((ushort)slist.Count);
slist.Add(g.Shader); slist.Add(g.Shader);
@ -498,8 +498,7 @@ namespace CodeWalker
dModel.VFT = 1080101496;//is this needed? dModel.VFT = 1080101496;//is this needed?
dModel.Unknown_4h = 1; dModel.Unknown_4h = 1;
dModel.RenderMaskFlags = 0x00FF; //GIMS "Mask" dModel.RenderMaskFlags = 0x00FF; //GIMS "Mask"
dModel.Geometries = new ResourcePointerArray64<DrawableGeometry>(); dModel.Geometries = dGeoms.ToArray();
dModel.Geometries.data_items = dGeoms.ToArray();
dModel.GeometriesCount1 = (ushort)dGeoms.Count; dModel.GeometriesCount1 = (ushort)dGeoms.Count;
dModel.GeometriesCount2 = (ushort)dGeoms.Count; dModel.GeometriesCount2 = (ushort)dGeoms.Count;
dModel.GeometriesCount3 = (ushort)dGeoms.Count; dModel.GeometriesCount3 = (ushort)dGeoms.Count;

View File

@ -1100,9 +1100,9 @@ namespace CodeWalker.Forms
Renderer.SelectionModelDrawFlags[model] = false; Renderer.SelectionModelDrawFlags[model] = false;
} }
if ((model.Geometries == null) || (model.Geometries.data_items == null)) continue; if (model.Geometries == null) continue;
foreach (var geom in model.Geometries.data_items) foreach (var geom in model.Geometries)
{ {
var gname = geom.ToString(); var gname = geom.ToString();
var gnode = mnode.Nodes.Add(gname); var gnode = mnode.Nodes.Add(gname);

View File

@ -106,9 +106,9 @@ namespace CodeWalker.Forms
var mnode = tnc.Add(mprefix + " " + model.ToString()); var mnode = tnc.Add(mprefix + " " + model.ToString());
mnode.Tag = model; mnode.Tag = model;
if ((model.Geometries == null) || (model.Geometries.data_items == null)) continue; if (model.Geometries == null) continue;
foreach (var geom in model.Geometries.data_items) foreach (var geom in model.Geometries)
{ {
var gname = geom.ToString(); var gname = geom.ToString();
var gnode = mnode.Nodes.Add(gname); var gnode = mnode.Nodes.Add(gname);
@ -259,8 +259,8 @@ namespace CodeWalker.Forms
{ {
foreach (var model in dwbl.AllModels) foreach (var model in dwbl.AllModels)
{ {
if (model?.Geometries?.data_items == null) continue; if (model?.Geometries == null) continue;
foreach (var geom in model.Geometries.data_items) foreach (var geom in model.Geometries)
{ {
if (geom.Shader == shader) if (geom.Shader == shader)
{ {

View File

@ -545,9 +545,9 @@ namespace CodeWalker
Renderer.SelectionModelDrawFlags[model] = false; Renderer.SelectionModelDrawFlags[model] = false;
} }
if ((model.Geometries == null) || (model.Geometries.data_items == null)) continue; if (model.Geometries == null) continue;
foreach (var geom in model.Geometries.data_items) foreach (var geom in model.Geometries)
{ {
var gname = geom.ToString(); var gname = geom.ToString();
var gnode = mnode.Nodes.Add(gname); var gnode = mnode.Nodes.Add(gname);

View File

@ -763,14 +763,14 @@ namespace CodeWalker.Rendering
BoneIndex = (int)((SkeletonBinding >> 24) & 0xFF); BoneIndex = (int)((SkeletonBinding >> 24) & 0xFF);
DrawableModel = dmodel; DrawableModel = dmodel;
long geomcount = dmodel.Geometries.data_items.Length; long geomcount = dmodel.Geometries.Length;
Geometries = new RenderableGeometry[geomcount]; Geometries = new RenderableGeometry[geomcount];
GeometryBounds = new AABB_s[geomcount]; GeometryBounds = new AABB_s[geomcount];
GeometrySize = 0; GeometrySize = 0;
for (int i = 0; i < geomcount; i++) for (int i = 0; i < geomcount; i++)
{ {
var dgeom = dmodel.Geometries.data_items[i]; var dgeom = dmodel.Geometries[i];
var rgeom = new RenderableGeometry(); var rgeom = new RenderableGeometry();
rgeom.Init(dgeom); rgeom.Init(dgeom);
rgeom.Owner = this; rgeom.Owner = this;

View File

@ -491,9 +491,9 @@ namespace CodeWalker
Renderer.SelectionModelDrawFlags[model] = false; Renderer.SelectionModelDrawFlags[model] = false;
} }
if ((model.Geometries == null) || (model.Geometries.data_items == null)) continue; if (model.Geometries == null) continue;
foreach (var geom in model.Geometries.data_items) foreach (var geom in model.Geometries)
{ {
var gname = geom.ToString(); var gname = geom.ToString();
var gnode = mnode.Nodes.Add(gname); var gnode = mnode.Nodes.Add(gname);

View File

@ -217,9 +217,9 @@ namespace CodeWalker.World
var tmnode = SelDrawableTexturesTreeView.Nodes.Add(mprefix + " " + model.ToString()); var tmnode = SelDrawableTexturesTreeView.Nodes.Add(mprefix + " " + model.ToString());
tmnode.Tag = model; tmnode.Tag = model;
if ((model.Geometries == null) || (model.Geometries.data_items == null)) continue; if (model.Geometries == null) continue;
foreach (var geom in model.Geometries.data_items) foreach (var geom in model.Geometries)
{ {
var gname = geom.ToString(); var gname = geom.ToString();
var gnode = mnode.Nodes.Add(gname); var gnode = mnode.Nodes.Add(gname);

View File

@ -3786,9 +3786,9 @@ namespace CodeWalker
Renderer.SelectionModelDrawFlags[model] = false; Renderer.SelectionModelDrawFlags[model] = false;
} }
if ((model.Geometries == null) || (model.Geometries.data_items == null)) continue; if (model.Geometries == null) continue;
foreach (var geom in model.Geometries.data_items) foreach (var geom in model.Geometries)
{ {
var gname = geom.ToString(); var gname = geom.ToString();
var gnode = mnode.Nodes.Add(gname); var gnode = mnode.Nodes.Add(gname);