FBX importer v1, fix for YNDs DLC loading, fix for renamed NG encrypted RPFs, RelFile MetaNames addition

This commit is contained in:
dexy 2019-03-20 21:21:47 +11:00
parent decc3dccb4
commit bc1efebe5c
23 changed files with 3876 additions and 183 deletions

View File

@ -123,6 +123,8 @@
</Compile> </Compile>
<Compile Include="Utils\BoundingBoxes.cs" /> <Compile Include="Utils\BoundingBoxes.cs" />
<Compile Include="Utils\Cache.cs" /> <Compile Include="Utils\Cache.cs" />
<Compile Include="Utils\Fbx.cs" />
<Compile Include="Utils\FbxConverter.cs" />
<Compile Include="Utils\Matrices.cs" /> <Compile Include="Utils\Matrices.cs" />
<Compile Include="Utils\Quaternions.cs" /> <Compile Include="Utils\Quaternions.cs" />
<Compile Include="Utils\Utils.cs" /> <Compile Include="Utils\Utils.cs" />

View File

@ -4932,7 +4932,7 @@ namespace CodeWalker.GameFiles
VehicleEngine = 4, VehicleEngine = 4,
Entity = 5, //not sure about this Entity = 5, //not sure about this
StaticEmitter = 6,//radio emitter? StaticEmitter = 6,//radio emitter?
Prop = 7,//prop? eg. fan, radar Prop = 7,//prop? entity emitter? eg. fan, radar
Helicopter = 8, Helicopter = 8,
Unk9 = 9, Unk9 = 9,
Unk11 = 11, //contains reference to Unk12 Unk11 = 11, //contains reference to Unk12

View File

@ -1013,6 +1013,8 @@ namespace CodeWalker.GameFiles
// YmtFile ymt = GetFile<YmtFile>(entry); // YmtFile ymt = GetFile<YmtFile>(entry);
//} //}
if (entry.Name.EndsWith(".ymf"))// || entry.Name.EndsWith(".ymt")) if (entry.Name.EndsWith(".ymf"))// || entry.Name.EndsWith(".ymt"))
{
try
{ {
UpdateStatus(string.Format(entry.Path)); UpdateStatus(string.Format(entry.Path));
YmfFile ymffile = RpfMan.GetFile<YmfFile>(entry); YmfFile ymffile = RpfMan.GetFile<YmfFile>(entry);
@ -1043,6 +1045,12 @@ namespace CodeWalker.GameFiles
} }
} }
catch (Exception ex)
{
string errstr = entry.Path + "\n" + ex.ToString();
ErrorLog(errstr);
}
}
} }
@ -2363,9 +2371,6 @@ namespace CodeWalker.GameFiles
{ {
UpdateStatus("Testing Audio REL files"); UpdateStatus("Testing Audio REL files");
StringBuilder sb = new StringBuilder();
StringBuilder sbh = new StringBuilder();
StringBuilder sbi = new StringBuilder();
bool savetest = true; bool savetest = true;
bool xmltest = true; bool xmltest = true;
@ -2386,82 +2391,6 @@ namespace CodeWalker.GameFiles
RpfMan.LoadFile(rel, rfe); RpfMan.LoadFile(rel, rfe);
#region string building
if (rel.NameTable == null)
{
sb.AppendLine(rfe.Path + ": no strings found");
}
else
{
sb.AppendLine(rfe.Path + ": " + rel.NameTable.Length.ToString() + " strings found:");
foreach (string str in rel.NameTable)
{
sb.AppendLine(str);
}
}
if (rel.IndexStrings != null)
{
sb.AppendLine("Config-specific:");
foreach (var unk in rel.IndexStrings)
{
sb.AppendLine(unk.ToString());
}
}
if (rel.IndexHashes != null)
{
sbh.AppendLine(rfe.Path + ": " + rel.IndexHashes.Length.ToString() + " entries:");
foreach (var unk in rel.IndexHashes)
{
sbh.Append(unk.Name.Hash.ToString("X8"));
string strval;
if (JenkIndex.Index.TryGetValue(unk.Name, out strval))
{
sbh.Append(" - ");
sbh.Append(strval);
}
sbh.AppendLine();
//sbh.AppendLine(unk.ToString());
}
sbh.AppendLine();
}
if (rel.HashTable != null)
{
sbh.AppendLine(rfe.Path + ": " + rel.HashTable.Length.ToString() + " Hashes1:");
foreach (var unk in rel.HashTable)
{
sbh.Append(unk.Hash.ToString("X8"));
string strval;
if (JenkIndex.Index.TryGetValue(unk, out strval))
{
sbh.Append(" - ");
sbh.Append(strval);
}
sbh.AppendLine();
}
sbh.AppendLine();
}
if (rel.PackTable != null)
{
sbh.AppendLine(rfe.Path + ": " + rel.PackTable.Length.ToString() + " Hashes2:");
foreach (var unk in rel.PackTable)
{
sbh.Append(unk.Hash.ToString("X8"));
string strval;
if (JenkIndex.Index.TryGetValue(unk, out strval))
{
sbh.Append(" - ");
sbh.Append(strval);
}
sbh.AppendLine();
}
sbh.AppendLine();
}
sb.AppendLine();
#endregion
byte[] data; byte[] data;
@ -2540,29 +2469,12 @@ namespace CodeWalker.GameFiles
} }
//sbi.Clear();
//foreach (var rd in rel.RelDatas)
//{
// sbi.AppendLine(new FlagsUint(rd.NameHash).Bin);
//}
//string indexbinstr = sbi.ToString();
} }
} }
} }
//int ctot = Dat151RelData.TotCount;
//StringBuilder sbp = new StringBuilder();
//foreach (string s in Dat151RelData.FoundCoords)
//{
// sbp.AppendLine(s);
//}
//string posz = sbp.ToString();
string relstrs = sb.ToString();
string hashstrs = sbh.ToString();
var hashmap = RelFile.HashesMap; var hashmap = RelFile.HashesMap;

View File

@ -3475,6 +3475,7 @@ namespace CodeWalker.GameFiles
silence = 3503773450, //used in game.dat151.rel silence = 3503773450, //used in game.dat151.rel
null_sound = 3817852694, //used in game.dat151.rel null_sound = 3817852694, //used in game.dat151.rel
constant_one = 3454258691, //used in dat .rels
run = 285848937, //used in game.dat151.rel run = 285848937, //used in game.dat151.rel
cop_dispatch_interaction_settings = 778268174, //used in game.dat151.rel cop_dispatch_interaction_settings = 778268174, //used in game.dat151.rel

View File

@ -775,8 +775,7 @@ namespace CodeWalker.GameFiles
} }
} }
[TC(typeof(EXP))] [TC(typeof(EXP))] public struct BoundMaterial_s
public struct BoundMaterial_s
{ {
public uint Data1; public uint Data1;

View File

@ -122,13 +122,14 @@ namespace CodeWalker.GameFiles
public MetaHash Name { get; set; } //530103687, 2401522793, 1912906641 public MetaHash Name { get; set; } //530103687, 2401522793, 1912906641
public uint Unknown_Ch { get; set; } // 0x00000000 public uint Unknown_Ch { get; set; } // 0x00000000
public byte ParameterCount { get; set; } public byte ParameterCount { get; set; }
public byte Unknown_11h { get; set; } // 2, 0, public byte RenderBucket { get; set; } // 2, 0,
public ushort Unknown_12h { get; set; } // 32768 public ushort Unknown_12h { get; set; } // 32768 HasComment?
public uint Unknown_14h { get; set; } //10485872, 17826000, 26214720 public ushort ParameterSize { get; set; } //112, 208, 320 (with 16h) 10485872, 17826000, 26214720
public ushort ParameterDataSize { get; set; } //160, 272, 400
public MetaHash FileName { get; set; } //2918136469, 2635608835, 2247429097 public MetaHash FileName { get; set; } //2918136469, 2635608835, 2247429097
public uint Unknown_1Ch { get; set; } // 0x00000000 public uint Unknown_1Ch { get; set; } // 0x00000000
public uint Unknown_20h { get; set; } //65284, 65281 public uint RenderBucketMask { get; set; } //65284, 65281 DrawBucketMask? (1<<bucket) | 0xFF00
public ushort Unknown_24h { get; set; } //0 public ushort Unknown_24h { get; set; } //0 Instanced?
public byte Unknown_26h { get; set; } //0 public byte Unknown_26h { get; set; } //0
public byte TextureParametersCount { get; set; } public byte TextureParametersCount { get; set; }
public uint Unknown_28h { get; set; } // 0x00000000 public uint Unknown_28h { get; set; } // 0x00000000
@ -149,12 +150,13 @@ namespace CodeWalker.GameFiles
this.Name = new MetaHash(reader.ReadUInt32()); this.Name = new MetaHash(reader.ReadUInt32());
this.Unknown_Ch = reader.ReadUInt32(); this.Unknown_Ch = reader.ReadUInt32();
this.ParameterCount = reader.ReadByte(); this.ParameterCount = reader.ReadByte();
this.Unknown_11h = reader.ReadByte(); this.RenderBucket = reader.ReadByte();
this.Unknown_12h = reader.ReadUInt16(); this.Unknown_12h = reader.ReadUInt16();
this.Unknown_14h = reader.ReadUInt32(); this.ParameterSize = reader.ReadUInt16();
this.ParameterDataSize = reader.ReadUInt16();
this.FileName = new MetaHash(reader.ReadUInt32()); this.FileName = new MetaHash(reader.ReadUInt32());
this.Unknown_1Ch = reader.ReadUInt32(); this.Unknown_1Ch = reader.ReadUInt32();
this.Unknown_20h = reader.ReadUInt32(); this.RenderBucketMask = reader.ReadUInt32();
this.Unknown_24h = reader.ReadUInt16(); this.Unknown_24h = reader.ReadUInt16();
this.Unknown_26h = reader.ReadByte(); this.Unknown_26h = reader.ReadByte();
this.TextureParametersCount = reader.ReadByte(); this.TextureParametersCount = reader.ReadByte();
@ -182,12 +184,13 @@ namespace CodeWalker.GameFiles
writer.Write(this.Name.Hash); writer.Write(this.Name.Hash);
writer.Write(this.Unknown_Ch); writer.Write(this.Unknown_Ch);
writer.Write(this.ParameterCount); writer.Write(this.ParameterCount);
writer.Write(this.Unknown_11h); writer.Write(this.RenderBucket);
writer.Write(this.Unknown_12h); writer.Write(this.Unknown_12h);
writer.Write(this.Unknown_14h); writer.Write(this.ParameterSize);
writer.Write(this.ParameterDataSize);
writer.Write(this.FileName.Hash); writer.Write(this.FileName.Hash);
writer.Write(this.Unknown_1Ch); writer.Write(this.Unknown_1Ch);
writer.Write(this.Unknown_20h); writer.Write(this.RenderBucketMask);
writer.Write(this.Unknown_24h); writer.Write(this.Unknown_24h);
writer.Write(this.Unknown_26h); writer.Write(this.Unknown_26h);
writer.Write(this.TextureParametersCount); writer.Write(this.TextureParametersCount);
@ -299,6 +302,32 @@ namespace CodeWalker.GameFiles
} }
} }
public ushort ParametersSize
{
get
{
ushort size = (ushort)((Parameters?.Length??0) * 16);
foreach (var x in Parameters)
{
size += (ushort)(16 * x.DataType);
}
return size;
}
}
public byte TextureParamsCount
{
get
{
byte c = 0;
foreach (var x in Parameters)
{
if (x.DataType == 0) c++;
}
return c;
}
}
public ShaderParameter[] Parameters { get; set; } public ShaderParameter[] Parameters { get; set; }
public MetaName[] Hashes { get; set; } public MetaName[] Hashes { get; set; }
public int Count { get; set; } public int Count { get; set; }
@ -1049,8 +1078,9 @@ namespace CodeWalker.GameFiles
public uint Unknown_14h { get; set; } // 0x00000000 public uint Unknown_14h { get; set; } // 0x00000000
public ulong BoundsPointer { get; set; } public ulong BoundsPointer { get; set; }
public ulong ShaderMappingPointer { get; set; } public ulong ShaderMappingPointer { get; set; }
public uint Unknown_28h { get; set; } public uint SkeletonBinding { get; set; }//4th byte is bone index, 2nd byte for skin meshes
public uint Unknown_2Ch { get; set; } //First byte is called "Mask" in GIMS EVO, third byte is always equal to GeometriesCount, is it ShaderMappingCount? public ushort RenderMaskFlags { get; set; } //First byte is called "Mask" in GIMS EVO
public ushort GeometriesCount3 { get; set; } //always equal to GeometriesCount, is it ShaderMappingCount?
// reference data // reference data
public ResourcePointerArray64<DrawableGeometry> Geometries { get; set; } public ResourcePointerArray64<DrawableGeometry> Geometries { get; set; }
@ -1116,8 +1146,10 @@ namespace CodeWalker.GameFiles
this.Unknown_14h = reader.ReadUInt32(); this.Unknown_14h = reader.ReadUInt32();
this.BoundsPointer = reader.ReadUInt64(); this.BoundsPointer = reader.ReadUInt64();
this.ShaderMappingPointer = reader.ReadUInt64(); this.ShaderMappingPointer = reader.ReadUInt64();
this.Unknown_28h = reader.ReadUInt32(); this.SkeletonBinding = reader.ReadUInt32();
this.Unknown_2Ch = reader.ReadUInt32(); this.RenderMaskFlags = reader.ReadUInt16();
this.GeometriesCount3 = reader.ReadUInt16();
// read reference data // read reference data
this.Geometries = reader.ReadBlockAt<ResourcePointerArray64<DrawableGeometry>>( this.Geometries = reader.ReadBlockAt<ResourcePointerArray64<DrawableGeometry>>(
@ -1138,6 +1170,7 @@ namespace CodeWalker.GameFiles
this.GeometriesPointer = (ulong)(this.Geometries != null ? this.Geometries.FilePosition : 0); this.GeometriesPointer = (ulong)(this.Geometries != null ? this.Geometries.FilePosition : 0);
this.GeometriesCount1 = (ushort)(this.Geometries != null ? this.Geometries.Count : 0); this.GeometriesCount1 = (ushort)(this.Geometries != null ? this.Geometries.Count : 0);
this.GeometriesCount2 = this.GeometriesCount1;//is this correct? this.GeometriesCount2 = this.GeometriesCount1;//is this correct?
this.GeometriesCount3 = this.GeometriesCount1;//is this correct?
this.BoundsPointer = (ulong)(this.BoundsDataBlock != null ? this.BoundsDataBlock.FilePosition : 0); this.BoundsPointer = (ulong)(this.BoundsDataBlock != null ? this.BoundsDataBlock.FilePosition : 0);
this.ShaderMappingPointer = (ulong)(this.ShaderMappingBlock != null ? this.ShaderMappingBlock.FilePosition : 0); this.ShaderMappingPointer = (ulong)(this.ShaderMappingBlock != null ? this.ShaderMappingBlock.FilePosition : 0);
@ -1151,8 +1184,9 @@ namespace CodeWalker.GameFiles
writer.Write(this.Unknown_14h); writer.Write(this.Unknown_14h);
writer.Write(this.BoundsPointer); writer.Write(this.BoundsPointer);
writer.Write(this.ShaderMappingPointer); writer.Write(this.ShaderMappingPointer);
writer.Write(this.Unknown_28h); writer.Write(this.SkeletonBinding);
writer.Write(this.Unknown_2Ch); writer.Write(this.RenderMaskFlags);
writer.Write(this.GeometriesCount3);
} }
/// <summary> /// <summary>
@ -2137,16 +2171,17 @@ namespace CodeWalker.GameFiles
public ulong DrawableModelsMediumPointer { get; set; } public ulong DrawableModelsMediumPointer { get; set; }
public ulong DrawableModelsLowPointer { get; set; } public ulong DrawableModelsLowPointer { get; set; }
public ulong DrawableModelsVeryLowPointer { get; set; } public ulong DrawableModelsVeryLowPointer { get; set; }
public float LodGroupHigh { get; set; } public float LodDistHigh { get; set; }
public float LodGroupMed { get; set; } public float LodDistMed { get; set; }
public float LodGroupLow { get; set; } public float LodDistLow { get; set; }
public float LodGroupVlow { get; set; } public float LodDistVlow { get; set; }
public uint Unknown_80h { get; set; } public uint Unknown_80h { get; set; }
public uint Unknown_84h { get; set; } public uint Unknown_84h { get; set; }
public uint Unknown_88h { get; set; } public uint Unknown_88h { get; set; }
public uint Unknown_8Ch { get; set; } public uint Unknown_8Ch { get; set; }
public ulong JointsPointer { get; set; } public ulong JointsPointer { get; set; }
public uint Unknown_98h { get; set; } public ushort Unknown_98h { get; set; }
public ushort Unknown_9Ah { get; set; }
public uint Unknown_9Ch { get; set; } // 0x00000000 public uint Unknown_9Ch { get; set; } // 0x00000000
public ulong DrawableModelsXPointer { get; set; } public ulong DrawableModelsXPointer { get; set; }
@ -2207,16 +2242,17 @@ namespace CodeWalker.GameFiles
this.DrawableModelsMediumPointer = reader.ReadUInt64(); this.DrawableModelsMediumPointer = reader.ReadUInt64();
this.DrawableModelsLowPointer = reader.ReadUInt64(); this.DrawableModelsLowPointer = reader.ReadUInt64();
this.DrawableModelsVeryLowPointer = reader.ReadUInt64(); this.DrawableModelsVeryLowPointer = reader.ReadUInt64();
this.LodGroupHigh = reader.ReadSingle(); this.LodDistHigh = reader.ReadSingle();
this.LodGroupMed = reader.ReadSingle(); this.LodDistMed = reader.ReadSingle();
this.LodGroupLow = reader.ReadSingle(); this.LodDistLow = reader.ReadSingle();
this.LodGroupVlow = reader.ReadSingle(); this.LodDistVlow = reader.ReadSingle();
this.Unknown_80h = reader.ReadUInt32(); this.Unknown_80h = reader.ReadUInt32();
this.Unknown_84h = reader.ReadUInt32(); this.Unknown_84h = reader.ReadUInt32();
this.Unknown_88h = reader.ReadUInt32(); this.Unknown_88h = reader.ReadUInt32();
this.Unknown_8Ch = reader.ReadUInt32(); this.Unknown_8Ch = reader.ReadUInt32();
this.JointsPointer = reader.ReadUInt64(); this.JointsPointer = reader.ReadUInt64();
this.Unknown_98h = reader.ReadUInt32(); this.Unknown_98h = reader.ReadUInt16();
this.Unknown_9Ah = reader.ReadUInt16();
this.Unknown_9Ch = reader.ReadUInt32(); this.Unknown_9Ch = reader.ReadUInt32();
this.DrawableModelsXPointer = reader.ReadUInt64(); this.DrawableModelsXPointer = reader.ReadUInt64();
@ -2345,16 +2381,17 @@ namespace CodeWalker.GameFiles
writer.Write(this.DrawableModelsMediumPointer); writer.Write(this.DrawableModelsMediumPointer);
writer.Write(this.DrawableModelsLowPointer); writer.Write(this.DrawableModelsLowPointer);
writer.Write(this.DrawableModelsVeryLowPointer); writer.Write(this.DrawableModelsVeryLowPointer);
writer.Write(this.LodGroupHigh); writer.Write(this.LodDistHigh);
writer.Write(this.LodGroupMed); writer.Write(this.LodDistMed);
writer.Write(this.LodGroupLow); writer.Write(this.LodDistLow);
writer.Write(this.LodGroupVlow); writer.Write(this.LodDistVlow);
writer.Write(this.Unknown_80h); writer.Write(this.Unknown_80h);
writer.Write(this.Unknown_84h); writer.Write(this.Unknown_84h);
writer.Write(this.Unknown_88h); writer.Write(this.Unknown_88h);
writer.Write(this.Unknown_8Ch); writer.Write(this.Unknown_8Ch);
writer.Write(this.JointsPointer); writer.Write(this.JointsPointer);
writer.Write(this.Unknown_98h); writer.Write(this.Unknown_98h);
writer.Write(this.Unknown_9Ah);
writer.Write(this.Unknown_9Ch); writer.Write(this.Unknown_9Ch);
writer.Write(this.DrawableModelsXPointer); writer.Write(this.DrawableModelsXPointer);
} }

View File

@ -1644,7 +1644,7 @@ namespace CodeWalker.GameFiles
//public ResourcePointerArray64<T> Entries; //public ResourcePointerArray64<T> Entries;
public ulong[] data_pointers { get; private set; } public ulong[] data_pointers { get; private set; }
public T[] data_items { get; private set; } public T[] data_items { get; set; }
private ResourcePointerArray64<T> data_block;//used for saving. private ResourcePointerArray64<T> data_block;//used for saving.

View File

@ -74,6 +74,11 @@ namespace CodeWalker.GameFiles
rf.ScanStructure(updateStatus, errorLog); rf.ScanStructure(updateStatus, errorLog);
if (rf.LastException != null) //incase of corrupted rpf (or renamed NG encrypted RPF)
{
continue;
}
AddRpfFile(rf, false, false); AddRpfFile(rf, false, false);
} }
catch (Exception ex) catch (Exception ex)
@ -384,7 +389,7 @@ namespace CodeWalker.GameFiles
} }
if (BuildExtendedJenkIndex) if (BuildExtendedJenkIndex)
{ {
if (nlow.EndsWith(".ydr") || nlow.EndsWith(".yft")) if (nlow.EndsWith(".ydr"))// || nlow.EndsWith(".yft")) //do yft's get lods?
{ {
var sname = nlow.Substring(0, nlow.Length - 4); var sname = nlow.Substring(0, nlow.Length - 4);
JenkIndex.Ensure(sname + "_lod"); JenkIndex.Ensure(sname + "_lod");

1877
CodeWalker.Core/Utils/Fbx.cs Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -432,6 +432,7 @@ namespace CodeWalker.World
} }
foreach (var dlcrpf in GameFileCache.DlcActiveRpfs) //load nodes from current dlc rpfs foreach (var dlcrpf in GameFileCache.DlcActiveRpfs) //load nodes from current dlc rpfs
{ {
if (dlcrpf.Path.StartsWith("x64")) continue; //don't override update.rpf YNDs with x64 ones! *hack
foreach (var rpffile in dlcrpf.Children) foreach (var rpffile in dlcrpf.Children)
{ {
AddRpfYnds(rpffile, yndentries); AddRpfYnds(rpffile, yndentries);

View File

@ -271,6 +271,12 @@
</Compile> </Compile>
<Compile Include="GameFiles\FxcParser.cs" /> <Compile Include="GameFiles\FxcParser.cs" />
<Compile Include="GameFiles\GameFileCacheFactory.cs" /> <Compile Include="GameFiles\GameFileCacheFactory.cs" />
<Compile Include="Tools\ImportFbxForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Tools\ImportFbxForm.Designer.cs">
<DependentUpon>ImportFbxForm.cs</DependentUpon>
</Compile>
<Compile Include="Tools\JenkGenForm.cs"> <Compile Include="Tools\JenkGenForm.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>
@ -640,6 +646,9 @@
<EmbeddedResource Include="Forms\YwrForm.resx"> <EmbeddedResource Include="Forms\YwrForm.resx">
<DependentUpon>YwrForm.cs</DependentUpon> <DependentUpon>YwrForm.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="Tools\ImportFbxForm.resx">
<DependentUpon>ImportFbxForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Tools\JenkGenForm.resx"> <EmbeddedResource Include="Tools\JenkGenForm.resx">
<DependentUpon>JenkGenForm.cs</DependentUpon> <DependentUpon>JenkGenForm.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>

View File

@ -41,6 +41,7 @@
this.EditExtractRawMenu = new System.Windows.Forms.ToolStripMenuItem(); this.EditExtractRawMenu = new System.Windows.Forms.ToolStripMenuItem();
this.EditExtractAllMenu = new System.Windows.Forms.ToolStripMenuItem(); this.EditExtractAllMenu = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
this.EditImportFbxMenu = new System.Windows.Forms.ToolStripMenuItem();
this.EditImportXmlMenu = new System.Windows.Forms.ToolStripMenuItem(); this.EditImportXmlMenu = new System.Windows.Forms.ToolStripMenuItem();
this.EditImportRawMenu = new System.Windows.Forms.ToolStripMenuItem(); this.EditImportRawMenu = new System.Windows.Forms.ToolStripMenuItem();
this.EditImportMenuSeparator = new System.Windows.Forms.ToolStripSeparator(); this.EditImportMenuSeparator = new System.Windows.Forms.ToolStripSeparator();
@ -115,6 +116,7 @@
this.ListContextNewMenu = new System.Windows.Forms.ToolStripMenuItem(); this.ListContextNewMenu = new System.Windows.Forms.ToolStripMenuItem();
this.ListContextNewFolderMenu = new System.Windows.Forms.ToolStripMenuItem(); this.ListContextNewFolderMenu = new System.Windows.Forms.ToolStripMenuItem();
this.ListContextNewRpfArchiveMenu = new System.Windows.Forms.ToolStripMenuItem(); this.ListContextNewRpfArchiveMenu = new System.Windows.Forms.ToolStripMenuItem();
this.ListContextImportFbxMenu = new System.Windows.Forms.ToolStripMenuItem();
this.ListContextImportXmlMenu = new System.Windows.Forms.ToolStripMenuItem(); this.ListContextImportXmlMenu = new System.Windows.Forms.ToolStripMenuItem();
this.ListContextImportRawMenu = new System.Windows.Forms.ToolStripMenuItem(); this.ListContextImportRawMenu = new System.Windows.Forms.ToolStripMenuItem();
this.ListContextImportSeparator = new System.Windows.Forms.ToolStripSeparator(); this.ListContextImportSeparator = new System.Windows.Forms.ToolStripSeparator();
@ -196,6 +198,7 @@
this.EditExtractRawMenu, this.EditExtractRawMenu,
this.EditExtractAllMenu, this.EditExtractAllMenu,
this.toolStripSeparator4, this.toolStripSeparator4,
this.EditImportFbxMenu,
this.EditImportXmlMenu, this.EditImportXmlMenu,
this.EditImportRawMenu, this.EditImportRawMenu,
this.EditImportMenuSeparator, this.EditImportMenuSeparator,
@ -267,6 +270,14 @@
this.toolStripSeparator4.Name = "toolStripSeparator4"; this.toolStripSeparator4.Name = "toolStripSeparator4";
this.toolStripSeparator4.Size = new System.Drawing.Size(204, 6); this.toolStripSeparator4.Size = new System.Drawing.Size(204, 6);
// //
// EditImportFbxMenu
//
this.EditImportFbxMenu.Name = "EditImportFbxMenu";
this.EditImportFbxMenu.Size = new System.Drawing.Size(207, 22);
this.EditImportFbxMenu.Text = "Import FBX...";
this.EditImportFbxMenu.Visible = false;
this.EditImportFbxMenu.Click += new System.EventHandler(this.EditImportFbxMenu_Click);
//
// EditImportXmlMenu // EditImportXmlMenu
// //
this.EditImportXmlMenu.Image = ((System.Drawing.Image)(resources.GetObject("EditImportXmlMenu.Image"))); this.EditImportXmlMenu.Image = ((System.Drawing.Image)(resources.GetObject("EditImportXmlMenu.Image")));
@ -383,21 +394,21 @@
// ViewLargeIconsMenu // ViewLargeIconsMenu
// //
this.ViewLargeIconsMenu.Name = "ViewLargeIconsMenu"; this.ViewLargeIconsMenu.Name = "ViewLargeIconsMenu";
this.ViewLargeIconsMenu.Size = new System.Drawing.Size(152, 22); this.ViewLargeIconsMenu.Size = new System.Drawing.Size(134, 22);
this.ViewLargeIconsMenu.Text = "Large Icons"; this.ViewLargeIconsMenu.Text = "Large Icons";
this.ViewLargeIconsMenu.Click += new System.EventHandler(this.ViewLargeIconsMenu_Click); this.ViewLargeIconsMenu.Click += new System.EventHandler(this.ViewLargeIconsMenu_Click);
// //
// ViewSmallIconsMenu // ViewSmallIconsMenu
// //
this.ViewSmallIconsMenu.Name = "ViewSmallIconsMenu"; this.ViewSmallIconsMenu.Name = "ViewSmallIconsMenu";
this.ViewSmallIconsMenu.Size = new System.Drawing.Size(152, 22); this.ViewSmallIconsMenu.Size = new System.Drawing.Size(134, 22);
this.ViewSmallIconsMenu.Text = "Small Icons"; this.ViewSmallIconsMenu.Text = "Small Icons";
this.ViewSmallIconsMenu.Click += new System.EventHandler(this.ViewSmallIconsMenu_Click); this.ViewSmallIconsMenu.Click += new System.EventHandler(this.ViewSmallIconsMenu_Click);
// //
// ViewListMenu // ViewListMenu
// //
this.ViewListMenu.Name = "ViewListMenu"; this.ViewListMenu.Name = "ViewListMenu";
this.ViewListMenu.Size = new System.Drawing.Size(152, 22); this.ViewListMenu.Size = new System.Drawing.Size(134, 22);
this.ViewListMenu.Text = "List"; this.ViewListMenu.Text = "List";
this.ViewListMenu.Click += new System.EventHandler(this.ViewListMenu_Click); this.ViewListMenu.Click += new System.EventHandler(this.ViewListMenu_Click);
// //
@ -406,14 +417,14 @@
this.ViewDetailsMenu.Checked = true; this.ViewDetailsMenu.Checked = true;
this.ViewDetailsMenu.CheckState = System.Windows.Forms.CheckState.Checked; this.ViewDetailsMenu.CheckState = System.Windows.Forms.CheckState.Checked;
this.ViewDetailsMenu.Name = "ViewDetailsMenu"; this.ViewDetailsMenu.Name = "ViewDetailsMenu";
this.ViewDetailsMenu.Size = new System.Drawing.Size(152, 22); this.ViewDetailsMenu.Size = new System.Drawing.Size(134, 22);
this.ViewDetailsMenu.Text = "Details"; this.ViewDetailsMenu.Text = "Details";
this.ViewDetailsMenu.Click += new System.EventHandler(this.ViewDetailsMenu_Click); this.ViewDetailsMenu.Click += new System.EventHandler(this.ViewDetailsMenu_Click);
// //
// toolStripSeparator11 // toolStripSeparator11
// //
this.toolStripSeparator11.Name = "toolStripSeparator11"; this.toolStripSeparator11.Name = "toolStripSeparator11";
this.toolStripSeparator11.Size = new System.Drawing.Size(149, 6); this.toolStripSeparator11.Size = new System.Drawing.Size(131, 6);
// //
// ViewThemeMenu // ViewThemeMenu
// //
@ -423,7 +434,7 @@
this.ViewThemeLightMenu, this.ViewThemeLightMenu,
this.ViewThemeDarkMenu}); this.ViewThemeDarkMenu});
this.ViewThemeMenu.Name = "ViewThemeMenu"; this.ViewThemeMenu.Name = "ViewThemeMenu";
this.ViewThemeMenu.Size = new System.Drawing.Size(152, 22); this.ViewThemeMenu.Size = new System.Drawing.Size(134, 22);
this.ViewThemeMenu.Text = "Theme"; this.ViewThemeMenu.Text = "Theme";
// //
// ViewThemeWindowsMenu // ViewThemeWindowsMenu
@ -431,28 +442,28 @@
this.ViewThemeWindowsMenu.Checked = true; this.ViewThemeWindowsMenu.Checked = true;
this.ViewThemeWindowsMenu.CheckState = System.Windows.Forms.CheckState.Checked; this.ViewThemeWindowsMenu.CheckState = System.Windows.Forms.CheckState.Checked;
this.ViewThemeWindowsMenu.Name = "ViewThemeWindowsMenu"; this.ViewThemeWindowsMenu.Name = "ViewThemeWindowsMenu";
this.ViewThemeWindowsMenu.Size = new System.Drawing.Size(152, 22); this.ViewThemeWindowsMenu.Size = new System.Drawing.Size(123, 22);
this.ViewThemeWindowsMenu.Text = "Windows"; this.ViewThemeWindowsMenu.Text = "Windows";
this.ViewThemeWindowsMenu.Click += new System.EventHandler(this.ViewThemeWindowsMenu_Click); this.ViewThemeWindowsMenu.Click += new System.EventHandler(this.ViewThemeWindowsMenu_Click);
// //
// ViewThemeBlueMenu // ViewThemeBlueMenu
// //
this.ViewThemeBlueMenu.Name = "ViewThemeBlueMenu"; this.ViewThemeBlueMenu.Name = "ViewThemeBlueMenu";
this.ViewThemeBlueMenu.Size = new System.Drawing.Size(152, 22); this.ViewThemeBlueMenu.Size = new System.Drawing.Size(123, 22);
this.ViewThemeBlueMenu.Text = "Blue"; this.ViewThemeBlueMenu.Text = "Blue";
this.ViewThemeBlueMenu.Click += new System.EventHandler(this.ViewThemeBlueMenu_Click); this.ViewThemeBlueMenu.Click += new System.EventHandler(this.ViewThemeBlueMenu_Click);
// //
// ViewThemeLightMenu // ViewThemeLightMenu
// //
this.ViewThemeLightMenu.Name = "ViewThemeLightMenu"; this.ViewThemeLightMenu.Name = "ViewThemeLightMenu";
this.ViewThemeLightMenu.Size = new System.Drawing.Size(152, 22); this.ViewThemeLightMenu.Size = new System.Drawing.Size(123, 22);
this.ViewThemeLightMenu.Text = "Light"; this.ViewThemeLightMenu.Text = "Light";
this.ViewThemeLightMenu.Click += new System.EventHandler(this.ViewThemeLightMenu_Click); this.ViewThemeLightMenu.Click += new System.EventHandler(this.ViewThemeLightMenu_Click);
// //
// ViewThemeDarkMenu // ViewThemeDarkMenu
// //
this.ViewThemeDarkMenu.Name = "ViewThemeDarkMenu"; this.ViewThemeDarkMenu.Name = "ViewThemeDarkMenu";
this.ViewThemeDarkMenu.Size = new System.Drawing.Size(152, 22); this.ViewThemeDarkMenu.Size = new System.Drawing.Size(123, 22);
this.ViewThemeDarkMenu.Text = "Dark"; this.ViewThemeDarkMenu.Text = "Dark";
this.ViewThemeDarkMenu.Click += new System.EventHandler(this.ViewThemeDarkMenu_Click); this.ViewThemeDarkMenu.Click += new System.EventHandler(this.ViewThemeDarkMenu_Click);
// //
@ -891,6 +902,7 @@
this.ListContextExtractAllMenu, this.ListContextExtractAllMenu,
this.toolStripSeparator5, this.toolStripSeparator5,
this.ListContextNewMenu, this.ListContextNewMenu,
this.ListContextImportFbxMenu,
this.ListContextImportXmlMenu, this.ListContextImportXmlMenu,
this.ListContextImportRawMenu, this.ListContextImportRawMenu,
this.ListContextImportSeparator, this.ListContextImportSeparator,
@ -908,7 +920,7 @@
this.ListContextDefragmentSeparator, this.ListContextDefragmentSeparator,
this.ListContextSelectAllMenu}); this.ListContextSelectAllMenu});
this.ListContextMenu.Name = "MainContextMenu"; this.ListContextMenu.Name = "MainContextMenu";
this.ListContextMenu.Size = new System.Drawing.Size(208, 442); this.ListContextMenu.Size = new System.Drawing.Size(208, 464);
// //
// ListContextViewMenu // ListContextViewMenu
// //
@ -995,6 +1007,13 @@
this.ListContextNewRpfArchiveMenu.Text = "RPF Archive..."; this.ListContextNewRpfArchiveMenu.Text = "RPF Archive...";
this.ListContextNewRpfArchiveMenu.Click += new System.EventHandler(this.ListContextNewRpfArchiveMenu_Click); this.ListContextNewRpfArchiveMenu.Click += new System.EventHandler(this.ListContextNewRpfArchiveMenu_Click);
// //
// ListContextImportFbxMenu
//
this.ListContextImportFbxMenu.Name = "ListContextImportFbxMenu";
this.ListContextImportFbxMenu.Size = new System.Drawing.Size(207, 22);
this.ListContextImportFbxMenu.Text = "Import FBX...";
this.ListContextImportFbxMenu.Click += new System.EventHandler(this.ListContextImportFbxMenu_Click);
//
// ListContextImportXmlMenu // ListContextImportXmlMenu
// //
this.ListContextImportXmlMenu.Image = ((System.Drawing.Image)(resources.GetObject("ListContextImportXmlMenu.Image"))); this.ListContextImportXmlMenu.Image = ((System.Drawing.Image)(resources.GetObject("ListContextImportXmlMenu.Image")));
@ -1326,5 +1345,7 @@
private System.Windows.Forms.ToolStripMenuItem ViewThemeDarkMenu; private System.Windows.Forms.ToolStripMenuItem ViewThemeDarkMenu;
private WeifenLuo.WinFormsUI.Docking.VisualStudioToolStripExtender VSExtender; private WeifenLuo.WinFormsUI.Docking.VisualStudioToolStripExtender VSExtender;
private System.Windows.Forms.ToolStripMenuItem ViewThemeWindowsMenu; private System.Windows.Forms.ToolStripMenuItem ViewThemeWindowsMenu;
private System.Windows.Forms.ToolStripMenuItem ListContextImportFbxMenu;
private System.Windows.Forms.ToolStripMenuItem EditImportFbxMenu;
} }
} }

View File

@ -537,10 +537,11 @@ namespace CodeWalker
var str = ic.ToString() + " item" + ((ic != 1) ? "s" : "") + " shown"; var str = ic.ToString() + " item" + ((ic != 1) ? "s" : "") + " shown";
bool isitem = false; bool isitem = false;
bool isfile = false; bool isfile = false;
bool issearch = CurrentFolder?.IsSearchResults ?? false;
bool canview = false; bool canview = false;
bool canedit = false; bool canedit = false;
bool canexportxml = false; bool canexportxml = false;
bool canimport = false; bool canimport = EditMode && (CurrentFolder?.RpfFolder != null) && !issearch;
if (sc != 0) if (sc != 0)
{ {
long bc = 0; long bc = 0;
@ -578,6 +579,7 @@ namespace CodeWalker
EditExtractRawMenu.Enabled = isfile; EditExtractRawMenu.Enabled = isfile;
EditImportRawMenu.Visible = canimport; EditImportRawMenu.Visible = canimport;
EditImportFbxMenu.Visible = canimport;
EditImportXmlMenu.Visible = canimport; EditImportXmlMenu.Visible = canimport;
EditImportMenuSeparator.Visible = canimport; EditImportMenuSeparator.Visible = canimport;
@ -689,6 +691,11 @@ namespace CodeWalker
rpf.ScanStructure(UpdateStatus, UpdateErrorLog); rpf.ScanStructure(UpdateStatus, UpdateErrorLog);
if (rpf.LastException != null) //incase of corrupted rpf (or renamed NG encrypted RPF)
{
continue;
}
node = CreateRpfTreeFolder(rpf, relpath, path); node = CreateRpfTreeFolder(rpf, relpath, path);
RecurseMainTreeViewRPF(node, allRpfs); RecurseMainTreeViewRPF(node, allRpfs);
@ -1703,6 +1710,7 @@ namespace CodeWalker
ListContextNewMenu.Visible = cancreate; ListContextNewMenu.Visible = cancreate;
ListContextImportRawMenu.Visible = canimport; ListContextImportRawMenu.Visible = canimport;
ListContextImportFbxMenu.Visible = canimport;
ListContextImportXmlMenu.Visible = canimport; ListContextImportXmlMenu.Visible = canimport;
ListContextImportSeparator.Visible = cancreate; ListContextImportSeparator.Visible = cancreate;
@ -1747,6 +1755,7 @@ namespace CodeWalker
MainListView.LabelEdit = enable; MainListView.LabelEdit = enable;
EnsureEditModeWarning(); EnsureEditModeWarning();
UpdateSelectionUI();
} }
private void EnsureEditModeWarning() private void EnsureEditModeWarning()
@ -2215,6 +2224,98 @@ namespace CodeWalker
AddNewFolderTreeNode(node); AddNewFolderTreeNode(node);
} }
}
private void ImportFbx()
{
if (!EditMode) return;
if (CurrentFolder?.IsSearchResults ?? false) return;
RpfDirectoryEntry parentrpffldr = CurrentFolder.RpfFolder;
if (parentrpffldr == null)
{
MessageBox.Show("No parent RPF folder selected! This shouldn't happen. Refresh the view and try again.");
return;
}
if (!EnsureRpfValidEncryption()) return;
OpenFileDialog.Filter = "FBX Files|*.fbx";
if (OpenFileDialog.ShowDialog(this) != DialogResult.OK)
{
return;//canceled
}
var fpaths = OpenFileDialog.FileNames;
var fdict = new Dictionary<string, byte[]>();
foreach (var fpath in fpaths)
{
#if !DEBUG
try
#endif
{
if (!File.Exists(fpath))
{
continue;//this shouldn't happen...
}
var fi = new FileInfo(fpath);
var fname = fi.Name;
var fnamel = fname.ToLowerInvariant();
var trimlength = 4;
if (!fnamel.EndsWith(".fbx"))
{
MessageBox.Show(fname + ": Not an FBX file!", "Cannot import FBX");
continue;
}
fname = fname.Substring(0, fname.Length - trimlength);
var data = File.ReadAllBytes(fpath);
fdict[fname] = data;
}
#if !DEBUG
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Unable to read file " + fpath);
}
#endif
}
var fbxForm = new ImportFbxForm();
fbxForm.SetInputFiles(fdict);
fbxForm.ShowDialog();
if (fbxForm.DialogResult != DialogResult.OK)
{
return; //fbx import canceled
}
var converted = fbxForm.GetOutputFiles();
if (converted == null)
{
return;
}
foreach (var kvp in converted)
{
var fname = kvp.Key;
var data = kvp.Value;
if (data != null)
{
RpfFile.CreateFile(parentrpffldr, fname, data);
}
}
RefreshMainListView();
} }
private void ImportXml() private void ImportXml()
{ {
@ -3413,6 +3514,11 @@ namespace CodeWalker
NewRpfArchive(); NewRpfArchive();
} }
private void ListContextImportFbxMenu_Click(object sender, EventArgs e)
{
ImportFbx();
}
private void ListContextImportXmlMenu_Click(object sender, EventArgs e) private void ListContextImportXmlMenu_Click(object sender, EventArgs e)
{ {
ImportXml(); ImportXml();
@ -3498,6 +3604,11 @@ namespace CodeWalker
ExtractAll(); ExtractAll();
} }
private void EditImportFbxMenu_Click(object sender, EventArgs e)
{
ImportFbx();
}
private void EditImportXmlMenu_Click(object sender, EventArgs e) private void EditImportXmlMenu_Click(object sender, EventArgs e)
{ {
ImportXml(); ImportXml();

View File

@ -313,7 +313,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADo ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADo
HwAAAk1TRnQBSQFMAgEBGAEAARgBAQEYAQEBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo HwAAAk1TRnQBSQFMAgEBGAEAATgBAQE4AQEBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAAXADAAEBAQABCAYAARwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AwABQAMAAXADAAEBAQABCAYAARwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA

View File

@ -1,5 +1,5 @@
 
Copyright(c) 2017 dexyfex Copyright(c) 2017-2019 dexyfex
@ -55,3 +55,20 @@ SOFTWARE.
/*
Copyright (c) 2015 Hamish Milne
"An FBX library for .NET"
Contains source code for FBX file format reading and writing from:
https://github.com/hamish-milne/FbxWriter
Published under GPL license, for full terms and conditions see the above link.
*/

View File

@ -238,7 +238,7 @@ namespace CodeWalker.Rendering
if (hastransforms) if (hastransforms)
{ {
int boneidx = (int)((model.Unk28h >> 24) & 0xFF); int boneidx = (int)((model.SkeletonBinding >> 24) & 0xFF);
Matrix trans = (boneidx < modeltransforms.Length) ? modeltransforms[boneidx] : Matrix.Identity; Matrix trans = (boneidx < modeltransforms.Length) ? modeltransforms[boneidx] : Matrix.Identity;
Bone bone = (hasbones && (boneidx < bones.Count)) ? bones[boneidx] : null; Bone bone = (hasbones && (boneidx < bones.Count)) ? bones[boneidx] : null;
@ -267,7 +267,7 @@ namespace CodeWalker.Rendering
} }
} }
if (((model.Unk28h >> 8) & 0xFF) > 0) //skin mesh? if (((model.SkeletonBinding >> 8) & 0xFF) > 0) //skin mesh?
{ {
model.Transform = Matrix.Identity; model.Transform = Matrix.Identity;
} }
@ -337,20 +337,16 @@ namespace CodeWalker.Rendering
public AABB_s[] GeometryBounds; public AABB_s[] GeometryBounds;
public long GeometrySize { get; private set; } public long GeometrySize { get; private set; }
public uint Unk4h; public uint SkeletonBinding;
public uint Unk14h; public uint RenderMaskFlags; //flags.......
public uint Unk28h;
public uint Unk2Ch; //flags.......
public bool UseTransform; public bool UseTransform;
public Matrix Transform; public Matrix Transform;
public void Init(DrawableModel dmodel) public void Init(DrawableModel dmodel)
{ {
Unk4h = dmodel.Unknown_4h; SkeletonBinding = dmodel.SkeletonBinding;//4th byte is bone index, 2nd byte for skin meshes
Unk14h = dmodel.Unknown_14h; RenderMaskFlags = dmodel.RenderMaskFlags; //only the first byte seems be related to this
Unk28h = dmodel.Unknown_28h;
Unk2Ch = dmodel.Unknown_2Ch; //only the first byte of Unknown_2Ch seems be related to this
DrawableModel = dmodel; DrawableModel = dmodel;

View File

@ -1904,7 +1904,7 @@ namespace CodeWalker.Rendering
private bool RenderIsModelFinalRender(RenderableModel model) private bool RenderIsModelFinalRender(RenderableModel model)
{ {
if ((model.Unk2Ch & 1) == 0) //smallest bit is proxy/"final render" bit? seems to work... if ((model.RenderMaskFlags & 1) == 0) //smallest bit is proxy/"final render" bit? seems to work...
{ {
return renderproxies; return renderproxies;
} }

View File

@ -739,7 +739,7 @@ namespace CodeWalker.Rendering
{ {
var shader = geom.Geom.DrawableGeom.Shader; var shader = geom.Geom.DrawableGeom.Shader;
var b = (shader!=null) ? shader.Unknown_11h : 0; //rage render bucket? var b = (shader!=null) ? shader.RenderBucket : 0; //rage render bucket?
var bucket = EnsureRenderBucket(b); var bucket = EnsureRenderBucket(b);

View File

@ -32,7 +32,15 @@ float4 Unpack4x8UNF(uint v)
float DepthFunc(float2 zw) float DepthFunc(float2 zw)
{ {
return zw.x;// return zw.x;
////this sort of works for reverse depth buffering, but has issues with vertices behind the near clip plane.
////might need to adjust the viewproj matrix to fix that...
////(for this to work, also need to change GpuBuffers.Clear,.ClearDepth and ShaderManager DepthComparison,RenderFinalPass)
//return max(0.001 / zw.x, 0);
//return zw.x * (0.1 + 0.00001*(abs(zw.y))); //return zw.x * (0.1 + 0.00001*(abs(zw.y)));
//return zw.x * (0.1 + 0.00001*((zw.y))); //return zw.x * (0.1 + 0.00001*((zw.y)));

145
Tools/ImportFbxForm.Designer.cs generated Normal file
View File

@ -0,0 +1,145 @@
namespace CodeWalker
{
partial class ImportFbxForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ImportFbxForm));
this.CancelThisButton = new System.Windows.Forms.Button();
this.ImportButton = new System.Windows.Forms.Button();
this.FbxFilesListBox = new System.Windows.Forms.ListBox();
this.label1 = new System.Windows.Forms.Label();
this.OutputTypeCombo = new System.Windows.Forms.ComboBox();
this.label2 = new System.Windows.Forms.Label();
this.StatusLabel = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// CancelThisButton
//
this.CancelThisButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.CancelThisButton.Location = new System.Drawing.Point(392, 310);
this.CancelThisButton.Name = "CancelThisButton";
this.CancelThisButton.Size = new System.Drawing.Size(75, 23);
this.CancelThisButton.TabIndex = 4;
this.CancelThisButton.Text = "Cancel";
this.CancelThisButton.UseVisualStyleBackColor = true;
this.CancelThisButton.Click += new System.EventHandler(this.CancelThisButton_Click);
//
// ImportButton
//
this.ImportButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.ImportButton.Location = new System.Drawing.Point(473, 310);
this.ImportButton.Name = "ImportButton";
this.ImportButton.Size = new System.Drawing.Size(75, 23);
this.ImportButton.TabIndex = 3;
this.ImportButton.Text = "Import";
this.ImportButton.UseVisualStyleBackColor = true;
this.ImportButton.Click += new System.EventHandler(this.ImportButton_Click);
//
// FbxFilesListBox
//
this.FbxFilesListBox.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.FbxFilesListBox.FormattingEnabled = true;
this.FbxFilesListBox.Location = new System.Drawing.Point(12, 25);
this.FbxFilesListBox.Name = "FbxFilesListBox";
this.FbxFilesListBox.Size = new System.Drawing.Size(246, 121);
this.FbxFilesListBox.TabIndex = 5;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(94, 13);
this.label1.TabIndex = 6;
this.label1.Text = "FBX files to import:";
//
// OutputTypeCombo
//
this.OutputTypeCombo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.OutputTypeCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.OutputTypeCombo.FormattingEnabled = true;
this.OutputTypeCombo.Items.AddRange(new object[] {
"YDR"});
this.OutputTypeCombo.Location = new System.Drawing.Point(427, 25);
this.OutputTypeCombo.Name = "OutputTypeCombo";
this.OutputTypeCombo.Size = new System.Drawing.Size(121, 21);
this.OutputTypeCombo.TabIndex = 7;
//
// label2
//
this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(356, 28);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(65, 13);
this.label2.TabIndex = 8;
this.label2.Text = "Output type:";
//
// StatusLabel
//
this.StatusLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.StatusLabel.AutoSize = true;
this.StatusLabel.Location = new System.Drawing.Point(12, 315);
this.StatusLabel.Name = "StatusLabel";
this.StatusLabel.Size = new System.Drawing.Size(81, 13);
this.StatusLabel.TabIndex = 9;
this.StatusLabel.Text = "Ready to import";
//
// ImportFbxForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(560, 345);
this.Controls.Add(this.StatusLabel);
this.Controls.Add(this.label2);
this.Controls.Add(this.OutputTypeCombo);
this.Controls.Add(this.label1);
this.Controls.Add(this.FbxFilesListBox);
this.Controls.Add(this.CancelThisButton);
this.Controls.Add(this.ImportButton);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "ImportFbxForm";
this.Text = "Import FBX - CodeWalker by dexyfex";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button CancelThisButton;
private System.Windows.Forms.Button ImportButton;
private System.Windows.Forms.ListBox FbxFilesListBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ComboBox OutputTypeCombo;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label StatusLabel;
}
}

133
Tools/ImportFbxForm.cs Normal file
View File

@ -0,0 +1,133 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CodeWalker
{
public partial class ImportFbxForm : Form
{
private Dictionary<string, byte[]> InputFiles { get; set; }
private Dictionary<string, byte[]> OutputFiles { get; set; }
public ImportFbxForm()
{
InitializeComponent();
DialogResult = DialogResult.Cancel;
OutputTypeCombo.Text = "YDR";
}
public void SetInputFiles(Dictionary<string, byte[]> fdict)
{
InputFiles = fdict;
FbxFilesListBox.Items.Clear();
foreach (var kvp in fdict)
{
FbxFilesListBox.Items.Add(kvp.Key);
}
}
public Dictionary<string, byte[]> GetOutputFiles()
{
return OutputFiles;
}
private void ConvertFiles()
{
if (InputFiles == null) return;
Cursor = Cursors.WaitCursor;
Task.Run(() =>
{
OutputFiles = new Dictionary<string, byte[]>();
foreach (var kvp in InputFiles)
{
var fname = kvp.Key;
var idata = kvp.Value;
UpdateStatus("Converting " + fname + "...");
FbxConverter fc = new FbxConverter();
var ydr = fc.ConvertToYdr(fname, idata);
if (ydr == null)
{
UpdateStatus("Converting " + fname + " failed!"); //TODO: error message
continue; //something went wrong..
}
byte[] odata = ydr.Save();
OutputFiles.Add(fname + ".ydr", odata);
}
UpdateStatus("Process complete.");
ConvertComplete();
});
}
private void ConvertComplete()
{
try
{
if (InvokeRequired)
{
BeginInvoke(new Action(() => { ConvertComplete(); }));
}
else
{
Cursor = Cursors.Default;
DialogResult = DialogResult.OK;
Close();
}
}
catch { }
}
public void UpdateStatus(string text)
{
try
{
if (InvokeRequired)
{
BeginInvoke(new Action(() => { UpdateStatus(text); }));
}
else
{
StatusLabel.Text = text;
}
}
catch { }
}
private void CancelThisButton_Click(object sender, EventArgs e)
{
Close();
}
private void ImportButton_Click(object sender, EventArgs e)
{
ConvertFiles();
}
}
}

409
Tools/ImportFbxForm.resx Normal file
View File

@ -0,0 +1,409 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<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">
<value>
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
6P///ysvjWVqtP///////wAAAAAAAAAAAP////D0/0hPpsDG6////////6y02d7k8////3qAx+/z/f//
/wAAAAAAAAAAAAAAAAAAAP///////////////8zT8V5ns1Rcrdzh9f///////////wAAAAAAAAAAAAAA
AAAAAP////////7+/6ix3nmBxFthtmdwu09WqbC54/v9//r8//j6//39/wAAAAAAAAAAAOjt/H6I0FJc
skpSqHF+wRMahFZhs4iT1AsNc1pgrm52v2RsuO/z/gAAAP////////L2/cLJ7rrD64+V4DY+ozU+mYmU
0X2Hy1hfss7V8urv/PP2/v///wAAAP///+Pp+d/k9////////+Pp/4uR3ysymW14xYOM0fD0/P///+Xq
+ri/6Pj6/wAAAOrv/j5DnbS75P////////////X4/+/0/ubr+/r7/////////9rh+hgZhKGo2QAAAPDz
/eLn+f////j6/2Nqttrg9////+Hn+P3+//3+/1hescLJ6/////L2/eru/AAAAAAAAAAAAP///8rR70tR
p/3+//v8/zY6jNPY7////09WqWpwu////wAAAAAAAAAAAAAAAAAAAAAAAPb4/vr7//////v8/5Wd1eHm
+P////v8//T3/wAAAAAAAAAAAAAAAP//AAD8PwAA/D8AAPwDAACAAwAAgAMAAIAHAADABwAAwAEAAMAB
AAAAAQAAAAEAAAABAAAAAQAAwAcAAOAPAAAoAAAAQAAAAIAAAAABABgAAAAAAAAwAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//P3//P3//P3/
/f7//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/
+fv/+fv/+Pr/+fv/+vv//P3//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA/f7/+fr/8/b/7PL/5+3/6e/+9Pf/+vv//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA/P3/9/r/6O7/cXe1UVaet7z17fL/+Pr//f3/AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+/z/9Pj/4Oj/NzyCUlOd2dz/6O//9Pf//P3/AAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/2+P9X2OmREGLnqPd
4+v/8vb/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/
1N35bXK1JSRtbHGz5O7/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA+vv/8PX/3Ob/U1eaDwtXjZLT4+z/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/2eP+MjR6AAA+c3i34Or/8fX/+/z/AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/1d/7MS91AAA1UFSS4On/8vb/+/z/AAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
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
/v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+vz/+fv/+Pr/+Pr/+vv//f3//v//AAAAAAAAAAAAAAAA
/v//+fv/9Pf/2+L/SVGtAABsLTaZytL58fX/9/n//f7/AAAAAAAAAAAAAAAA/v7/+/z/9/n/9fj/9vn/
9fj/9vj/+vz//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//f3//f3//f3//v7//v//AAAA
AAAAAAAAAAAAAAAAAAAA+/z/9vn/6e//mZ7gTVarr7bp6/H/9fj/+vv//v7/AAAAAAAAAAAAAAAAAAAA
/v7//f7/+/z/+/z/+/z//P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f3/+Pr/9fj/6e7/4+n/8fb/9Pf/+Pr//f3/AAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+fv/+fv/+vv/+Pr/+vv/
/P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7/
/f3//P3//f7//v7//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////
///////4D/////////AH////////8Af////////wB/////////AH////////8Af////////wB///////
//AH////////8Af////////wB/////////AH////////8AfwP//////wB8Af//+Af/AHgB///wA/8AcA
H///AB/wBgAf//8AD/AGAB///wAH8AYAH///AAPwBAAf//8AA/AEAD///wAD8AQAP///AAPwBAB///+A
A/AEAP///8AD4AAA////4AcAAAH////wDgAAAf/////8AAAH//////gAAAf/////4AAAAf/////gAAAA
/f//+AAAAAAAD//AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+A
AAAAAAAP/4AAAAAAAB//wAAAAABAf/4HwAAAAYAf8APAAAADgA/gA+AAAAMAA8AD8AAABwADgAP8AAAf
AAOAA/4AAB8AA4ADAAAAAQADgAIAcA4AgAOABgBwDgBAA4AMAGAMADADwDwAYAwAOAfg+ABgBAAeH//4
AEAEAB////gAwAYAH///+ADABgAf///4AcAGAB////gBwAcAH///+APAB4A////8B+AHwH//////4A//
///////gD/////////Af//////////////8=
</value>
</data>
</root>