mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-11-25 16:32:55 +08:00
Animations XML conversion
This commit is contained in:
parent
918ed7fccf
commit
7e43271a67
@ -5,6 +5,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
namespace CodeWalker.GameFiles
|
namespace CodeWalker.GameFiles
|
||||||
{
|
{
|
||||||
@ -19,6 +20,7 @@ namespace CodeWalker.GameFiles
|
|||||||
public ClipMapEntry[] ClipMapEntries { get; set; }
|
public ClipMapEntry[] ClipMapEntries { get; set; }
|
||||||
public AnimationMapEntry[] AnimMapEntries { get; set; }
|
public AnimationMapEntry[] AnimMapEntries { get; set; }
|
||||||
|
|
||||||
|
public string LoadException { get; set; }
|
||||||
|
|
||||||
public YcdFile() : base(null, GameFileType.Ycd)
|
public YcdFile() : base(null, GameFileType.Ycd)
|
||||||
{
|
{
|
||||||
@ -41,91 +43,58 @@ namespace CodeWalker.GameFiles
|
|||||||
throw new Exception("File entry wasn't a resource! (is it binary data?)");
|
throw new Exception("File entry wasn't a resource! (is it binary data?)");
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceDataReader rd = new ResourceDataReader(resentry, data);
|
ResourceDataReader rd = null;
|
||||||
|
try
|
||||||
|
|
||||||
ClipDictionary = rd.ReadBlock<ClipDictionary>();
|
|
||||||
|
|
||||||
ClipMap = new Dictionary<MetaHash, ClipMapEntry>();
|
|
||||||
AnimMap = new Dictionary<MetaHash, AnimationMapEntry>();
|
|
||||||
if (ClipDictionary != null)
|
|
||||||
{
|
{
|
||||||
if ((ClipDictionary.Clips != null) && (ClipDictionary.Clips.data_items != null))
|
rd = new ResourceDataReader(resentry, data);
|
||||||
{
|
|
||||||
foreach (var cme in ClipDictionary.Clips.data_items)
|
|
||||||
{
|
|
||||||
if (cme != null)
|
|
||||||
{
|
|
||||||
ClipMap[cme.Hash] = cme;
|
|
||||||
var nxt = cme.Next;
|
|
||||||
while (nxt != null)
|
|
||||||
{
|
|
||||||
ClipMap[nxt.Hash] = nxt;
|
|
||||||
nxt = nxt.Next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((ClipDictionary.Animations != null) && (ClipDictionary.Animations.Animations != null) && (ClipDictionary.Animations.Animations.data_items != null))
|
|
||||||
{
|
|
||||||
foreach (var ame in ClipDictionary.Animations.Animations.data_items)
|
|
||||||
{
|
|
||||||
if (ame != null)
|
|
||||||
{
|
|
||||||
AnimMap[ame.Hash] = ame;
|
|
||||||
var nxt = ame.NextEntry;
|
|
||||||
while (nxt != null)
|
|
||||||
{
|
|
||||||
AnimMap[nxt.Hash] = nxt;
|
|
||||||
nxt = nxt.NextEntry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//data = entry.File.DecompressBytes(data); //??
|
||||||
|
LoadException = ex.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClipDictionary = rd?.ReadBlock<ClipDictionary>();
|
||||||
|
|
||||||
|
InitDictionaries();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InitDictionaries()
|
||||||
|
{
|
||||||
|
ClipMap = ClipDictionary?.ClipMap ?? new Dictionary<MetaHash, ClipMapEntry>();
|
||||||
|
AnimMap = ClipDictionary?.AnimMap ?? new Dictionary<MetaHash, AnimationMapEntry>();
|
||||||
|
|
||||||
foreach (var cme in ClipMap.Values)
|
foreach (var cme in ClipMap.Values)
|
||||||
{
|
{
|
||||||
var clip = cme.Clip;
|
if (cme?.Clip != null) cme.Clip.Ycd = this;
|
||||||
if (clip == null) continue;
|
|
||||||
clip.Ycd = this;
|
|
||||||
if (string.IsNullOrEmpty(clip.Name)) continue;
|
|
||||||
string name = clip.Name.Replace('\\', '/');
|
|
||||||
var slidx = name.LastIndexOf('/');
|
|
||||||
if ((slidx >= 0) && (slidx < name.Length - 1))
|
|
||||||
{
|
|
||||||
name = name.Substring(slidx + 1);
|
|
||||||
}
|
|
||||||
var didx = name.LastIndexOf('.');
|
|
||||||
if ((didx > 0) && (didx < name.Length))
|
|
||||||
{
|
|
||||||
name = name.Substring(0, didx);
|
|
||||||
}
|
|
||||||
clip.ShortName = name;
|
|
||||||
name = name.ToLowerInvariant();
|
|
||||||
JenkIndex.Ensure(name);
|
|
||||||
|
|
||||||
|
|
||||||
//if (name.EndsWith("_uv_0")) //hash for these entries match string with this removed, +1
|
|
||||||
//{
|
|
||||||
//}
|
|
||||||
//if (name.EndsWith("_uv_1")) //same as above, but +2
|
|
||||||
//{
|
|
||||||
//}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
foreach (var ame in AnimMap.Values)
|
foreach (var ame in AnimMap.Values)
|
||||||
{
|
{
|
||||||
var anim = ame.Animation;
|
if (ame?.Animation != null) ame.Animation.Ycd = this;
|
||||||
if (anim == null) continue;
|
|
||||||
anim.Ycd = this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ClipMapEntries = ClipMap.Values.ToArray();
|
ClipMapEntries = ClipMap.Values.ToArray();
|
||||||
AnimMapEntries = AnimMap.Values.ToArray();
|
AnimMapEntries = AnimMap.Values.ToArray();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public byte[] Save()
|
||||||
|
{
|
||||||
|
//if (BuildStructsOnSave)
|
||||||
|
//{
|
||||||
|
// BuildStructs();
|
||||||
|
//}
|
||||||
|
|
||||||
|
byte[] data = ResourceBuilder.Build(ClipDictionary, 46); //ycd is 46...
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void SaveOpenFormatsAnimation(Animation crAnim, Stream outStream)
|
public void SaveOpenFormatsAnimation(Animation crAnim, Stream outStream)
|
||||||
{
|
{
|
||||||
var seqs = new int[(crAnim.Frames / crAnim.SequenceFrameLimit) + 1];
|
var seqs = new int[(crAnim.Frames / crAnim.SequenceFrameLimit) + 1];
|
||||||
@ -171,7 +140,7 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
else if (chList.Length == 1)
|
else if (chList.Length == 1)
|
||||||
{
|
{
|
||||||
if (chList[0] is AnimChannelStaticSmallestThreeQuaternion)
|
if (chList[0] is AnimChannelStaticQuaternion)
|
||||||
{
|
{
|
||||||
isRotation = true;
|
isRotation = true;
|
||||||
}
|
}
|
||||||
@ -201,7 +170,7 @@ namespace CodeWalker.GameFiles
|
|||||||
return " Static";
|
return " Static";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (chan is AnimChannelStaticFloat || chan is AnimChannelStaticVector3 || chan is AnimChannelStaticSmallestThreeQuaternion)
|
else if (chan is AnimChannelStaticFloat || chan is AnimChannelStaticVector3 || chan is AnimChannelStaticQuaternion)
|
||||||
{
|
{
|
||||||
return " Static";
|
return " Static";
|
||||||
}
|
}
|
||||||
@ -245,10 +214,10 @@ namespace CodeWalker.GameFiles
|
|||||||
switch (chan)
|
switch (chan)
|
||||||
{
|
{
|
||||||
case AnimChannelStaticFloat sf:
|
case AnimChannelStaticFloat sf:
|
||||||
return $" {sf.FloatValue}\r\n";
|
return $" {sf.Value}\r\n";
|
||||||
case AnimChannelStaticVector3 v3:
|
case AnimChannelStaticVector3 v3:
|
||||||
return $" {v3.Value[0]} {v3.Value[1]} {v3.Value[2]}\r\n";
|
return $" {v3.Value[0]} {v3.Value[1]} {v3.Value[2]}\r\n";
|
||||||
case AnimChannelStaticSmallestThreeQuaternion q3:
|
case AnimChannelStaticQuaternion q3:
|
||||||
return $" {q3.Value[0]} {q3.Value[1]} {q3.Value[2]} {q3.Value[3]}\r\n";
|
return $" {q3.Value[0]} {q3.Value[1]} {q3.Value[2]} {q3.Value[3]}\r\n";
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
@ -303,4 +272,61 @@ namespace CodeWalker.GameFiles
|
|||||||
writer.Flush();
|
writer.Flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class YcdXml : MetaXmlBase
|
||||||
|
{
|
||||||
|
|
||||||
|
public static string GetXml(YcdFile ycd)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.AppendLine(XmlHeader);
|
||||||
|
|
||||||
|
if ((ycd != null) && (ycd.ClipDictionary != null))
|
||||||
|
{
|
||||||
|
var name = "ClipDictionary";
|
||||||
|
|
||||||
|
OpenTag(sb, 0, name);
|
||||||
|
|
||||||
|
ycd.ClipDictionary.WriteXml(sb, 1);
|
||||||
|
|
||||||
|
CloseTag(sb, 0, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class XmlYcd
|
||||||
|
{
|
||||||
|
|
||||||
|
public static YcdFile GetYcd(string xml)
|
||||||
|
{
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
doc.LoadXml(xml);
|
||||||
|
return GetYcd(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static YcdFile GetYcd(XmlDocument doc)
|
||||||
|
{
|
||||||
|
YcdFile ycd = new YcdFile();
|
||||||
|
ycd.ClipDictionary = new ClipDictionary();
|
||||||
|
ycd.ClipDictionary.ReadXml(doc.DocumentElement);
|
||||||
|
ycd.InitDictionaries();
|
||||||
|
//ycd.BuildStructsOnSave = false; //structs don't need to be rebuilt here!
|
||||||
|
return ycd;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -2964,38 +2964,274 @@ namespace CodeWalker.GameFiles
|
|||||||
}
|
}
|
||||||
public void TestYcds()
|
public void TestYcds()
|
||||||
{
|
{
|
||||||
|
var errorfiles = new List<YcdFile>();
|
||||||
|
var errorentries = new List<RpfEntry>();
|
||||||
|
|
||||||
foreach (RpfFile file in AllRpfs)
|
foreach (RpfFile file in AllRpfs)
|
||||||
{
|
{
|
||||||
foreach (RpfEntry entry in file.AllEntries)
|
foreach (RpfEntry entry in file.AllEntries)
|
||||||
{
|
{
|
||||||
try
|
//try
|
||||||
|
//{
|
||||||
|
if (entry.NameLower.EndsWith(".ycd"))
|
||||||
{
|
{
|
||||||
if (entry.NameLower.EndsWith(".ycd"))
|
UpdateStatus(string.Format(entry.Path));
|
||||||
|
YcdFile ycd1 = RpfMan.GetFile<YcdFile>(entry);
|
||||||
|
if (ycd1 == null)
|
||||||
{
|
{
|
||||||
UpdateStatus(string.Format(entry.Path));
|
errorentries.Add(entry);
|
||||||
YcdFile ycdfile = RpfMan.GetFile<YcdFile>(entry);
|
}
|
||||||
if ((ycdfile != null))// && (ycdfile.Meta != null))
|
else if (ycd1?.LoadException != null)
|
||||||
{ }
|
{
|
||||||
|
errorfiles.Add(ycd1);//these ones have file corruption issues and won't load as resource...
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ycd1.ClipDictionary == null)
|
||||||
|
{ continue; }
|
||||||
|
|
||||||
|
var t = true;
|
||||||
|
if (t)//just here to test loading only
|
||||||
|
{ continue; }
|
||||||
|
|
||||||
|
var xml = YcdXml.GetXml(ycd1);
|
||||||
|
var ycdX = XmlYcd.GetYcd(xml);
|
||||||
|
var data = ycdX.Save();
|
||||||
|
var ycd2 = new YcdFile();
|
||||||
|
RpfFile.LoadResourceFile(ycd2, data, 46);//full roundtrip
|
||||||
|
|
||||||
|
|
||||||
|
if (ycd2 == null)
|
||||||
|
{ continue; }
|
||||||
|
if (ycd2.ClipDictionary == null)
|
||||||
|
{ continue; }
|
||||||
|
|
||||||
|
var c1 = ycd1.ClipDictionary.Clips?.data_items;
|
||||||
|
var c2 = ycd2.ClipDictionary.Clips?.data_items;
|
||||||
|
if ((c1 == null) || (c2 == null))
|
||||||
|
{ continue; }
|
||||||
|
if (c1.Length != c2.Length)
|
||||||
|
{ continue; }
|
||||||
|
|
||||||
|
var a1 = ycd1.ClipDictionary.Animations?.Animations?.data_items;
|
||||||
|
var a2 = ycd2.ClipDictionary.Animations?.Animations?.data_items;
|
||||||
|
if ((a1 == null) || (a2 == null))
|
||||||
|
{ continue; }
|
||||||
|
if (a1.Length != a2.Length)
|
||||||
|
{ continue; }
|
||||||
|
|
||||||
|
var m1 = ycd1.AnimMap;
|
||||||
|
var m2 = ycd2.AnimMap;
|
||||||
|
if ((m1 == null) || (m2 == null))
|
||||||
|
{ continue; }
|
||||||
|
if (m1.Count != m2.Count)
|
||||||
|
{ continue; }
|
||||||
|
foreach (var kvp1 in m1)
|
||||||
|
{
|
||||||
|
var an1 = kvp1.Value;
|
||||||
|
var an2 = an1;
|
||||||
|
if(!m2.TryGetValue(kvp1.Key, out an2))
|
||||||
|
{ continue; }
|
||||||
|
|
||||||
|
var sa1 = an1?.Animation?.Sequences?.data_items;
|
||||||
|
var sa2 = an2?.Animation?.Sequences?.data_items;
|
||||||
|
if ((sa1 == null) || (sa2 == null))
|
||||||
|
{ continue; }
|
||||||
|
if (sa1.Length != sa2.Length)
|
||||||
|
{ continue; }
|
||||||
|
for (int s = 0; s < sa1.Length; s++)
|
||||||
|
{
|
||||||
|
var s1 = sa1[s];
|
||||||
|
var s2 = sa2[s];
|
||||||
|
if ((s1?.Sequences == null) || (s2?.Sequences == null))
|
||||||
|
{ continue; }
|
||||||
|
|
||||||
|
if (s1.NumFrames != s2.NumFrames)
|
||||||
|
{ }
|
||||||
|
if (s1.ChunkSize != s2.ChunkSize)
|
||||||
|
{ }
|
||||||
|
if (s1.FrameOffset != s2.FrameOffset)
|
||||||
|
{ }
|
||||||
|
if (s1.DataLength != s2.DataLength)
|
||||||
|
{ }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//for (int b = 0; b < s1.DataLength; b++)
|
||||||
|
//{
|
||||||
|
// var b1 = s1.Data[b];
|
||||||
|
// var b2 = s2.Data[b];
|
||||||
|
// if (b1 != b2)
|
||||||
|
// { }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int ss = 0; ss < s1.Sequences.Length; ss++)
|
||||||
|
{
|
||||||
|
var ss1 = s1.Sequences[ss];
|
||||||
|
var ss2 = s2.Sequences[ss];
|
||||||
|
if ((ss1?.Channels == null) || (ss2?.Channels == null))
|
||||||
|
{ continue; }
|
||||||
|
if (ss1.Channels.Length != ss2.Channels.Length)
|
||||||
|
{ continue; }
|
||||||
|
|
||||||
|
|
||||||
|
for (int c = 0; c < ss1.Channels.Length; c++)
|
||||||
|
{
|
||||||
|
var sc1 = ss1.Channels[c];
|
||||||
|
var sc2 = ss2.Channels[c];
|
||||||
|
if ((sc1 == null) || (sc2 == null))
|
||||||
|
{ continue; }
|
||||||
|
if (sc1.Type == AnimChannelType.LinearFloat)
|
||||||
|
{ continue; }
|
||||||
|
if (sc1.Type != sc2.Type)
|
||||||
|
{ continue; }
|
||||||
|
if (sc1.Index != sc2.Index)
|
||||||
|
{ continue; }
|
||||||
|
if (sc1.Type == AnimChannelType.StaticQuaternion)
|
||||||
|
{
|
||||||
|
var acsq1 = sc1 as AnimChannelStaticQuaternion;
|
||||||
|
var acsq2 = sc2 as AnimChannelStaticQuaternion;
|
||||||
|
var vdiff = acsq1.Value - acsq2.Value;
|
||||||
|
var len = vdiff.Length();
|
||||||
|
var v1len = Math.Max(acsq1.Value.Length(), 1);
|
||||||
|
if (len > 1e-2f * v1len)
|
||||||
|
{ continue; }
|
||||||
|
}
|
||||||
|
else if (sc1.Type == AnimChannelType.StaticVector3)
|
||||||
|
{
|
||||||
|
var acsv1 = sc1 as AnimChannelStaticVector3;
|
||||||
|
var acsv2 = sc2 as AnimChannelStaticVector3;
|
||||||
|
var vdiff = acsv1.Value - acsv2.Value;
|
||||||
|
var len = vdiff.Length();
|
||||||
|
var v1len = Math.Max(acsv1.Value.Length(), 1);
|
||||||
|
if (len > 1e-2f * v1len)
|
||||||
|
{ continue; }
|
||||||
|
}
|
||||||
|
else if (sc1.Type == AnimChannelType.StaticFloat)
|
||||||
|
{
|
||||||
|
var acsf1 = sc1 as AnimChannelStaticFloat;
|
||||||
|
var acsf2 = sc2 as AnimChannelStaticFloat;
|
||||||
|
var vdiff = Math.Abs(acsf1.Value - acsf2.Value);
|
||||||
|
var v1len = Math.Max(Math.Abs(acsf1.Value), 1);
|
||||||
|
if (vdiff > 1e-2f * v1len)
|
||||||
|
{ continue; }
|
||||||
|
}
|
||||||
|
else if (sc1.Type == AnimChannelType.RawFloat)
|
||||||
|
{
|
||||||
|
var acrf1 = sc1 as AnimChannelRawFloat;
|
||||||
|
var acrf2 = sc2 as AnimChannelRawFloat;
|
||||||
|
for (int v = 0; v < acrf1.Values.Length; v++)
|
||||||
|
{
|
||||||
|
var v1 = acrf1.Values[v];
|
||||||
|
var v2 = acrf2.Values[v];
|
||||||
|
var vdiff = Math.Abs(v1 - v2);
|
||||||
|
var v1len = Math.Max(Math.Abs(v1), 1);
|
||||||
|
if (vdiff > 1e-2f * v1len)
|
||||||
|
{ break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (sc1.Type == AnimChannelType.QuantizeFloat)
|
||||||
|
{
|
||||||
|
var acqf1 = sc1 as AnimChannelQuantizeFloat;
|
||||||
|
var acqf2 = sc2 as AnimChannelQuantizeFloat;
|
||||||
|
if (acqf1.ValueBits != acqf2.ValueBits)
|
||||||
|
{ continue; }
|
||||||
|
if (Math.Abs(acqf1.Offset - acqf2.Offset) > (0.001f * Math.Abs(acqf1.Offset)))
|
||||||
|
{ continue; }
|
||||||
|
if (Math.Abs(acqf1.Quantum - acqf2.Quantum) > 0.00001f)
|
||||||
|
{ continue; }
|
||||||
|
for (int v = 0; v < acqf1.Values.Length; v++)
|
||||||
|
{
|
||||||
|
var v1 = acqf1.Values[v];
|
||||||
|
var v2 = acqf2.Values[v];
|
||||||
|
var vdiff = Math.Abs(v1 - v2);
|
||||||
|
var v1len = Math.Max(Math.Abs(v1), 1);
|
||||||
|
if (vdiff > 1e-2f * v1len)
|
||||||
|
{ break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (sc1.Type == AnimChannelType.IndirectQuantizeFloat)
|
||||||
|
{
|
||||||
|
var aciqf1 = sc1 as AnimChannelIndirectQuantizeFloat;
|
||||||
|
var aciqf2 = sc2 as AnimChannelIndirectQuantizeFloat;
|
||||||
|
if (aciqf1.FrameBits != aciqf2.FrameBits)
|
||||||
|
{ continue; }
|
||||||
|
if (aciqf1.ValueBits != aciqf2.ValueBits)
|
||||||
|
{ continue; }
|
||||||
|
if (Math.Abs(aciqf1.Offset - aciqf2.Offset) > (0.001f * Math.Abs(aciqf1.Offset)))
|
||||||
|
{ continue; }
|
||||||
|
if (Math.Abs(aciqf1.Quantum - aciqf2.Quantum) > 0.00001f)
|
||||||
|
{ continue; }
|
||||||
|
for (int f = 0; f < aciqf1.Frames.Length; f++)
|
||||||
|
{
|
||||||
|
if (aciqf1.Frames[f] != aciqf2.Frames[f])
|
||||||
|
{ break; }
|
||||||
|
}
|
||||||
|
for (int v = 0; v < aciqf1.Values.Length; v++)
|
||||||
|
{
|
||||||
|
var v1 = aciqf1.Values[v];
|
||||||
|
var v2 = aciqf2.Values[v];
|
||||||
|
var vdiff = Math.Abs(v1 - v2);
|
||||||
|
var v1len = Math.Max(Math.Abs(v1), 1);
|
||||||
|
if (vdiff > 1e-2f * v1len)
|
||||||
|
{ break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((sc1.Type == AnimChannelType.CachedQuaternion1)||(sc1.Type == AnimChannelType.CachedQuaternion2))
|
||||||
|
{
|
||||||
|
var acrf1 = sc1 as AnimChannelCachedQuaternion;
|
||||||
|
var acrf2 = sc2 as AnimChannelCachedQuaternion;
|
||||||
|
if (acrf1.QuatIndex != acrf2.QuatIndex)
|
||||||
|
{ continue; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//for (int f = 0; f < s1.NumFrames; f++)
|
||||||
|
//{
|
||||||
|
// var v1 = ss1.EvaluateVector(f);
|
||||||
|
// var v2 = ss2.EvaluateVector(f);
|
||||||
|
// var vdiff = v1 - v2;
|
||||||
|
// var len = vdiff.Length();
|
||||||
|
// var v1len = Math.Max(v1.Length(), 1);
|
||||||
|
// if (len > 1e-2f*v1len)
|
||||||
|
// { }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
//if (entry.NameLower.EndsWith(".awc")) //awcs can also contain clip dicts..
|
|
||||||
//{
|
|
||||||
// UpdateStatus(string.Format(entry.Path));
|
|
||||||
// AwcFile awcfile = RpfMan.GetFile<AwcFile>(entry);
|
|
||||||
// if ((awcfile != null))
|
|
||||||
// { }
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
UpdateStatus("Error! " + ex.ToString());
|
|
||||||
}
|
}
|
||||||
|
//if (entry.NameLower.EndsWith(".awc")) //awcs can also contain clip dicts..
|
||||||
|
//{
|
||||||
|
// UpdateStatus(string.Format(entry.Path));
|
||||||
|
// AwcFile awcfile = RpfMan.GetFile<AwcFile>(entry);
|
||||||
|
// if ((awcfile != null))
|
||||||
|
// { }
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
//catch (Exception ex)
|
||||||
|
//{
|
||||||
|
// UpdateStatus("Error! " + ex.ToString());
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//var sd = Sequence.SeqDict;
|
if (errorfiles.Count > 0)
|
||||||
//if (sd != null)
|
{ }
|
||||||
//{
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
public void TestYtds()
|
public void TestYtds()
|
||||||
{
|
{
|
||||||
|
@ -1384,18 +1384,6 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string XmlEscape(string unescaped)
|
|
||||||
{
|
|
||||||
if (unescaped == null) return null;
|
|
||||||
XmlDocument doc = new XmlDocument();
|
|
||||||
XmlNode node = doc.CreateElement("root");
|
|
||||||
node.InnerText = unescaped;
|
|
||||||
var escaped = node.InnerXml;
|
|
||||||
if (escaped != unescaped)
|
|
||||||
{ }
|
|
||||||
return node.InnerXml;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class PsoCont
|
public class PsoCont
|
||||||
{
|
{
|
||||||
@ -1742,9 +1730,16 @@ namespace CodeWalker.GameFiles
|
|||||||
var cind2 = ind + 2;
|
var cind2 = ind + 2;
|
||||||
for (int i = 0; i < itemCount; i++)
|
for (int i = 0; i < itemCount; i++)
|
||||||
{
|
{
|
||||||
OpenTag(sb, cind, "Item");
|
if (arr[i] != null)
|
||||||
arr[i].WriteXml(sb, cind2);
|
{
|
||||||
CloseTag(sb, cind, "Item");
|
OpenTag(sb, cind, "Item");
|
||||||
|
arr[i].WriteXml(sb, cind2);
|
||||||
|
CloseTag(sb, cind, "Item");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SelfClosingTag(sb, cind, "Item");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CloseTag(sb, ind, name);
|
CloseTag(sb, ind, name);
|
||||||
}
|
}
|
||||||
@ -1891,6 +1886,22 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static string XmlEscape(string unescaped)
|
||||||
|
{
|
||||||
|
if (unescaped == null) return null;
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
XmlNode node = doc.CreateElement("root");
|
||||||
|
node.InnerText = unescaped;
|
||||||
|
var escaped = node.InnerXml;
|
||||||
|
if (escaped != unescaped)
|
||||||
|
{ }
|
||||||
|
return node.InnerXml;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public enum XmlTagMode
|
public enum XmlTagMode
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
@ -813,6 +813,78 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static T[] ReadItemArray<T>(XmlNode node, string name) where T : IMetaXmlItem, new()
|
||||||
|
{
|
||||||
|
var vnode2 = node.SelectSingleNode(name);
|
||||||
|
if (vnode2 != null)
|
||||||
|
{
|
||||||
|
var inodes = vnode2.SelectNodes("Item");
|
||||||
|
if (inodes?.Count > 0)
|
||||||
|
{
|
||||||
|
var vlist = new List<T>();
|
||||||
|
foreach (XmlNode inode in inodes)
|
||||||
|
{
|
||||||
|
var v = new T();
|
||||||
|
v.ReadXml(inode);
|
||||||
|
vlist.Add(v);
|
||||||
|
}
|
||||||
|
return vlist.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T[] ReadItemArrayNullable<T>(XmlNode node, string name) where T : IMetaXmlItem, new()
|
||||||
|
{
|
||||||
|
var vnode2 = node.SelectSingleNode(name);
|
||||||
|
if (vnode2 != null)
|
||||||
|
{
|
||||||
|
var inodes = vnode2.SelectNodes("Item");
|
||||||
|
if (inodes?.Count > 0)
|
||||||
|
{
|
||||||
|
var vlist = new List<T>();
|
||||||
|
foreach (XmlNode inode in inodes)
|
||||||
|
{
|
||||||
|
if (inode.HasChildNodes)
|
||||||
|
{
|
||||||
|
var v = new T();
|
||||||
|
v.ReadXml(inode);
|
||||||
|
vlist.Add(v);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vlist.Add(default(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vlist.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static MetaHash[] ReadHashItemArray(XmlNode node, string name)
|
||||||
|
{
|
||||||
|
var vnode = node.SelectSingleNode(name);
|
||||||
|
if (vnode != null)
|
||||||
|
{
|
||||||
|
var inodes = vnode.SelectNodes("Item");
|
||||||
|
if (inodes?.Count > 0)
|
||||||
|
{
|
||||||
|
var vlist = new List<MetaHash>();
|
||||||
|
foreach (XmlNode inode in inodes)
|
||||||
|
{
|
||||||
|
vlist.Add(GetHash(inode.InnerText));
|
||||||
|
}
|
||||||
|
return vlist.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ArrayResults
|
struct ArrayResults
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -748,7 +748,7 @@ namespace CodeWalker.GameFiles
|
|||||||
public ushort EntriesCapacity { get; private set; }
|
public ushort EntriesCapacity { get; private set; }
|
||||||
|
|
||||||
// reference data
|
// reference data
|
||||||
public T[] data_items { get; private set; }
|
public T[] data_items { get; set; }
|
||||||
|
|
||||||
private ResourceSystemStructBlock<T> data_block;//used for saving.
|
private ResourceSystemStructBlock<T> data_block;//used for saving.
|
||||||
|
|
||||||
|
@ -218,11 +218,35 @@ namespace CodeWalker
|
|||||||
return GetRawByteArray(cnode);
|
return GetRawByteArray(cnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static uint[] GetRawUintArray(XmlNode node)
|
||||||
|
{
|
||||||
|
if (node == null) return new uint[0];
|
||||||
|
var data = new List<uint>();
|
||||||
|
var split = Regex.Split(node.InnerText, @"[\s\r\n\t]");
|
||||||
|
for (int i = 0; i < split.Length; i++)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(split[i]))
|
||||||
|
{
|
||||||
|
var str = split[i];
|
||||||
|
if (string.IsNullOrEmpty(str)) continue;
|
||||||
|
var val = 0u;
|
||||||
|
uint.TryParse(str, out val);
|
||||||
|
data.Add(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data.ToArray();
|
||||||
|
}
|
||||||
|
public static uint[] GetChildRawUintArray(XmlNode node, string name)
|
||||||
|
{
|
||||||
|
var cnode = node.SelectSingleNode(name);
|
||||||
|
return GetRawUintArray(cnode);
|
||||||
|
}
|
||||||
|
|
||||||
public static float[] GetRawFloatArray(XmlNode node)
|
public static float[] GetRawFloatArray(XmlNode node)
|
||||||
{
|
{
|
||||||
if (node == null) return new float[0];
|
if (node == null) return new float[0];
|
||||||
var items = new List<float>();
|
var items = new List<float>();
|
||||||
var split = node.InnerText.Split('\n');// Regex.Split(node.InnerText, @"[\s\r\n\t]");
|
var split = Regex.Split(node.InnerText, @"[\s\r\n\t]");//node.InnerText.Split('\n');//
|
||||||
for (int i = 0; i < split.Length; i++)
|
for (int i = 0; i < split.Length; i++)
|
||||||
{
|
{
|
||||||
var s = split[i]?.Trim();
|
var s = split[i]?.Trim();
|
||||||
|
102
Forms/YcdForm.Designer.cs
generated
102
Forms/YcdForm.Designer.cs
generated
@ -28,6 +28,7 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
|
this.components = new System.ComponentModel.Container();
|
||||||
System.Windows.Forms.ListViewGroup listViewGroup1 = new System.Windows.Forms.ListViewGroup("Clips", System.Windows.Forms.HorizontalAlignment.Left);
|
System.Windows.Forms.ListViewGroup listViewGroup1 = new System.Windows.Forms.ListViewGroup("Clips", System.Windows.Forms.HorizontalAlignment.Left);
|
||||||
System.Windows.Forms.ListViewGroup listViewGroup2 = new System.Windows.Forms.ListViewGroup("Animations", System.Windows.Forms.HorizontalAlignment.Left);
|
System.Windows.Forms.ListViewGroup listViewGroup2 = new System.Windows.Forms.ListViewGroup("Animations", System.Windows.Forms.HorizontalAlignment.Left);
|
||||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(YcdForm));
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(YcdForm));
|
||||||
@ -35,10 +36,18 @@
|
|||||||
this.MainListView = new System.Windows.Forms.ListView();
|
this.MainListView = new System.Windows.Forms.ListView();
|
||||||
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||||
this.MainPropertyGrid = new CodeWalker.WinForms.ReadOnlyPropertyGrid();
|
this.MainPropertyGrid = new CodeWalker.WinForms.ReadOnlyPropertyGrid();
|
||||||
|
this.MainTabControl = new System.Windows.Forms.TabControl();
|
||||||
|
this.DetailsTabPage = new System.Windows.Forms.TabPage();
|
||||||
|
this.XmlTabPage = new System.Windows.Forms.TabPage();
|
||||||
|
this.XmlTextBox = new FastColoredTextBoxNS.FastColoredTextBox();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
|
||||||
this.splitContainer1.Panel1.SuspendLayout();
|
this.splitContainer1.Panel1.SuspendLayout();
|
||||||
this.splitContainer1.Panel2.SuspendLayout();
|
this.splitContainer1.Panel2.SuspendLayout();
|
||||||
this.splitContainer1.SuspendLayout();
|
this.splitContainer1.SuspendLayout();
|
||||||
|
this.MainTabControl.SuspendLayout();
|
||||||
|
this.DetailsTabPage.SuspendLayout();
|
||||||
|
this.XmlTabPage.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.XmlTextBox)).BeginInit();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// splitContainer1
|
// splitContainer1
|
||||||
@ -55,7 +64,7 @@
|
|||||||
// splitContainer1.Panel2
|
// splitContainer1.Panel2
|
||||||
//
|
//
|
||||||
this.splitContainer1.Panel2.Controls.Add(this.MainPropertyGrid);
|
this.splitContainer1.Panel2.Controls.Add(this.MainPropertyGrid);
|
||||||
this.splitContainer1.Size = new System.Drawing.Size(763, 474);
|
this.splitContainer1.Size = new System.Drawing.Size(751, 442);
|
||||||
this.splitContainer1.SplitterDistance = 254;
|
this.splitContainer1.SplitterDistance = 254;
|
||||||
this.splitContainer1.TabIndex = 1;
|
this.splitContainer1.TabIndex = 1;
|
||||||
//
|
//
|
||||||
@ -78,7 +87,7 @@
|
|||||||
this.MainListView.Location = new System.Drawing.Point(3, 3);
|
this.MainListView.Location = new System.Drawing.Point(3, 3);
|
||||||
this.MainListView.MultiSelect = false;
|
this.MainListView.MultiSelect = false;
|
||||||
this.MainListView.Name = "MainListView";
|
this.MainListView.Name = "MainListView";
|
||||||
this.MainListView.Size = new System.Drawing.Size(248, 468);
|
this.MainListView.Size = new System.Drawing.Size(248, 436);
|
||||||
this.MainListView.TabIndex = 0;
|
this.MainListView.TabIndex = 0;
|
||||||
this.MainListView.UseCompatibleStateImageBehavior = false;
|
this.MainListView.UseCompatibleStateImageBehavior = false;
|
||||||
this.MainListView.View = System.Windows.Forms.View.Details;
|
this.MainListView.View = System.Windows.Forms.View.Details;
|
||||||
@ -98,15 +107,92 @@
|
|||||||
this.MainPropertyGrid.Location = new System.Drawing.Point(3, 3);
|
this.MainPropertyGrid.Location = new System.Drawing.Point(3, 3);
|
||||||
this.MainPropertyGrid.Name = "MainPropertyGrid";
|
this.MainPropertyGrid.Name = "MainPropertyGrid";
|
||||||
this.MainPropertyGrid.ReadOnly = false;
|
this.MainPropertyGrid.ReadOnly = false;
|
||||||
this.MainPropertyGrid.Size = new System.Drawing.Size(499, 468);
|
this.MainPropertyGrid.Size = new System.Drawing.Size(487, 436);
|
||||||
this.MainPropertyGrid.TabIndex = 0;
|
this.MainPropertyGrid.TabIndex = 0;
|
||||||
//
|
//
|
||||||
|
// MainTabControl
|
||||||
|
//
|
||||||
|
this.MainTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Left)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
|
this.MainTabControl.Controls.Add(this.DetailsTabPage);
|
||||||
|
this.MainTabControl.Controls.Add(this.XmlTabPage);
|
||||||
|
this.MainTabControl.Location = new System.Drawing.Point(2, 3);
|
||||||
|
this.MainTabControl.Name = "MainTabControl";
|
||||||
|
this.MainTabControl.SelectedIndex = 0;
|
||||||
|
this.MainTabControl.Size = new System.Drawing.Size(759, 468);
|
||||||
|
this.MainTabControl.TabIndex = 2;
|
||||||
|
this.MainTabControl.SelectedIndexChanged += new System.EventHandler(this.MainTabControl_SelectedIndexChanged);
|
||||||
|
//
|
||||||
|
// DetailsTabPage
|
||||||
|
//
|
||||||
|
this.DetailsTabPage.Controls.Add(this.splitContainer1);
|
||||||
|
this.DetailsTabPage.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.DetailsTabPage.Name = "DetailsTabPage";
|
||||||
|
this.DetailsTabPage.Size = new System.Drawing.Size(751, 442);
|
||||||
|
this.DetailsTabPage.TabIndex = 0;
|
||||||
|
this.DetailsTabPage.Text = "Details";
|
||||||
|
this.DetailsTabPage.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// XmlTabPage
|
||||||
|
//
|
||||||
|
this.XmlTabPage.Controls.Add(this.XmlTextBox);
|
||||||
|
this.XmlTabPage.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.XmlTabPage.Name = "XmlTabPage";
|
||||||
|
this.XmlTabPage.Size = new System.Drawing.Size(751, 442);
|
||||||
|
this.XmlTabPage.TabIndex = 1;
|
||||||
|
this.XmlTabPage.Text = "XML";
|
||||||
|
this.XmlTabPage.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// XmlTextBox
|
||||||
|
//
|
||||||
|
this.XmlTextBox.AutoCompleteBracketsList = new char[] {
|
||||||
|
'(',
|
||||||
|
')',
|
||||||
|
'{',
|
||||||
|
'}',
|
||||||
|
'[',
|
||||||
|
']',
|
||||||
|
'\"',
|
||||||
|
'\"',
|
||||||
|
'\'',
|
||||||
|
'\''};
|
||||||
|
this.XmlTextBox.AutoIndentChars = false;
|
||||||
|
this.XmlTextBox.AutoIndentCharsPatterns = "";
|
||||||
|
this.XmlTextBox.AutoIndentExistingLines = false;
|
||||||
|
this.XmlTextBox.AutoScrollMinSize = new System.Drawing.Size(27, 14);
|
||||||
|
this.XmlTextBox.BackBrush = null;
|
||||||
|
this.XmlTextBox.CharHeight = 14;
|
||||||
|
this.XmlTextBox.CharWidth = 8;
|
||||||
|
this.XmlTextBox.CommentPrefix = null;
|
||||||
|
this.XmlTextBox.Cursor = System.Windows.Forms.Cursors.IBeam;
|
||||||
|
this.XmlTextBox.DelayedEventsInterval = 1;
|
||||||
|
this.XmlTextBox.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
|
||||||
|
this.XmlTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.XmlTextBox.Font = new System.Drawing.Font("Courier New", 9.75F);
|
||||||
|
this.XmlTextBox.IsReplaceMode = false;
|
||||||
|
this.XmlTextBox.Language = FastColoredTextBoxNS.Language.XML;
|
||||||
|
this.XmlTextBox.LeftBracket = '<';
|
||||||
|
this.XmlTextBox.LeftBracket2 = '(';
|
||||||
|
this.XmlTextBox.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.XmlTextBox.Name = "XmlTextBox";
|
||||||
|
this.XmlTextBox.Paddings = new System.Windows.Forms.Padding(0);
|
||||||
|
this.XmlTextBox.RightBracket = '>';
|
||||||
|
this.XmlTextBox.RightBracket2 = ')';
|
||||||
|
this.XmlTextBox.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
|
||||||
|
this.XmlTextBox.ServiceColors = ((FastColoredTextBoxNS.ServiceColors)(resources.GetObject("XmlTextBox.ServiceColors")));
|
||||||
|
this.XmlTextBox.Size = new System.Drawing.Size(751, 442);
|
||||||
|
this.XmlTextBox.TabIndex = 1;
|
||||||
|
this.XmlTextBox.Zoom = 100;
|
||||||
|
this.XmlTextBox.TextChanged += new System.EventHandler<FastColoredTextBoxNS.TextChangedEventArgs>(this.XmlTextBox_TextChanged);
|
||||||
|
this.XmlTextBox.VisibleRangeChangedDelayed += new System.EventHandler(this.XmlTextBox_VisibleRangeChangedDelayed);
|
||||||
|
//
|
||||||
// YcdForm
|
// YcdForm
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.ClientSize = new System.Drawing.Size(763, 474);
|
this.ClientSize = new System.Drawing.Size(763, 474);
|
||||||
this.Controls.Add(this.splitContainer1);
|
this.Controls.Add(this.MainTabControl);
|
||||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
this.Name = "YcdForm";
|
this.Name = "YcdForm";
|
||||||
this.Text = "Clip Dictionary Inspector - CodeWalker by dexyfex";
|
this.Text = "Clip Dictionary Inspector - CodeWalker by dexyfex";
|
||||||
@ -114,6 +200,10 @@
|
|||||||
this.splitContainer1.Panel2.ResumeLayout(false);
|
this.splitContainer1.Panel2.ResumeLayout(false);
|
||||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
|
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
|
||||||
this.splitContainer1.ResumeLayout(false);
|
this.splitContainer1.ResumeLayout(false);
|
||||||
|
this.MainTabControl.ResumeLayout(false);
|
||||||
|
this.DetailsTabPage.ResumeLayout(false);
|
||||||
|
this.XmlTabPage.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.XmlTextBox)).EndInit();
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -123,5 +213,9 @@
|
|||||||
private System.Windows.Forms.ListView MainListView;
|
private System.Windows.Forms.ListView MainListView;
|
||||||
private System.Windows.Forms.ColumnHeader columnHeader1;
|
private System.Windows.Forms.ColumnHeader columnHeader1;
|
||||||
private WinForms.ReadOnlyPropertyGrid MainPropertyGrid;
|
private WinForms.ReadOnlyPropertyGrid MainPropertyGrid;
|
||||||
|
private System.Windows.Forms.TabControl MainTabControl;
|
||||||
|
private System.Windows.Forms.TabPage DetailsTabPage;
|
||||||
|
private System.Windows.Forms.TabPage XmlTabPage;
|
||||||
|
private FastColoredTextBoxNS.FastColoredTextBox XmlTextBox;
|
||||||
}
|
}
|
||||||
}
|
}
|
132
Forms/YcdForm.cs
132
Forms/YcdForm.cs
@ -1,4 +1,5 @@
|
|||||||
using CodeWalker.GameFiles;
|
using CodeWalker.GameFiles;
|
||||||
|
using FastColoredTextBoxNS;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
@ -29,6 +30,8 @@ namespace CodeWalker.Forms
|
|||||||
}
|
}
|
||||||
public string FilePath { get; set; }
|
public string FilePath { get; set; }
|
||||||
|
|
||||||
|
private bool LoadingXml = false;
|
||||||
|
private bool DelayHighlight = false;
|
||||||
|
|
||||||
|
|
||||||
public YcdForm()
|
public YcdForm()
|
||||||
@ -43,30 +46,7 @@ namespace CodeWalker.Forms
|
|||||||
|
|
||||||
private void ExportOnim_Click(object sender, EventArgs e)
|
private void ExportOnim_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (MainListView.SelectedItems[0].Tag is Animation anim)
|
|
||||||
{
|
|
||||||
var saveFileDialog = new SaveFileDialog();
|
|
||||||
|
|
||||||
string newfn = $"{Path.GetFileNameWithoutExtension(Ycd.Name)}_{MainListView.SelectedItems[0].Text}.onim";
|
|
||||||
|
|
||||||
saveFileDialog.FileName = newfn;
|
|
||||||
if (saveFileDialog.ShowDialog() == DialogResult.OK)
|
|
||||||
{
|
|
||||||
string path = saveFileDialog.FileName;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (var file = File.OpenWrite(path))
|
|
||||||
{
|
|
||||||
Ycd.SaveOpenFormatsAnimation(anim, file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show("Error saving file " + path + ":\n" + ex.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateFormTitle()
|
private void UpdateFormTitle()
|
||||||
@ -74,6 +54,49 @@ namespace CodeWalker.Forms
|
|||||||
Text = fileName + " - Clip Dictionary Inspector - CodeWalker by dexyfex";
|
Text = fileName + " - Clip Dictionary Inspector - CodeWalker by dexyfex";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateXmlTextBox(string xml)
|
||||||
|
{
|
||||||
|
LoadingXml = true;
|
||||||
|
XmlTextBox.Text = "";
|
||||||
|
XmlTextBox.Language = Language.XML;
|
||||||
|
DelayHighlight = false;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(xml))
|
||||||
|
{
|
||||||
|
LoadingXml = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//if (xml.Length > (1048576 * 5))
|
||||||
|
//{
|
||||||
|
// XmlTextBox.Language = Language.Custom;
|
||||||
|
// XmlTextBox.Text = "[XML size > 10MB - Not shown due to performance limitations - Please use an external viewer for this file.]";
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
if (xml.Length > (1024 * 512))
|
||||||
|
{
|
||||||
|
XmlTextBox.Language = Language.Custom;
|
||||||
|
DelayHighlight = true;
|
||||||
|
}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// XmlTextBox.Language = Language.XML;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
Cursor = Cursors.WaitCursor;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
XmlTextBox.Text = xml;
|
||||||
|
//XmlTextBox.IsChanged = false;
|
||||||
|
XmlTextBox.ClearUndo();
|
||||||
|
|
||||||
|
Cursor = Cursors.Default;
|
||||||
|
LoadingXml = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void LoadYcd(YcdFile ycd)
|
public void LoadYcd(YcdFile ycd)
|
||||||
{
|
{
|
||||||
@ -120,8 +143,60 @@ namespace CodeWalker.Forms
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LoadXml()
|
||||||
|
{
|
||||||
|
if (Ycd != null)
|
||||||
|
{
|
||||||
|
var xml = YcdXml.GetXml(Ycd);
|
||||||
|
UpdateXmlTextBox(xml);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void HTMLSyntaxHighlight(Range range)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Style BlueStyle = new TextStyle(Brushes.Blue, null, FontStyle.Regular);
|
||||||
|
Style RedStyle = new TextStyle(Brushes.Red, null, FontStyle.Regular);
|
||||||
|
Style MaroonStyle = new TextStyle(Brushes.Maroon, null, FontStyle.Regular);
|
||||||
|
|
||||||
|
//clear style of changed range
|
||||||
|
range.ClearStyle(BlueStyle, MaroonStyle, RedStyle);
|
||||||
|
//tag brackets highlighting
|
||||||
|
range.SetStyle(BlueStyle, @"<|/>|</|>");
|
||||||
|
//tag name
|
||||||
|
range.SetStyle(MaroonStyle, @"<(?<range>[!\w]+)");
|
||||||
|
//end of tag
|
||||||
|
range.SetStyle(MaroonStyle, @"</(?<range>\w+)>");
|
||||||
|
//attributes
|
||||||
|
range.SetStyle(RedStyle, @"(?<range>\S+?)='[^']*'|(?<range>\S+)=""[^""]*""|(?<range>\S+)=\S+");
|
||||||
|
//attribute values
|
||||||
|
range.SetStyle(BlueStyle, @"\S+?=(?<range>'[^']*')|\S+=(?<range>""[^""]*"")|\S+=(?<range>\S+)");
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void XmlTextBox_VisibleRangeChangedDelayed(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//this approach is much faster to load, but no outlining is available
|
||||||
|
|
||||||
|
//highlight only visible area of text
|
||||||
|
if (DelayHighlight)
|
||||||
|
{
|
||||||
|
HTMLSyntaxHighlight(XmlTextBox.VisibleRange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void XmlTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!LoadingXml)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void MainListView_SelectedIndexChanged(object sender, EventArgs e)
|
private void MainListView_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (MainListView.SelectedItems.Count == 1)
|
if (MainListView.SelectedItems.Count == 1)
|
||||||
@ -143,5 +218,16 @@ namespace CodeWalker.Forms
|
|||||||
//MainPropertyGrid.SelectedObject = null;
|
//MainPropertyGrid.SelectedObject = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void MainTabControl_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (MainTabControl.SelectedTab == XmlTabPage)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(XmlTextBox.Text))
|
||||||
|
{
|
||||||
|
LoadXml();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -117,6 +117,24 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
|
<data name="XmlTextBox.ServiceColors" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAFdGYXN0Q29sb3JlZFRleHRCb3gsIFZlcnNpb249Mi4xNi4yNC4w
|
||||||
|
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWZiOGFhMTJiOTk0ZWY2MWIMAwAAAFFTeXN0
|
||||||
|
ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2Vu
|
||||||
|
PWIwM2Y1ZjdmMTFkNTBhM2EFAQAAACJGYXN0Q29sb3JlZFRleHRCb3hOUy5TZXJ2aWNlQ29sb3JzBgAA
|
||||||
|
ACg8Q29sbGFwc2VNYXJrZXJGb3JlQ29sb3I+a19fQmFja2luZ0ZpZWxkKDxDb2xsYXBzZU1hcmtlckJh
|
||||||
|
Y2tDb2xvcj5rX19CYWNraW5nRmllbGQqPENvbGxhcHNlTWFya2VyQm9yZGVyQ29sb3I+a19fQmFja2lu
|
||||||
|
Z0ZpZWxkJjxFeHBhbmRNYXJrZXJGb3JlQ29sb3I+a19fQmFja2luZ0ZpZWxkJjxFeHBhbmRNYXJrZXJC
|
||||||
|
YWNrQ29sb3I+a19fQmFja2luZ0ZpZWxkKDxFeHBhbmRNYXJrZXJCb3JkZXJDb2xvcj5rX19CYWNraW5n
|
||||||
|
RmllbGQEBAQEBAQUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAFFN5c3RlbS5EcmF3aW5nLkNvbG9yAwAA
|
||||||
|
ABRTeXN0ZW0uRHJhd2luZy5Db2xvcgMAAAAUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAFFN5c3RlbS5E
|
||||||
|
cmF3aW5nLkNvbG9yAwAAABRTeXN0ZW0uRHJhd2luZy5Db2xvcgMAAAACAAAABfz///8UU3lzdGVtLkRy
|
||||||
|
YXdpbmcuQ29sb3IEAAAABG5hbWUFdmFsdWUKa25vd25Db2xvcgVzdGF0ZQEAAAAJBwcDAAAACgAAAAAA
|
||||||
|
AAAAlgABAAH7/////P///woAAAAAAAAAAKQAAQAB+v////z///8KAAAAAAAAAACWAAEAAfn////8////
|
||||||
|
CgAAAAAAAAAATgABAAH4/////P///woAAAAAAAAAAKQAAQAB9/////z///8KAAAAAAAAAACWAAEACw==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
|
14
Peds/PedsForm.Designer.cs
generated
14
Peds/PedsForm.Designer.cs
generated
@ -108,6 +108,7 @@
|
|||||||
this.label4 = new System.Windows.Forms.Label();
|
this.label4 = new System.Windows.Forms.Label();
|
||||||
this.ToolsTabControl = new System.Windows.Forms.TabControl();
|
this.ToolsTabControl = new System.Windows.Forms.TabControl();
|
||||||
this.ToolsPanel = new System.Windows.Forms.Panel();
|
this.ToolsPanel = new System.Windows.Forms.Panel();
|
||||||
|
this.EnableRootMotionCheckBox = new System.Windows.Forms.CheckBox();
|
||||||
this.ConsolePanel.SuspendLayout();
|
this.ConsolePanel.SuspendLayout();
|
||||||
this.ToolsOptionsTabPage.SuspendLayout();
|
this.ToolsOptionsTabPage.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.TimeOfDayTrackBar)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.TimeOfDayTrackBar)).BeginInit();
|
||||||
@ -656,6 +657,7 @@
|
|||||||
//
|
//
|
||||||
// ToolsPedTabPage
|
// ToolsPedTabPage
|
||||||
//
|
//
|
||||||
|
this.ToolsPedTabPage.Controls.Add(this.EnableRootMotionCheckBox);
|
||||||
this.ToolsPedTabPage.Controls.Add(this.label23);
|
this.ToolsPedTabPage.Controls.Add(this.label23);
|
||||||
this.ToolsPedTabPage.Controls.Add(this.label22);
|
this.ToolsPedTabPage.Controls.Add(this.label22);
|
||||||
this.ToolsPedTabPage.Controls.Add(this.ClipComboBox);
|
this.ToolsPedTabPage.Controls.Add(this.ClipComboBox);
|
||||||
@ -1064,6 +1066,17 @@
|
|||||||
this.ToolsPanel.TabIndex = 7;
|
this.ToolsPanel.TabIndex = 7;
|
||||||
this.ToolsPanel.Visible = false;
|
this.ToolsPanel.Visible = false;
|
||||||
//
|
//
|
||||||
|
// EnableRootMotionCheckBox
|
||||||
|
//
|
||||||
|
this.EnableRootMotionCheckBox.AutoSize = true;
|
||||||
|
this.EnableRootMotionCheckBox.Location = new System.Drawing.Point(54, 503);
|
||||||
|
this.EnableRootMotionCheckBox.Name = "EnableRootMotionCheckBox";
|
||||||
|
this.EnableRootMotionCheckBox.Size = new System.Drawing.Size(114, 17);
|
||||||
|
this.EnableRootMotionCheckBox.TabIndex = 32;
|
||||||
|
this.EnableRootMotionCheckBox.Text = "Enable root motion";
|
||||||
|
this.EnableRootMotionCheckBox.UseVisualStyleBackColor = true;
|
||||||
|
this.EnableRootMotionCheckBox.CheckedChanged += new System.EventHandler(this.EnableRootMotionCheckBox_CheckedChanged);
|
||||||
|
//
|
||||||
// PedsForm
|
// PedsForm
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
@ -1184,5 +1197,6 @@
|
|||||||
private System.Windows.Forms.Label label21;
|
private System.Windows.Forms.Label label21;
|
||||||
private System.Windows.Forms.ComboBox ClipDictComboBox;
|
private System.Windows.Forms.ComboBox ClipDictComboBox;
|
||||||
private System.Windows.Forms.Label label23;
|
private System.Windows.Forms.Label label23;
|
||||||
|
private System.Windows.Forms.CheckBox EnableRootMotionCheckBox;
|
||||||
}
|
}
|
||||||
}
|
}
|
142
Peds/PedsForm.cs
142
Peds/PedsForm.cs
@ -92,6 +92,7 @@ namespace CodeWalker.Peds
|
|||||||
public ClipMapEntry AnimClip { get; set; } = null;
|
public ClipMapEntry AnimClip { get; set; } = null;
|
||||||
public Drawable[] Drawables { get; set; } = new Drawable[12];
|
public Drawable[] Drawables { get; set; } = new Drawable[12];
|
||||||
public Texture[] Textures { get; set; } = new Texture[12];
|
public Texture[] Textures { get; set; } = new Texture[12];
|
||||||
|
public bool EnableRootMotion { get; set; } = false; //used to toggle whether or not to include root motion when playing animations
|
||||||
}
|
}
|
||||||
|
|
||||||
PedSelection SelectedPed = new PedSelection();
|
PedSelection SelectedPed = new PedSelection();
|
||||||
@ -971,6 +972,80 @@ namespace CodeWalker.Peds
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void LoadClipDict(string name)
|
||||||
|
{
|
||||||
|
var ycdhash = JenkHash.GenHash(name.ToLowerInvariant());
|
||||||
|
var ycd = GameFileCache.GetYcd(ycdhash);
|
||||||
|
while ((ycd != null) && (!ycd.Loaded))
|
||||||
|
{
|
||||||
|
Thread.Sleep(20);//kinda hacky
|
||||||
|
ycd = GameFileCache.GetYcd(ycdhash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//if (ycd != null)
|
||||||
|
//{
|
||||||
|
// ////// TESTING XML CONVERSIONS
|
||||||
|
// var xml = YcdXml.GetXml(ycd);
|
||||||
|
// var ycd2 = XmlYcd.GetYcd(xml);
|
||||||
|
// var data = ycd2.Save();
|
||||||
|
// var ycd3 = new YcdFile();
|
||||||
|
// RpfFile.LoadResourceFile(ycd3, data, 46);
|
||||||
|
// //var xml2 = YcdXml.GetXml(ycd3);
|
||||||
|
// //if (xml != xml2)
|
||||||
|
// //{ }
|
||||||
|
// ycd = ycd3;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SelectedPed.Ycd = ycd;
|
||||||
|
|
||||||
|
ClipComboBox.Items.Clear();
|
||||||
|
ClipComboBox.Items.Add("");
|
||||||
|
|
||||||
|
if (ycd?.ClipMapEntries == null)
|
||||||
|
{
|
||||||
|
ClipComboBox.SelectedIndex = 0;
|
||||||
|
SelectedPed.AnimClip = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<string> items = new List<string>();
|
||||||
|
|
||||||
|
foreach (var cme in ycd.ClipMapEntries)
|
||||||
|
{
|
||||||
|
var animclip = cme.Clip as ClipAnimation;
|
||||||
|
if (animclip != null)
|
||||||
|
{
|
||||||
|
items.Add(animclip.ShortName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var animcliplist = cme.Clip as ClipAnimationList;
|
||||||
|
if (animcliplist?.Animations?.Data != null)
|
||||||
|
{
|
||||||
|
items.Add(animcliplist.ShortName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
items.Sort();
|
||||||
|
foreach (var item in items)
|
||||||
|
{
|
||||||
|
ClipComboBox.Items.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelectClip(string name)
|
||||||
|
{
|
||||||
|
MetaHash cliphash = JenkHash.GenHash(name);
|
||||||
|
ClipMapEntry cme = null;
|
||||||
|
SelectedPed.Ycd?.ClipMap?.TryGetValue(cliphash, out cme);
|
||||||
|
SelectedPed.AnimClip = cme;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1193,6 +1268,10 @@ namespace CodeWalker.Peds
|
|||||||
|
|
||||||
var td = SelectedPed.Ytd?.TextureDict;
|
var td = SelectedPed.Ytd?.TextureDict;
|
||||||
var ac = SelectedPed.AnimClip;
|
var ac = SelectedPed.AnimClip;
|
||||||
|
if (ac != null)
|
||||||
|
{
|
||||||
|
ac.EnableRootMotion = SelectedPed.EnableRootMotion;
|
||||||
|
}
|
||||||
|
|
||||||
var skel = SelectedPed.Yft?.Fragment?.Drawable?.Skeleton;
|
var skel = SelectedPed.Yft?.Fragment?.Drawable?.Skeleton;
|
||||||
if (skel != null)
|
if (skel != null)
|
||||||
@ -1788,69 +1867,22 @@ namespace CodeWalker.Peds
|
|||||||
|
|
||||||
private void ClipDictComboBox_TextChanged(object sender, EventArgs e)
|
private void ClipDictComboBox_TextChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
LoadClipDict(ClipDictComboBox.Text);
|
||||||
var ycdhash = JenkHash.GenHash(ClipDictComboBox.Text.ToLowerInvariant());
|
|
||||||
var ycd = GameFileCache.GetYcd(ycdhash);
|
|
||||||
while ((ycd != null) && (!ycd.Loaded))
|
|
||||||
{
|
|
||||||
Thread.Sleep(20);//kinda hacky
|
|
||||||
ycd = GameFileCache.GetYcd(ycdhash);
|
|
||||||
}
|
|
||||||
|
|
||||||
SelectedPed.Ycd = ycd;
|
|
||||||
|
|
||||||
ClipComboBox.Items.Clear();
|
|
||||||
ClipComboBox.Items.Add("");
|
|
||||||
|
|
||||||
if (ycd?.ClipMapEntries == null)
|
|
||||||
{
|
|
||||||
ClipComboBox.SelectedIndex = 0;
|
|
||||||
SelectedPed.AnimClip = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<string> items = new List<string>();
|
|
||||||
|
|
||||||
foreach (var cme in ycd.ClipMapEntries)
|
|
||||||
{
|
|
||||||
var animclip = cme.Clip as ClipAnimation;
|
|
||||||
if (animclip != null)
|
|
||||||
{
|
|
||||||
items.Add(animclip.ShortName);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var animcliplist = cme.Clip as ClipAnimationList;
|
|
||||||
if (animcliplist?.Animations?.Data != null)
|
|
||||||
{
|
|
||||||
items.Add(animcliplist.ShortName);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
items.Sort();
|
|
||||||
foreach (var item in items)
|
|
||||||
{
|
|
||||||
ClipComboBox.Items.Add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClipComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
private void ClipComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
SelectClip(ClipComboBox.Text);
|
||||||
var name = ClipComboBox.Text;
|
|
||||||
|
|
||||||
MetaHash cliphash = JenkHash.GenHash(name);
|
|
||||||
ClipMapEntry cme = null;
|
|
||||||
SelectedPed.Ycd?.ClipMap?.TryGetValue(cliphash, out cme);
|
|
||||||
SelectedPed.AnimClip = cme;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClipComboBox_TextChanged(object sender, EventArgs e)
|
private void ClipComboBox_TextChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
ClipComboBox_SelectedIndexChanged(sender, e);
|
SelectClip(ClipComboBox.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnableRootMotionCheckBox_CheckedChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
SelectedPed.EnableRootMotion = EnableRootMotionCheckBox.Checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,8 @@ namespace CodeWalker.Rendering
|
|||||||
|
|
||||||
public Matrix3_s[] BoneTransforms;
|
public Matrix3_s[] BoneTransforms;
|
||||||
public List<Bone> Bones;
|
public List<Bone> Bones;
|
||||||
|
public bool EnableRootMotion = false; //used to toggle whether or not to include root motion when playing animations
|
||||||
|
|
||||||
|
|
||||||
public override void Init(DrawableBase drawable)
|
public override void Init(DrawableBase drawable)
|
||||||
{
|
{
|
||||||
@ -385,39 +387,39 @@ namespace CodeWalker.Rendering
|
|||||||
BoneTransforms[i] = bt;
|
BoneTransforms[i] = bt;
|
||||||
}
|
}
|
||||||
|
|
||||||
//var drawbl = Key;
|
var drawbl = Key;
|
||||||
//if (AllModels == null) return;
|
if (AllModels == null) return;
|
||||||
//for (int i = 0; i < AllModels.Length; i++)
|
for (int i = 0; i < AllModels.Length; i++)
|
||||||
//{
|
{
|
||||||
// var model = AllModels[i];
|
var model = AllModels[i];
|
||||||
// if (model?.Geometries == null) continue;
|
if (model?.Geometries == null) continue;
|
||||||
// for (int g = 0; g < model.Geometries.Length; g++)
|
for (int g = 0; g < model.Geometries.Length; g++)
|
||||||
// {
|
{
|
||||||
// var geom = model.Geometries[g];
|
var geom = model.Geometries[g];
|
||||||
// var boneids = geom?.DrawableGeom?.BoneIds;
|
var boneids = geom?.DrawableGeom?.BoneIds;
|
||||||
// if (boneids == null) continue;
|
if (boneids == null) continue;
|
||||||
// if (boneids.Length != Bones.Count)
|
if (boneids.Length != Bones.Count)
|
||||||
// {
|
{
|
||||||
// var idc = boneids.Length;
|
var idc = boneids.Length;
|
||||||
// if (geom.BoneTransforms == null)
|
if (geom.BoneTransforms == null)
|
||||||
// {
|
{
|
||||||
// geom.BoneTransforms = new Matrix3_s[idc];
|
geom.BoneTransforms = new Matrix3_s[idc];
|
||||||
// }
|
}
|
||||||
// for (int b = 0; b < idc; b++)
|
for (int b = 0; b < idc; b++)
|
||||||
// {
|
{
|
||||||
// var id = boneids[b];
|
var id = boneids[b];
|
||||||
// if (id < BoneTransforms.Length)
|
if (id < BoneTransforms.Length)
|
||||||
// {
|
{
|
||||||
// geom.BoneTransforms[b] = BoneTransforms[id];
|
geom.BoneTransforms[b] = BoneTransforms[id];
|
||||||
// if (id != b)
|
if (id != b)
|
||||||
// { }
|
{ }
|
||||||
// }
|
}
|
||||||
// else
|
else
|
||||||
// { }
|
{ }
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,6 +430,8 @@ namespace CodeWalker.Rendering
|
|||||||
if (CurrentAnimTime == realTime) return;//already updated this!
|
if (CurrentAnimTime == realTime) return;//already updated this!
|
||||||
CurrentAnimTime = realTime;
|
CurrentAnimTime = realTime;
|
||||||
|
|
||||||
|
EnableRootMotion = ClipMapEntry?.EnableRootMotion ?? false;
|
||||||
|
|
||||||
if (ClipMapEntry != null)
|
if (ClipMapEntry != null)
|
||||||
{
|
{
|
||||||
UpdateAnim(ClipMapEntry); //animate skeleton/models
|
UpdateAnim(ClipMapEntry); //animate skeleton/models
|
||||||
@ -451,6 +455,7 @@ namespace CodeWalker.Rendering
|
|||||||
}
|
}
|
||||||
private void UpdateAnim(ClipMapEntry cme)
|
private void UpdateAnim(ClipMapEntry cme)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (cme.Next != null)
|
if (cme.Next != null)
|
||||||
{
|
{
|
||||||
UpdateAnim(cme.Next);
|
UpdateAnim(cme.Next);
|
||||||
@ -545,10 +550,13 @@ namespace CodeWalker.Rendering
|
|||||||
case 5://root motion vector
|
case 5://root motion vector
|
||||||
if (bone.Tag != 0)
|
if (bone.Tag != 0)
|
||||||
{ }
|
{ }
|
||||||
//v0 = aseq.EvaluateVector(f0);
|
if (EnableRootMotion)
|
||||||
//v1 = aseq.EvaluateVector(f1);
|
{
|
||||||
//v = interpolate ? (v0 * ialpha) + (v1 * falpha) : v0;
|
v0 = aseq.EvaluateVector(f0);
|
||||||
//bone.AnimTranslation += v.XYZ();
|
v1 = aseq.EvaluateVector(f1);
|
||||||
|
v = interpolate ? (v0 * ialpha) + (v1 * falpha) : v0;
|
||||||
|
bone.AnimTranslation += v.XYZ();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 6://quaternion... root rotation?
|
case 6://quaternion... root rotation?
|
||||||
if (bone.Tag != 0)
|
if (bone.Tag != 0)
|
||||||
@ -574,6 +582,8 @@ namespace CodeWalker.Rendering
|
|||||||
{ }
|
{ }
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if (bone.Tag != 0)
|
||||||
|
{ }
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -832,7 +842,7 @@ namespace CodeWalker.Rendering
|
|||||||
public bool isHair = false;
|
public bool isHair = false;
|
||||||
public bool disableRendering = false;
|
public bool disableRendering = false;
|
||||||
|
|
||||||
//public Matrix3_s[] BoneTransforms = null;
|
public Matrix3_s[] BoneTransforms = null;
|
||||||
|
|
||||||
public static ShaderParamNames[] GetTextureSamplerList()
|
public static ShaderParamNames[] GetTextureSamplerList()
|
||||||
{
|
{
|
||||||
|
@ -801,11 +801,11 @@ namespace CodeWalker.Rendering
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//if (geom.BoneTransforms != null)
|
if (geom.BoneTransforms != null)
|
||||||
//{
|
{
|
||||||
// SetBoneMatrices(context, geom.BoneTransforms);
|
SetBoneMatrices(context, geom.BoneTransforms);
|
||||||
// defaultBoneMatricesBound = false;
|
defaultBoneMatricesBound = false;
|
||||||
//}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,11 +358,11 @@ namespace CodeWalker.Rendering
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//if (geom.BoneTransforms != null)
|
if (geom.BoneTransforms != null)
|
||||||
//{
|
{
|
||||||
// SetBoneMatrices(context, geom.BoneTransforms);
|
SetBoneMatrices(context, geom.BoneTransforms);
|
||||||
// defaultBoneMatricesBound = false;
|
defaultBoneMatricesBound = false;
|
||||||
//}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user