mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-11-21 22:42:54 +08:00
Ped clothes not exploding
This commit is contained in:
parent
181689ac95
commit
ef1debfb41
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{ }
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -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
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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...
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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...
|
||||
|
||||
|
@ -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...
|
||||
|
||||
|
@ -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...
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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.
Loading…
Reference in New Issue
Block a user