Ped clothes not exploding

This commit is contained in:
dexy 2019-11-29 20:47:11 +11:00
parent 181689ac95
commit ef1debfb41
30 changed files with 482 additions and 1507 deletions

View File

@ -12,6 +12,9 @@ namespace CodeWalker.GameFiles
{
public ClothDictionary ClothDictionary { get; set; }
public Dictionary<uint, CharacterCloth> Dict { get; set; }
public string LoadException { get; set; }
@ -48,6 +51,23 @@ namespace CodeWalker.GameFiles
ClothDictionary = rd?.ReadBlock<ClothDictionary>();
if (ClothDictionary != null)
{
Dict = new Dictionary<uint, CharacterCloth>();
int n = ClothDictionary.ClothNameHashes?.data_items?.Length ?? 0;
for (int i = 0; i < n; i++)
{
if (i >= (ClothDictionary.Clothes?.data_items?.Length ?? 0)) break;
var hash = ClothDictionary.ClothNameHashes.data_items[i];
var cloth = ClothDictionary.Clothes.data_items[i];
Dict[hash] = cloth;
}
}
Loaded = true;
}
}
}

View File

@ -84,6 +84,7 @@ namespace CodeWalker.GameFiles
public Dictionary<MetaHash, PedFile> PedVariationsDict { get; set; }
public Dictionary<MetaHash, Dictionary<MetaHash, RpfFileEntry>> PedDrawableDicts { get; set; }
public Dictionary<MetaHash, Dictionary<MetaHash, RpfFileEntry>> PedTextureDicts { get; set; }
public Dictionary<MetaHash, Dictionary<MetaHash, RpfFileEntry>> PedClothDicts { get; set; }
public List<RpfFile> BaseRpfs { get; private set; }
public List<RpfFile> AllRpfs { get; private set; }
@ -182,6 +183,7 @@ namespace CodeWalker.GameFiles
//TestMetas();
//TestPsos();
//TestCuts();
//TestYlds();
//TestYcds();
//TestYtds();
//TestYbns();
@ -1639,10 +1641,36 @@ namespace CodeWalker.GameFiles
var allPedYmts = new Dictionary<MetaHash, PedFile>();
var allPedDrwDicts = new Dictionary<MetaHash, Dictionary<MetaHash, RpfFileEntry>>();
var allPedTexDicts = new Dictionary<MetaHash, Dictionary<MetaHash, RpfFileEntry>>();
var allPedClothDicts = new Dictionary<MetaHash, Dictionary<MetaHash, RpfFileEntry>>();
Dictionary<MetaHash, RpfFileEntry> ensureDict(Dictionary<MetaHash, Dictionary<MetaHash, RpfFileEntry>> coll, MetaHash hash)
{
Dictionary<MetaHash, RpfFileEntry> dict;
if (!coll.TryGetValue(hash, out dict))
{
dict = new Dictionary<MetaHash, RpfFileEntry>();
coll[hash] = dict;
}
return dict;
}
var addPedDicts = new Action<string, MetaHash, RpfDirectoryEntry>((namel, hash, dir)=>
{
Dictionary<MetaHash, RpfFileEntry> dict = null;
var files = dir?.Files;
if (files != null)
{
foreach (var file in files)
{
if (file.NameLower == namel + ".yld")
{
dict = ensureDict(allPedClothDicts, hash);
dict[file.ShortNameHash] = file;
}
}
}
if (dir?.Directories != null)
{
foreach (var cdir in dir.Directories)
@ -1653,29 +1681,25 @@ namespace CodeWalker.GameFiles
break;
}
}
var files = dir?.Files;
files = dir?.Files;
if (files != null)
{
Dictionary<MetaHash, RpfFileEntry> dict = null;
foreach (var file in files)
{
if (file?.NameLower == null) continue;
if (file.NameLower.EndsWith(".ydd"))
{
if (!allPedDrwDicts.TryGetValue(hash, out dict))
{
dict = new Dictionary<MetaHash, RpfFileEntry>();
allPedDrwDicts[hash] = dict;
}
dict = ensureDict(allPedDrwDicts, hash);
dict[file.ShortNameHash] = file;
}
else if (file.NameLower.EndsWith(".ytd"))
{
if (!allPedTexDicts.TryGetValue(hash, out dict))
{
dict = new Dictionary<MetaHash, RpfFileEntry>();
allPedTexDicts[hash] = dict;
}
dict = ensureDict(allPedTexDicts, hash);
dict[file.ShortNameHash] = file;
}
else if (file.NameLower.EndsWith(".yld"))
{
dict = ensureDict(allPedClothDicts, hash);
dict[file.ShortNameHash] = file;
}
}
@ -1773,6 +1797,7 @@ namespace CodeWalker.GameFiles
PedVariationsDict = allPedYmts;
PedDrawableDicts = allPedDrwDicts;
PedTextureDicts = allPedTexDicts;
PedClothDicts = allPedClothDicts;
foreach (var kvp in PedsInitDict)
@ -2287,6 +2312,9 @@ namespace CodeWalker.GameFiles
case GameFileType.Ynv:
req.Loaded = LoadFile(req as YnvFile);
break;
case GameFileType.Yld:
req.Loaded = LoadFile(req as YldFile);
break;
default:
break;
}
@ -3014,6 +3042,44 @@ namespace CodeWalker.GameFiles
{
}
}
public void TestYlds()
{
var exceptions = new List<Exception>();
foreach (RpfFile file in AllRpfs)
{
foreach (RpfEntry entry in file.AllEntries)
{
#if !DEBUG
try
#endif
{
var rfe = entry as RpfFileEntry;
if (rfe == null) continue;
if (rfe.NameLower.EndsWith(".yld"))
{
UpdateStatus(string.Format(entry.Path));
YldFile yld = new YldFile(rfe);
RpfMan.LoadFile(yld, rfe);
}
}
#if !DEBUG
catch (Exception ex)
{
UpdateStatus("Error! " + ex.ToString());
exceptions.Add(ex);
}
#endif
}
}
if (exceptions.Count > 0)
{ }
}
public void TestYcds()
{
var errorfiles = new List<YcdFile>();
@ -3621,6 +3687,8 @@ namespace CodeWalker.GameFiles
}
public void TestYfts()
{
bool savetest = true;
var errorfiles = new List<RpfEntry>();
foreach (RpfFile file in AllRpfs)
{
@ -3647,6 +3715,8 @@ namespace CodeWalker.GameFiles
if (fentry == null)
{ continue; } //shouldn't happen
if (!savetest) continue;
var bytes = yft.Save();

View File

@ -525,8 +525,8 @@ namespace CodeWalker.GameFiles
public uint Unknown_F4h { get; set; } // 0x00000000
public uint Unknown_F8h { get; set; }
public uint Unknown_FCh { get; set; } // 0x00000000
public ResourceSimpleList64<Unknown_C_004> Unknown_100h { get; set; }
public ResourceSimpleList64<Unknown_C_004> Unknown_110h { get; set; }
public ResourceSimpleList64_s<Unknown_C_004> Unknown_100h { get; set; }
public ResourceSimpleList64_s<Unknown_C_004> Unknown_110h { get; set; }
public uint Unknown_120h { get; set; } // 0x00000000
public uint Unknown_124h { get; set; } // 0x00000000
public uint Unknown_128h { get; set; } // 0x00000000
@ -619,8 +619,8 @@ namespace CodeWalker.GameFiles
this.Unknown_F4h = reader.ReadUInt32();
this.Unknown_F8h = reader.ReadUInt32();
this.Unknown_FCh = reader.ReadUInt32();
this.Unknown_100h = reader.ReadBlock<ResourceSimpleList64<Unknown_C_004>>();
this.Unknown_110h = reader.ReadBlock<ResourceSimpleList64<Unknown_C_004>>();
this.Unknown_100h = reader.ReadBlock<ResourceSimpleList64_s<Unknown_C_004>>();
this.Unknown_110h = reader.ReadBlock<ResourceSimpleList64_s<Unknown_C_004>>();
this.Unknown_120h = reader.ReadUInt32();
this.Unknown_124h = reader.ReadUInt32();
this.Unknown_128h = reader.ReadUInt32();
@ -654,7 +654,17 @@ namespace CodeWalker.GameFiles
);
this.Unknown_140h_Data = reader.ReadBlockAt<Unknown_C_007>(
this.Unknown_140h_Pointer // offset
);
);
if (Unknown_70h?.data_items?.Length > 0)
{ }
if (Unknown_80h?.data_items?.Length > 0)
{ }
if (Unknown_100h?.data_items?.Length > 0)
{ }
if (Unknown_110h?.data_items?.Length > 0)
{ }
}
/// <summary>
@ -881,9 +891,9 @@ namespace CodeWalker.GameFiles
public uint Unknown_54h { get; set; } // 0x00000000
public uint Unknown_58h { get; set; } // 0x00000000
public uint Unknown_5Ch { get; set; } // 0x00000000
public ulong pxxxxx_2 { get; set; }
public ushort cntxx51a { get; set; }
public ushort cntxx51b { get; set; }
public ulong UnknownPointer { get; set; }
public ushort UnknownCount1 { get; set; }
public ushort UnknownCount2 { get; set; }
public uint Unknown_6Ch { get; set; } // 0x00000000
public uint Unknown_70h { get; set; } // 0x00000000
public uint Unknown_74h { get; set; } // 0x00000000
@ -894,7 +904,9 @@ namespace CodeWalker.GameFiles
public ClothInstanceTuning InstanceTuning { get; set; }
public FragDrawable Drawable { get; set; }
public ClothController Controller { get; set; }
public ResourceSimpleArray<uint_r> pxxxxx_2data { get; set; }
public uint[] UnknownData { get; set; }
private ResourceSystemStructBlock<uint> UnknownDataBlock = null;
/// <summary>
/// Reads the data-block from a stream.
@ -923,9 +935,9 @@ namespace CodeWalker.GameFiles
this.Unknown_54h = reader.ReadUInt32();
this.Unknown_58h = reader.ReadUInt32();
this.Unknown_5Ch = reader.ReadUInt32();
this.pxxxxx_2 = reader.ReadUInt64();
this.cntxx51a = reader.ReadUInt16();
this.cntxx51b = reader.ReadUInt16();
this.UnknownPointer = reader.ReadUInt64();
this.UnknownCount1 = reader.ReadUInt16();
this.UnknownCount2 = reader.ReadUInt16();
this.Unknown_6Ch = reader.ReadUInt32();
this.Unknown_70h = reader.ReadUInt32();
this.Unknown_74h = reader.ReadUInt32();
@ -942,10 +954,13 @@ namespace CodeWalker.GameFiles
this.Controller = reader.ReadBlockAt<ClothController>(
this.ControllerPointer // offset
);
this.pxxxxx_2data = reader.ReadBlockAt<ResourceSimpleArray<uint_r>>(
this.pxxxxx_2, // offset
this.cntxx51a
);
this.UnknownData = reader.ReadUintsAt(this.UnknownPointer, this.UnknownCount1);
if (this.Drawable != null)
{
this.Drawable.OwnerCloth = this;
}
}
/// <summary>
@ -957,9 +972,9 @@ namespace CodeWalker.GameFiles
this.InstanceTuningPointer = (ulong)(this.InstanceTuning != null ? this.InstanceTuning.FilePosition : 0);
this.DrawablePointer = (ulong)(this.Drawable != null ? this.Drawable.FilePosition : 0);
this.ControllerPointer = (ulong)(this.Controller != null ? this.Controller.FilePosition : 0);
this.pxxxxx_2 = (ulong)(this.pxxxxx_2data != null ? this.pxxxxx_2data.FilePosition : 0);
this.cntxx51a = (ushort)(this.pxxxxx_2data != null ? this.pxxxxx_2data.Count : 0);
this.cntxx51b = (ushort)(this.pxxxxx_2data != null ? this.pxxxxx_2data.Count : 0);
this.UnknownPointer = (ulong)(this.UnknownDataBlock != null ? this.UnknownDataBlock.FilePosition : 0);
this.UnknownCount1 = (ushort)(this.UnknownDataBlock != null ? this.UnknownDataBlock.ItemCount : 0);
this.UnknownCount2 = this.UnknownCount1;
// write structure data
writer.Write(this.VFT);
@ -983,9 +998,9 @@ namespace CodeWalker.GameFiles
writer.Write(this.Unknown_54h);
writer.Write(this.Unknown_58h);
writer.Write(this.Unknown_5Ch);
writer.Write(this.pxxxxx_2);
writer.Write(this.cntxx51a);
writer.Write(this.cntxx51b);
writer.Write(this.UnknownPointer);
writer.Write(this.UnknownCount1);
writer.Write(this.UnknownCount2);
writer.Write(this.Unknown_6Ch);
writer.Write(this.Unknown_70h);
writer.Write(this.Unknown_74h);
@ -1002,7 +1017,11 @@ namespace CodeWalker.GameFiles
if (InstanceTuning != null) list.Add(InstanceTuning);
if (Drawable != null) list.Add(Drawable);
if (Controller != null) list.Add(Controller);
if (pxxxxx_2data != null) list.Add(pxxxxx_2data);
if (UnknownData != null)
{
UnknownDataBlock = new ResourceSystemStructBlock<uint>(UnknownData);
list.Add(UnknownDataBlock);
}
return list.ToArray();
}
}
@ -1020,7 +1039,7 @@ namespace CodeWalker.GameFiles
public uint Unknown_4h { get; set; } // 0x00000001
public uint Unknown_8h { get; set; } // 0x00000000
public uint Unknown_Ch { get; set; } // 0x00000000
public ResourceSimpleList64<Unknown_C_001> Unknown_10h { get; set; }
public ResourceSimpleList64_s<Vector4> Unknown_10h { get; set; }
public ulong ControllerPointer { get; set; }
public ulong BoundPointer { get; set; }
public ResourceSimpleList64_uint Unknown_30h { get; set; }
@ -1057,7 +1076,7 @@ namespace CodeWalker.GameFiles
this.Unknown_4h = reader.ReadUInt32();
this.Unknown_8h = reader.ReadUInt32();
this.Unknown_Ch = reader.ReadUInt32();
this.Unknown_10h = reader.ReadBlock<ResourceSimpleList64<Unknown_C_001>>();
this.Unknown_10h = reader.ReadBlock<ResourceSimpleList64_s<Vector4>>();
this.ControllerPointer = reader.ReadUInt64();
this.BoundPointer = reader.ReadUInt64();
this.Unknown_30h = reader.ReadBlock<ResourceSimpleList64_uint>();
@ -1087,6 +1106,7 @@ namespace CodeWalker.GameFiles
this.Bound = reader.ReadBlockAt<Bounds>(
this.BoundPointer // offset
);
}
/// <summary>
@ -1167,7 +1187,7 @@ namespace CodeWalker.GameFiles
public uint Unknown_D4h { get; set; } // 0x00000000
public uint Unknown_D8h { get; set; } // 0x00000000
public float Unknown_DCh { get; set; } // 0x3F800000 = 1.0f
public ResourceSimpleList64_uint Unknown_E0h { get; set; }
public ResourceSimpleList64_uint BoneIds { get; set; }
/// <summary>
/// Reads the data-block from a stream.
@ -1189,7 +1209,7 @@ namespace CodeWalker.GameFiles
this.Unknown_D4h = reader.ReadUInt32();
this.Unknown_D8h = reader.ReadUInt32();
this.Unknown_DCh = reader.ReadSingle();
this.Unknown_E0h = reader.ReadBlock<ResourceSimpleList64_uint>();
this.BoneIds = reader.ReadBlock<ResourceSimpleList64_uint>();
}
/// <summary>
@ -1212,7 +1232,7 @@ namespace CodeWalker.GameFiles
writer.Write(this.Unknown_D4h);
writer.Write(this.Unknown_D8h);
writer.Write(this.Unknown_DCh);
writer.WriteBlock(this.Unknown_E0h);
writer.WriteBlock(this.BoneIds);
}
public override Tuple<long, IResourceBlock>[] GetParts()
@ -1222,7 +1242,7 @@ namespace CodeWalker.GameFiles
new Tuple<long, IResourceBlock>(0x90, Vertices),
new Tuple<long, IResourceBlock>(0xB0, Unknown_B0h),
new Tuple<long, IResourceBlock>(0xC0, Unknown_C0h),
new Tuple<long, IResourceBlock>(0xE0, Unknown_E0h)
new Tuple<long, IResourceBlock>(0xE0, BoneIds)
};
}
}
@ -1326,48 +1346,6 @@ namespace CodeWalker.GameFiles
}
[TypeConverter(typeof(ExpandableObjectConverter))] public class Unknown_C_001 : ResourceSystemBlock
{
public override long BlockLength => 0x10;
// structure data
public uint Unknown_0h { get; set; }
public uint Unknown_4h { get; set; }
public uint Unknown_8h { get; set; }
public uint Unknown_Ch { get; set; }
/// <summary>
/// Reads the data-block from a stream.
/// </summary>
public override void Read(ResourceDataReader reader, params object[] parameters)
{
// read structure data
this.Unknown_0h = reader.ReadUInt32();
this.Unknown_4h = reader.ReadUInt32();
this.Unknown_8h = reader.ReadUInt32();
this.Unknown_Ch = reader.ReadUInt32();
}
/// <summary>
/// Writes the data-block to a stream.
/// </summary>
public override void Write(ResourceDataWriter writer, params object[] parameters)
{
// write structure data
writer.Write(this.Unknown_0h);
writer.Write(this.Unknown_4h);
writer.Write(this.Unknown_8h);
writer.Write(this.Unknown_Ch);
}
public override string ToString()
{
return Unknown_0h.ToString() + ", " + Unknown_4h.ToString() + ", " + Unknown_8h.ToString() + ", " + Unknown_Ch.ToString();
}
}
[TypeConverter(typeof(ExpandableObjectConverter))] public struct Unknown_C_003
{
public Vector4 Unknown0 { get; set; }
@ -1380,43 +1358,14 @@ namespace CodeWalker.GameFiles
}
[TypeConverter(typeof(ExpandableObjectConverter))] public class Unknown_C_004 : ResourceSystemBlock
[TypeConverter(typeof(ExpandableObjectConverter))] public struct Unknown_C_004
{
public override long BlockLength => 0x10;
// structure data
public ushort Unknown_0h { get; set; }
public ushort Unknown_2h { get; set; }
public float Unknown_4h { get; set; }
public float Unknown_8h { get; set; }
public float Unknown_Ch { get; set; }
/// <summary>
/// Reads the data-block from a stream.
/// </summary>
public override void Read(ResourceDataReader reader, params object[] parameters)
{
// read structure data
this.Unknown_0h = reader.ReadUInt16();
this.Unknown_2h = reader.ReadUInt16();
this.Unknown_4h = reader.ReadSingle();
this.Unknown_8h = reader.ReadSingle();
this.Unknown_Ch = reader.ReadSingle();
}
/// <summary>
/// Writes the data-block to a stream.
/// </summary>
public override void Write(ResourceDataWriter writer, params object[] parameters)
{
// write structure data
writer.Write(this.Unknown_0h);
writer.Write(this.Unknown_2h);
writer.Write(this.Unknown_4h);
writer.Write(this.Unknown_8h);
writer.Write(this.Unknown_Ch);
}
public override string ToString()
{
return Unknown_0h.ToString() + ", " + Unknown_2h.ToString() + ", " + Unknown_4h.ToString() + ", " + Unknown_8h.ToString() + ", " + Unknown_Ch.ToString();
@ -1704,4 +1653,151 @@ namespace CodeWalker.GameFiles
public class ClothInstance
{
public CharacterCloth CharCloth { get; set; }
public EnvironmentCloth EnvCloth { get; set; }
public ClothController Controller { get; set; }
public Matrix Transform { get; set; } = Matrix.Identity;
public Vector4[] Vertices { get; set; }
public Skeleton Skeleton { get; set; }
double CurrentTime = 0.0;
public void Init(CharacterCloth c, Skeleton s)
{
CharCloth = c;
Skeleton = s;
Init(c?.Controller);
var cc = c.Controller;
var verts = cc?.Vertices?.data_items;
if (verts != null)
{
if (verts.Length == Vertices?.Length)
{
for (int i = 0; i < verts.Length; i++)
{
Vertices[i] = verts[i];
}
}
else
{ }
}
var t = c.Transform;
t.M44 = 1.0f;
Transform = t;
}
public void Init(EnvironmentCloth c, Skeleton s)
{
EnvCloth = c;
Skeleton = s;
Init(c?.Controller);
}
private void Init(ClothController cc)
{
Controller = cc;
var bg = cc?.BridgeSimGfx;
var vc = bg?.VertexCount ?? 0;
if (vc > 0)
{
Vertices = new Vector4[vc];
var unk02 = bg.Unknown_20h?.data_items;//float //// ??
var unk03 = bg.Unknown_30h?.data_items;//float
var unk04 = bg.Unknown_40h?.data_items;//float
var unk06 = bg.Unknown_60h?.data_items;//float ////// cloth thickness?
var unk07 = bg.Unknown_70h?.data_items;//uint
var unk08 = bg.Unknown_80h?.data_items;//uint
var unk0A = bg.Unknown_A0h?.data_items;//float //// ??
var unk0B = bg.Unknown_B0h?.data_items;//uint
var unk0C = bg.Unknown_C0h?.data_items;//uint
var unk0E = bg.Unknown_E0h?.data_items;//ushort //some sort of indexes? nearest neighbour?
var unk0F = bg.Unknown_F0h?.data_items;//ushort
var unk10 = bg.Unknown_100h?.data_items;//ushort
//var unk12 = bg.Unknown_128h?.data_items;//uint
}
}
public void Update(double t)
{
if (Vertices == null) return;
if (CurrentTime == t) return;
var elapsed = (t - CurrentTime);
CurrentTime = t;
var charCont = CharCloth?.Controller;
if (charCont != null)
{
var cv = charCont?.Vertices?.data_items;
if (Vertices.Length != cv?.Length)
{ return; }
var boneIds = charCont.BoneIds?.data_items;
if (boneIds == null)
{ return; }
for (int i = 0; i < boneIds.Length; i++)
{
var boneid = (ushort)boneIds[i];
Bone bone = null;
Skeleton.BonesMap.TryGetValue(boneid, out bone);
if (bone == null)
{ continue; }
var xform = bone.SkinTransform;
for (int v = 0; v < Vertices.Length; v++)
{
var nv = xform.MultiplyW(cv[v].XYZ());
Vertices[v] = new Vector4(nv, 0);
}
break;//hackity yak
}
if (boneIds.Length > 1)
{ }
}
}
}
}

View File

@ -2678,7 +2678,6 @@ namespace CodeWalker.GameFiles
f.FragMatrices = fd.FragMatrices;
f.Name = fd.Name;
f.OwnerFragment = fd.OwnerFragment;
f.OwnerFragmentCloth = fd.OwnerFragmentCloth;
f.OwnerFragmentPhys = fd.OwnerFragmentPhys;
r = f;
}

File diff suppressed because it is too large Load Diff

View File

@ -17,17 +17,21 @@ namespace CodeWalker.World
public CPedModelInfo__InitData InitData { get; set; } = null; //ped init data
public YddFile Ydd { get; set; } = null; //ped drawables
public YtdFile Ytd { get; set; } = null; //ped textures
public YldFile Yld { get; set; } = null; //ped clothes
public YcdFile Ycd { get; set; } = null; //ped animations
public YftFile Yft { get; set; } = null; //ped skeleton YFT
public PedFile Ymt { get; set; } = null; //ped variation info
public Dictionary<MetaHash, RpfFileEntry> DrawableFilesDict { get; set; } = null;
public Dictionary<MetaHash, RpfFileEntry> TextureFilesDict { get; set; } = null;
public Dictionary<MetaHash, RpfFileEntry> ClothFilesDict { get; set; } = null;
public RpfFileEntry[] DrawableFiles { get; set; } = null;
public RpfFileEntry[] TextureFiles { get; set; } = null;
public RpfFileEntry[] ClothFiles { get; set; } = null;
public ClipMapEntry AnimClip { get; set; } = null;
public string[] DrawableNames { get; set; } = new string[12];
public Drawable[] Drawables { get; set; } = new Drawable[12];
public Texture[] Textures { get; set; } = new Texture[12];
public ClothInstance[] Clothes { get; set; } = new ClothInstance[12];
public bool EnableRootMotion { get; set; } = false; //used to toggle whether or not to include root motion when playing animations
public Skeleton Skeleton { get; set; } = null;
@ -87,6 +91,21 @@ namespace CodeWalker.World
gfc.PedTextureDicts.TryGetValue(NameHash, out peddict);
TextureFilesDict = peddict;
TextureFiles = TextureFilesDict?.Values.ToArray();
gfc.PedClothDicts.TryGetValue(NameHash, out peddict);
ClothFilesDict = peddict;
ClothFiles = ClothFilesDict?.Values.ToArray();
RpfFileEntry clothFile = null;
if (ClothFilesDict?.TryGetValue(pedhash, out clothFile) ?? false)
{
Yld = gfc.GetFileUncached<YldFile>(clothFile);
while ((Yld != null) && (!Yld.Loaded))
{
Thread.Sleep(20);//kinda hacky
gfc.TryLoadEnqueue(Yld);
}
}
while ((Ydd != null) && (!Ydd.Loaded))
@ -184,9 +203,39 @@ namespace CodeWalker.World
}
}
CharacterCloth cc = null;
if (Yld?.Dict != null)
{
Yld.Dict.TryGetValue(namehash, out cc);
}
if ((cc == null) && (ClothFilesDict != null))
{
RpfFileEntry file = null;
if (ClothFilesDict.TryGetValue(namehash, out file))
{
var yld = gfc.GetFileUncached<YldFile>(file);
while ((yld != null) && (!yld.Loaded))
{
Thread.Sleep(20);//kinda hacky
gfc.TryLoadEnqueue(yld);
}
if (yld?.ClothDictionary?.Clothes?.data_items?.Length > 0)
{
cc = yld.ClothDictionary.Clothes.data_items[0];//should only be one in this dict
}
}
}
ClothInstance c = null;
if (cc != null)
{
c = new ClothInstance();
c.Init(cc, Skeleton);
}
if (d != null) Drawables[index] = d.ShallowCopy() as Drawable;
if (t != null) Textures[index] = t;
if (c != null) Clothes[index] = c;
DrawableNames[index] = name;
}

View File

@ -60,6 +60,10 @@ cbuffer BoneMatrices : register(b7) //rage_bonemtx
{
row_major float3x4 gBoneMtx[255]; // Offset: 0 Size: 12240
}
cbuffer ClothVertices : register(b8) //pedcloth
{
float4 clothVertices[254]; // Offset: 64 Size: 4060
}
struct VS_OUTPUT
{
@ -257,34 +261,44 @@ float3 GetGrassInstancePosition(float3 ipos, float3 vc0, float3 vc1, uint iid)
}
float3x4 BoneMatrix(float4 weights, float4 indices)
void BoneTransform(float4 weights, float4 indices, float3 ipos, float3 inorm, float3 itang, out float3 opos, out float3 onorm, out float3 otang)
{
uint4 binds = (uint4)(indices * 255.001953);
float3x4 b0 = gBoneMtx[binds.x];
float3x4 b1 = gBoneMtx[binds.y];
float3x4 b2 = gBoneMtx[binds.z];
float3x4 b3 = gBoneMtx[binds.w];
float4 t0 = b0[0]*weights.x + b1[0]*weights.y + b2[0]*weights.z + b3[0]*weights.w;
float4 t1 = b0[1]*weights.x + b1[1]*weights.y + b2[1]*weights.z + b3[1]*weights.w;
float4 t2 = b0[2]*weights.x + b1[2]*weights.y + b2[2]*weights.z + b3[2]*weights.w;
return float3x4(t0, t1, t2);
}
float3 BoneTransform(float3 ipos, float3x4 m)
{
float3 r;
float4 p = float4(ipos, 1);
r.x = dot(m[0], p);
r.y = dot(m[1], p);
r.z = dot(m[2], p);
return r;
}
float3 BoneTransformNormal(float3 inorm, float3x4 m)
{
float3 r;
r.x = dot(m[0].xyz, inorm);
r.y = dot(m[1].xyz, inorm);
r.z = dot(m[2].xyz, inorm);
return r;
if (binds.z > 254) //this is the signal to use clothVertices!
{
float4 cv0 = clothVertices[binds.w];
float4 cv1 = clothVertices[binds.x];
float4 cv2 = clothVertices[binds.y];
float3 r0 = cv0.zxy - cv1.zxy;
float3 r8 = cv2.yzx - cv1.yzx;
float3 r4 = normalize((r0.zxy * r8.yzx) - (r0.xyz * r8.xyz));
float3 r5 = (cv2.xyz*weights.x) + (cv1.xyz*weights.y) + (cv0.xyz*weights.z);
float r0w = (weights.w - 0.5) * 0.1;
r5 = (r0w * -r4) + r5;
opos = r5;
onorm = r4;
float3 r7 = r4.yzx * itang.zxy;//itang? transformed by bone?? weird
float3 r9 = r4.zxy * itang.yzx;
otang = (r9 - r7);
}
else
{
float3x4 b0 = gBoneMtx[binds.x];
float3x4 b1 = gBoneMtx[binds.y];
float3x4 b2 = gBoneMtx[binds.z];
float3x4 b3 = gBoneMtx[binds.w];
float4 t0 = b0[0]*weights.x + b1[0]*weights.y + b2[0]*weights.z + b3[0]*weights.w;
float4 t1 = b0[1]*weights.x + b1[1]*weights.y + b2[1]*weights.z + b3[1]*weights.w;
float4 t2 = b0[2]*weights.x + b1[2]*weights.y + b2[2]*weights.z + b3[2]*weights.w;
float3x4 m = float3x4(t0, t1, t2);
float4 p = float4(ipos, 1);
opos = float3(dot(m[0], p), dot(m[1], p), dot(m[2], p));
onorm = float3(dot(m[0].xyz, inorm), dot(m[1].xyz, inorm), dot(m[2].xyz, inorm));
otang = float3(dot(m[0].xyz, itang), dot(m[1].xyz, itang), dot(m[2].xyz, itang));
}
}
float3 ModelTransform(float3 ipos, float3 vc0, float3 vc1, uint iid)
{

View File

@ -15,11 +15,10 @@ struct VS_INPUT
VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
{
VS_OUTPUT output;
float3x4 bone = BoneMatrix(input.BlendWeights, input.BlendIndices);
float3 bpos = BoneTransform(input.Position.xyz, bone);
float3 bpos, bnorm, btang;
BoneTransform(input.BlendWeights, input.BlendIndices, input.Position.xyz, input.Normal, float3(0, 1, 0), bpos, bnorm, btang);
float3 opos = ModelTransform(bpos, input.Colour0.xyz, input.Colour1.xyz, iid);
float4 cpos = ScreenTransform(opos);
float3 bnorm = BoneTransformNormal(input.Normal, bone);
float3 onorm = NormalTransform(bnorm);
float3 otang = 0.5; // NormalTransform(float3(1, 0, 0)); //no tangent to use on this vertex type...

View File

@ -17,12 +17,10 @@ struct VS_INPUT
VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
{
VS_OUTPUT output;
float3x4 bone = BoneMatrix(input.BlendWeights, input.BlendIndices);
float3 bpos = BoneTransform(input.Position.xyz, bone);
float3 bpos, bnorm, btang;
BoneTransform(input.BlendWeights, input.BlendIndices, input.Position.xyz, input.Normal, input.Tangent.xyz, bpos, bnorm, btang);
float3 opos = ModelTransform(bpos, input.Colour0.xyz, input.Colour1.xyz, iid);
float4 cpos = ScreenTransform(opos);
float3 bnorm = BoneTransformNormal(input.Normal.xyz, bone);
float3 btang = BoneTransformNormal(input.Tangent.xyz, bone);
float3 onorm = NormalTransform(bnorm);
float3 otang = NormalTransform(btang);

View File

@ -16,12 +16,10 @@ struct VS_INPUT
VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
{
VS_OUTPUT output;
float3x4 bone = BoneMatrix(input.BlendWeights, input.BlendIndices);
float3 bpos = BoneTransform(input.Position.xyz, bone);
float3 bpos, bnorm, btang;
BoneTransform(input.BlendWeights, input.BlendIndices, input.Position.xyz, input.Normal, input.Tangent.xyz, bpos, bnorm, btang);
float3 opos = ModelTransform(bpos, input.Colour0.xyz, input.Colour1.xyz, iid);
float4 cpos = ScreenTransform(opos);
float3 bnorm = BoneTransformNormal(input.Normal.xyz, bone);
float3 btang = BoneTransformNormal(input.Tangent.xyz, bone);
float3 onorm = NormalTransform(bnorm);
float3 otang = NormalTransform(btang);

View File

@ -14,11 +14,10 @@ struct VS_INPUT
VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
{
VS_OUTPUT output;
float3x4 bone = BoneMatrix(input.BlendWeights, input.BlendIndices);
float3 bpos = BoneTransform(input.Position.xyz, bone);
float3 bpos, bnorm, btang;
BoneTransform(input.BlendWeights, input.BlendIndices, input.Position.xyz, input.Normal, float3(0, 1, 0), bpos, bnorm, btang);
float3 opos = ModelTransform(bpos, input.Colour0.xyz, input.Colour0.xyz, iid);
float4 cpos = ScreenTransform(opos);
float3 bnorm = BoneTransformNormal(input.Normal, bone);
float3 onorm = NormalTransform(bnorm);
float3 otang = 0.5; // NormalTransform(float3(1, 0, 0)); //no tangent to use on this vertex type...

View File

@ -15,11 +15,10 @@ struct VS_INPUT
VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
{
VS_OUTPUT output;
float3x4 bone = BoneMatrix(input.BlendWeights, input.BlendIndices);
float3 bpos = BoneTransform(input.Position.xyz, bone);
float3 bpos, bnorm, btang;
BoneTransform(input.BlendWeights, input.BlendIndices, input.Position.xyz, input.Normal, float3(0, 1, 0), bpos, bnorm, btang);
float3 opos = ModelTransform(bpos, input.Colour0.xyz, input.Colour0.xyz, iid);
float4 cpos = ScreenTransform(opos);
float3 bnorm = BoneTransformNormal(input.Normal, bone);
float3 onorm = NormalTransform(bnorm);
float3 otang = 0.5; // NormalTransform(float3(1, 0, 0)); //no tangent to use on this vertex type...

View File

@ -16,11 +16,10 @@ struct VS_INPUT
VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
{
VS_OUTPUT output;
float3x4 bone = BoneMatrix(input.BlendWeights, input.BlendIndices);
float3 bpos = BoneTransform(input.Position.xyz, bone);
float3 bpos, bnorm, btang;
BoneTransform(input.BlendWeights, input.BlendIndices, input.Position.xyz, input.Normal, float3(0, 1, 0), bpos, bnorm, btang);
float3 opos = ModelTransform(bpos, input.Colour0.xyz, input.Colour0.xyz, iid);
float4 cpos = ScreenTransform(opos);
float3 bnorm = BoneTransformNormal(input.Normal, bone);
float3 onorm = NormalTransform(bnorm);
float3 otang = 0.5; // NormalTransform(float3(1, 0, 0)); //no tangent to use on this vertex type...

View File

@ -16,12 +16,10 @@ struct VS_INPUT
VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
{
VS_OUTPUT output;
float3x4 bone = BoneMatrix(input.BlendWeights, input.BlendIndices);
float3 bpos = BoneTransform(input.Position.xyz, bone);
float3 bpos, bnorm, btang;
BoneTransform(input.BlendWeights, input.BlendIndices, input.Position.xyz, input.Normal, input.Tangent.xyz, bpos, bnorm, btang);
float3 opos = ModelTransform(bpos, input.Colour0.xyz, input.Colour0.xyz, iid);
float4 cpos = ScreenTransform(opos);
float3 bnorm = BoneTransformNormal(input.Normal.xyz, bone);
float3 btang = BoneTransformNormal(input.Tangent.xyz, bone);
float3 onorm = NormalTransform(bnorm);
float3 otang = NormalTransform(btang);

View File

@ -15,12 +15,10 @@ struct VS_INPUT
VS_OUTPUT main(VS_INPUT input, uint iid : SV_InstanceID)
{
VS_OUTPUT output;
float3x4 bone = BoneMatrix(input.BlendWeights, input.BlendIndices);
float3 bpos = BoneTransform(input.Position.xyz, bone);
float3 bpos, bnorm, btang;
BoneTransform(input.BlendWeights, input.BlendIndices, input.Position.xyz, input.Normal, input.Tangent.xyz, bpos, bnorm, btang);
float3 opos = ModelTransform(bpos, input.Colour0.xyz, input.Colour0.xyz, iid);
float4 cpos = ScreenTransform(opos);
float3 bnorm = BoneTransformNormal(input.Normal.xyz, bone);
float3 btang = BoneTransformNormal(input.Tangent.xyz, bone);
float3 onorm = NormalTransform(bnorm);
float3 otang = NormalTransform(btang);

View File

@ -34,6 +34,10 @@ cbuffer BoneMatrices : register(b7) //rage_bonemtx
{
row_major float3x4 gBoneMtx[255]; // Offset: 0 Size: 12240
}
cbuffer ClothVertices : register(b8) //pedcloth
{
float4 clothVertices[254]; // Offset: 64 Size: 4060
}
struct VS_INPUT
{
@ -59,26 +63,35 @@ struct VS_OUTPUT
float3x4 BoneMatrix(float4 weights, float4 indices)
void BoneTransform(float4 weights, float4 indices, float3 ipos, out float3 opos)
{
uint4 binds = (uint4) (indices * 255.001953);
float3x4 b0 = gBoneMtx[binds.x];
float3x4 b1 = gBoneMtx[binds.y];
float3x4 b2 = gBoneMtx[binds.z];
float3x4 b3 = gBoneMtx[binds.w];
float4 t0 = b0[0] * weights.x + b1[0] * weights.y + b2[0] * weights.z + b3[0] * weights.w;
float4 t1 = b0[1] * weights.x + b1[1] * weights.y + b2[1] * weights.z + b3[1] * weights.w;
float4 t2 = b0[2] * weights.x + b1[2] * weights.y + b2[2] * weights.z + b3[2] * weights.w;
return float3x4(t0, t1, t2);
}
float3 BoneTransform(float3 ipos, float3x4 m)
{
float3 r;
float4 p = float4(ipos, 1);
r.x = dot(m[0], p);
r.y = dot(m[1], p);
r.z = dot(m[2], p);
return r;
if (binds.z > 254) //this is the signal to use clothVertices!
{
float4 cv0 = clothVertices[binds.w];
float4 cv1 = clothVertices[binds.x];
float4 cv2 = clothVertices[binds.y];
float3 r0 = cv0.zxy - cv1.zxy;
float3 r8 = cv2.yzx - cv1.yzx;
float3 r4 = normalize((r0.zxy * r8.yzx) - (r0.xyz * r8.xyz));
float3 r5 = (cv2.xyz * weights.x) + (cv1.xyz * weights.y) + (cv0.xyz * weights.z);
float r0w = (weights.w - 0.5) * 0.1;
r5 = (r0w * -r4) + r5;
opos = r5;
}
else
{
float3x4 b0 = gBoneMtx[binds.x];
float3x4 b1 = gBoneMtx[binds.y];
float3x4 b2 = gBoneMtx[binds.z];
float3x4 b3 = gBoneMtx[binds.w];
float4 t0 = b0[0] * weights.x + b1[0] * weights.y + b2[0] * weights.z + b3[0] * weights.w;
float4 t1 = b0[1] * weights.x + b1[1] * weights.y + b2[1] * weights.z + b3[1] * weights.w;
float4 t2 = b0[2] * weights.x + b1[2] * weights.y + b2[2] * weights.z + b3[2] * weights.w;
float3x4 m = float3x4(t0, t1, t2);
float4 p = float4(ipos, 1);
opos = float3(dot(m[0], p), dot(m[1], p), dot(m[2], p));
}
}
@ -88,8 +101,8 @@ float3 BoneTransform(float3 ipos, float3x4 m)
VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT output;
float3x4 bone = BoneMatrix(input.BlendWeights, input.BlendIndices);
float3 ipos = BoneTransform(input.Position.xyz, bone);
float3 ipos;
BoneTransform(input.BlendWeights, input.BlendIndices, input.Position.xyz, ipos);
float3 tpos = (HasTransforms == 1) ? mul(float4(ipos, 1), Transform).xyz : ipos;
float3 spos = tpos * Scale;
float3 bpos = mulvq(spos, Orientation);

View File

@ -672,7 +672,7 @@ namespace CodeWalker.Peds
}
if (peds.Count > 0)
{
var ind = PedNameComboBox.FindString("A_F_M_Beach_01"); // //A_C_Pug
var ind = PedNameComboBox.FindString("A_F_Y_Beach_01"); // //A_C_Pug
PedNameComboBox.SelectedIndex = Math.Max(ind, 0);
//PedNameComboBox.SelectedIndex = 0;
}

View File

@ -80,6 +80,8 @@ namespace CodeWalker.Rendering
public bool EnableRootMotion = false; //used to toggle whether or not to include root motion when playing animations
public ClothInstance Cloth;
public override void Init(DrawableBase drawable)
{

View File

@ -2509,7 +2509,7 @@ namespace CodeWalker.Rendering
return res;
}
public bool RenderDrawable(DrawableBase drawable, Archetype arche, YmapEntityDef entity, uint txdHash = 0, TextureDictionary txdExtra = null, Texture diffOverride = null, ClipMapEntry animClip = null)
public bool RenderDrawable(DrawableBase drawable, Archetype arche, YmapEntityDef entity, uint txdHash = 0, TextureDictionary txdExtra = null, Texture diffOverride = null, ClipMapEntry animClip = null, ClothInstance cloth = null)
{
//enqueue a single drawable for rendering.
@ -2534,6 +2534,9 @@ namespace CodeWalker.Rendering
rndbl.ResetBoneTransforms();
}
rndbl.Cloth = cloth;
return RenderRenderable(rndbl, arche, entity);
}
@ -2596,6 +2599,10 @@ namespace CodeWalker.Rendering
{
rndbl.UpdateAnims(currentRealTime);
}
if (rndbl.Cloth != null)
{
rndbl.Cloth.Update(currentRealTime);
}
@ -2795,6 +2802,7 @@ namespace CodeWalker.Rendering
//var compData = ped.Ymt?.VariationInfo?.GetComponentData(i);
var drawable = ped.Drawables[i];
var texture = ped.Textures[i];
var cloth = ped.Clothes[i];
//if (compData == null) return;
if (drawable == null) return;
@ -2837,7 +2845,7 @@ namespace CodeWalker.Rendering
if (drawFlag)
{
RenderDrawable(drawable, null, ped.RenderEntity, 0, td, texture, ac);
RenderDrawable(drawable, null, ped.RenderEntity, 0, td, texture, ac, cloth);
}

View File

@ -154,6 +154,7 @@ namespace CodeWalker.Rendering
GpuVarsBuffer<BasicShaderInstGlobals> InstGlobalVars;
GpuVarsBuffer<BasicShaderInstLocals> InstLocalVars;
GpuABuffer<Matrix3_s> BoneMatrices;
GpuABuffer<Vector4> ClothVertices;
SamplerState texsampler;
SamplerState texsampleranis;
SamplerState texsamplertnt;
@ -244,6 +245,7 @@ namespace CodeWalker.Rendering
InstGlobalVars = new GpuVarsBuffer<BasicShaderInstGlobals>(device);
InstLocalVars = new GpuVarsBuffer<BasicShaderInstLocals>(device);
BoneMatrices = new GpuABuffer<Matrix3_s>(device, 255);
ClothVertices = new GpuABuffer<Vector4>(device, 254);
InitInstGlobalVars();
@ -584,6 +586,10 @@ namespace CodeWalker.Rendering
SetBoneMatrices(context, defaultBoneMatrices);
defaultBoneMatricesBound = true;
}
if (model.Owner.Cloth?.Vertices != null)
{
SetClothVertices(context, model.Owner.Cloth.Vertices);
}
if (!model.UseTransform) return;
VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
@ -829,6 +835,12 @@ namespace CodeWalker.Rendering
BoneMatrices.SetVSCBuffer(context, 7);
}
public void SetClothVertices(DeviceContext context, Vector4[] vertices)
{
ClothVertices.Update(context, vertices);
ClothVertices.SetVSCBuffer(context, 8);
}
public void SetInstanceVars(DeviceContext context, RenderableInstanceBatch batch)
{
@ -1020,6 +1032,7 @@ namespace CodeWalker.Rendering
InstGlobalVars.Dispose();
InstLocalVars.Dispose();
BoneMatrices.Dispose();
ClothVertices.Dispose();
basicps.Dispose();
basicvspnct.Dispose();

View File

@ -65,6 +65,7 @@ namespace CodeWalker.Rendering
GpuVarsBuffer<ShadowShaderVSModelVars> VSModelVars;
GpuVarsBuffer<ShadowShaderGeomVars> GeomVars;
GpuABuffer<Matrix3_s> BoneMatrices;
GpuABuffer<Vector4> ClothVertices;
SamplerState texsampler;
SamplerState texsamplerc;
@ -94,6 +95,7 @@ namespace CodeWalker.Rendering
VSModelVars = new GpuVarsBuffer<ShadowShaderVSModelVars>(device);
GeomVars = new GpuVarsBuffer<ShadowShaderGeomVars>(device);
BoneMatrices = new GpuABuffer<Matrix3_s>(device, 255);
ClothVertices = new GpuABuffer<Vector4>(device, 254);
//supported layouts - requires Position, Normal, Colour, Texcoord
@ -243,6 +245,10 @@ namespace CodeWalker.Rendering
SetBoneMatrices(context, defaultBoneMatrices);
defaultBoneMatricesBound = true;
}
if (model.Owner.Cloth?.Vertices != null)
{
SetClothVertices(context, model.Owner.Cloth.Vertices);
}
if (!model.UseTransform) return;
VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
@ -378,6 +384,12 @@ namespace CodeWalker.Rendering
BoneMatrices.SetVSCBuffer(context, 7);
}
public void SetClothVertices(DeviceContext context, Vector4[] vertices)
{
ClothVertices.Update(context, vertices);
ClothVertices.SetVSCBuffer(context, 8);
}
public override void UnbindResources(DeviceContext context)
{
@ -415,6 +427,7 @@ namespace CodeWalker.Rendering
VSModelVars.Dispose();
GeomVars.Dispose();
BoneMatrices.Dispose();
ClothVertices.Dispose();
shadowps.Dispose();

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.