Cutscene viewer progress, Hash updates

This commit is contained in:
dexy 2019-11-25 20:44:16 +11:00
parent dfa62a9803
commit 5a869fa836
23 changed files with 2298 additions and 389 deletions

View File

@ -143,6 +143,7 @@
<Compile Include="World\Camera.cs" />
<Compile Include="World\Clouds.cs" />
<Compile Include="World\Entity.cs" />
<Compile Include="World\Ped.cs" />
<Compile Include="World\PopZones.cs" />
<Compile Include="World\Scenarios.cs" />
<Compile Include="World\Space.cs" />

View File

@ -118,7 +118,7 @@ namespace CodeWalker.GameFiles
{ } //just testing
else
{
dates.Add(new CacheFileDate(line));//eg: 2740459947 130680580712018938 8944
dates.Add(new CacheFileDate(line));//eg: 2740459947 (hash of: platform:/data/cdimages/scaleform_frontend.rpf) 130680580712018938 8944
}
break;
}

View File

@ -101,6 +101,11 @@ namespace CodeWalker.GameFiles
public CutConcatData[] concatDataList { get; set; } // PsoDataType.Array, 784, 1, (MetaName)2621475),//ARRAYINFO, PsoDataType.Structure, 0, 0, MetaName.rage__cutfCutsceneFile2__SConcatData),
public CutHaltFrequency[] discardFrameList { get; set; } // PsoDataType.Array, 5280, 0, (MetaName)37)//ARRAYINFO, PsoDataType.Structure, 0, 0, MetaName.vHaltFrequency),
public Dictionary<int, CutObject> ObjectsDict { get; set; } = new Dictionary<int, CutObject>();
public override void ReadXml(XmlNode node)
{
fTotalDuration = Xml.GetChildFloatAttribute(node, "fTotalDuration", "value");
@ -134,9 +139,98 @@ namespace CodeWalker.GameFiles
sectionSplitList = Xml.GetChildRawFloatArray(node, "sectionSplitList");
concatDataList = XmlMeta.ReadItemArrayNullable<CutConcatData>(node, "concatDataList");
discardFrameList = XmlMeta.ReadItemArrayNullable<CutHaltFrequency>(node, "discardFrameList");
AssociateObjects();
}
public void AssociateObjects()
{
ObjectsDict.Clear();
if (pCutsceneObjects != null)
{
foreach (var obj in pCutsceneObjects)
{
if (obj is CutObject cobj)
{
ObjectsDict[cobj.iObjectId] = cobj;
}
}
}
CutEventArgs getEventArgs(int i)
{
if (i < 0) return null;
if (i >= pCutsceneEventArgsList?.Length) return null;
var args = pCutsceneEventArgsList[i];
if (!(args is CutEventArgs))
{ }
return args as CutEventArgs;
}
CutObject getObject(int i)
{
CutObject o = null;
ObjectsDict.TryGetValue(i, out o);
return o;
}
if (pCutsceneEventArgsList != null)
{
foreach (var arg in pCutsceneEventArgsList)
{
if (arg is CutObjectIdEventArgs oarg)
{
oarg.Object = getObject(oarg.iObjectId);
}
if (arg is CutObjectIdListEventArgs larg)
{
var objs = new CutObject[larg.iObjectIdList?.Length ?? 0];
for (int i = 0; i < objs.Length; i++)
{
objs[i] = getObject(larg.iObjectIdList[i]);
}
larg.ObjectList = objs;
}
}
}
if (pCutsceneEventList != null)
{
foreach (var evt in pCutsceneEventList)
{
if (evt is CutObjectIdEvent oevt)
{
oevt.Object = getObject(oevt.iObjectId);
}
if (evt is CutEvent cevt)
{
cevt.EventArgs = getEventArgs(cevt.iEventArgsIndex);
}
else
{ }
}
}
if (pCutsceneLoadEventList != null)
{
foreach (var evt in pCutsceneLoadEventList)
{
if (evt is CutObjectIdEvent oevt)
{
oevt.Object = getObject(oevt.iObjectId);
}
if (evt is CutEvent cevt)
{
cevt.EventArgs = getEventArgs(cevt.iEventArgsIndex);
}
else
{ }
}
}
}
public static CutBase ConstructObject(string type)
{
switch (type)
@ -233,6 +327,9 @@ namespace CodeWalker.GameFiles
{
UserData1 = (byte)Xml.GetChildUIntAttribute(node, "UserData1", "value");
UserData2 = (byte)Xml.GetChildUIntAttribute(node, "UserData2", "value");
if ((UserData1 != 0) || (UserData2 != 0))
{ }
}
public override string ToString()
@ -248,6 +345,9 @@ namespace CodeWalker.GameFiles
public override void ReadXml(XmlNode node)
{
Items = CutsceneFile2.ReadObjectArray(node, "Items");
if (Items?.Length > 0)
{ }
}
public override string ToString()
@ -358,7 +458,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
return iObjectId.ToString() + ": " + base.ToString();
return iObjectId.ToString() + ": " + base.ToString().Replace("CodeWalker.GameFiles.Cut", "");
}
}
[TC(typeof(EXP))] public class CutAssetManagerObject : CutObject // rage__cutfAssetManagerObject
@ -376,6 +476,11 @@ namespace CodeWalker.GameFiles
base.ReadXml(node);
cName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cName"));
}
public override string ToString()
{
return base.ToString() + ": " + cName.ToString();
}
}
[TC(typeof(EXP))] public class CutCameraObject : CutNamedObject // rage__cutfCameraObject
{
@ -726,19 +831,74 @@ namespace CodeWalker.GameFiles
}
public enum CutEventType : int
{
LoadScene = 0,
LoadAnimation = 2,
LoadAudio = 4,
LoadModels = 6,
UnloadModels = 7,
LoadParticles = 8,
LoadOverlays = 10,
LoadGxt2 = 12,
EnableHideObject = 14,
DisableHideObject = 15,
EnableFixupModel = 16,
EnableBlockBounds = 18,
DisableBlockBounds = 19,
EnableScreenFade = 20,
DisableScreenFade = 21,
EnableAnimation = 22,
DisableAnimation = 23,
EnableParticleEffect = 24,
DisableParticleEffect = 25,
EnableOverlay = 26,
DisableOverlay = 27,
EnableAudio = 28,
DisableAudio = 29,
Subtitle = 30,
PedVariation = 34,
CameraCut = 43,
LoadRayfireDes = 46,
UnloadRayfireDes = 47,
EnableCamera = 48,
CameraUnk1 = 49,
CameraUnk2 = 50,
DisableCamera = 51,
DecalUnk1 = 52,
DecalUnk2 = 53,
CameraShadowCascade = 54,
CameraUnk3 = 55,
CameraUnk4 = 59,
CameraUnk5 = 63,
CameraUnk6 = 64,
PropUnk1 = 73,
EnableLight = 74,
DisableLight = 75,
CameraUnk7 = 76,
Unk1 = 77,
Unk2 = 78,
CameraUnk8 = 79,
VehicleUnk1 = 258,
PedUnk1 = 262,
}
[TC(typeof(EXP))] public class CutEvent : CutBase // rage__cutfEvent
{
public float fTime { get; set; } // PsoDataType.Float, 16, 0, 0),
public int iEventId { get; set; } // PsoDataType.SInt, 20, 0, 0),
public CutEventType iEventId { get; set; } // PsoDataType.SInt, 20, 0, 0),
public int iEventArgsIndex { get; set; } // PsoDataType.SInt, 24, 0, 0),
public object pChildEvents { get; set; } // PsoDataType.Structure, 32, 3, 0),
//public object pChildEvents { get; set; } // PsoDataType.Structure, 32, 3, 0),
public uint StickyId { get; set; } // PsoDataType.UInt, 40, 0, 0),
public bool IsChild { get; set; } // PsoDataType.Bool, 44, 0, 0)
public CutEventArgs EventArgs { get; set; }
public override void ReadXml(XmlNode node)
{
fTime = Xml.GetChildFloatAttribute(node, "fTime", "value");
iEventId = Xml.GetChildIntAttribute(node, "iEventId", "value");
iEventId = (CutEventType)Xml.GetChildIntAttribute(node, "iEventId", "value");
iEventArgsIndex = Xml.GetChildIntAttribute(node, "iEventArgsIndex", "value");
//pChildEvents = CutsceneFile2.ReadObject(node, "pChildEvents"); //seems never used
StickyId = Xml.GetChildUIntAttribute(node, "StickyId", "value");
@ -746,13 +906,20 @@ namespace CodeWalker.GameFiles
var cNode = node.SelectSingleNode("pChildEvents");
if ((cNode?.ChildNodes?.Count > 0) || (cNode?.Attributes?.Count > 0))
{ }
{ }//nothing gets here?
}
public override string ToString()
{
return fTime.ToString("0.00") + " : " + iEventId.ToString();
}
}
[TC(typeof(EXP))] public class CutObjectIdEvent : CutEvent // rage__cutfObjectIdEvent
{
public int iObjectId { get; set; } // PsoDataType.SInt, 48, 0, 0)
public CutObject Object { get; set; }
public override void ReadXml(XmlNode node)
{
base.ReadXml(node);
@ -795,6 +962,8 @@ namespace CodeWalker.GameFiles
{
public int iObjectId { get; set; } // PsoDataType.SInt, 32, 0, 0)
public CutObject Object { get; set; }
public override void ReadXml(XmlNode node)
{
base.ReadXml(node);
@ -805,6 +974,8 @@ namespace CodeWalker.GameFiles
{
public int[] iObjectIdList { get; set; } // PsoDataType.Array, 32, 0, (MetaName)2)//ARRAYINFO, PsoDataType.SInt, 0, 0, 0),
public CutObject[] ObjectList { get; set; }
public override void ReadXml(XmlNode node)
{
base.ReadXml(node);

View File

@ -16,6 +16,7 @@ namespace CodeWalker.GameFiles
public Dictionary<MetaHash, ClipMapEntry> ClipMap { get; set; }
public Dictionary<MetaHash, AnimationMapEntry> AnimMap { get; set; }
public Dictionary<MetaHash, ClipMapEntry> CutsceneMap { get; set; } //used for ycd's that are indexed in cutscenes, since name hashes all appended with -n
public ClipMapEntry[] ClipMapEntries { get; set; }
public AnimationMapEntry[] AnimMapEntries { get; set; }
@ -78,6 +79,29 @@ namespace CodeWalker.GameFiles
}
public void BuildCutsceneMap(int cutIndex)
{
CutsceneMap = new Dictionary<MetaHash, ClipMapEntry>();
var replstr = "-" + cutIndex.ToString();
foreach (var cme in ClipMapEntries)
{
var sn = cme?.Clip?.ShortName ?? "";
if (sn.EndsWith(replstr))
{
sn = sn.Substring(0, sn.Length - replstr.Length);
}
if (sn.EndsWith("_dual"))
{
sn = sn.Substring(0, sn.Length - 5);
}
JenkIndex.Ensure(sn);
var h = JenkHash.GenHash(sn);
CutsceneMap[h] = cme;
}
}

View File

@ -48,6 +48,7 @@ namespace CodeWalker.GameFiles
public Dictionary<uint, RpfFileEntry> YbnDict { get; private set; }
public Dictionary<uint, RpfFileEntry> YcdDict { get; private set; }
public Dictionary<uint, RpfFileEntry> YnvDict { get; private set; }
public Dictionary<uint, RpfFileEntry> Gxt2Dict { get; private set; }
public Dictionary<uint, RpfFileEntry> AllYmapsDict { get; private set; }
@ -1202,7 +1203,7 @@ namespace CodeWalker.GameFiles
{
var dat = RpfMan.GetFile<CacheDatFile>(dlccachefile);
if (dat == null)
{ continue; } //update\\x64\\dlcpacks\\mpspecialraces\\dlc.rpf\\x64\\data\\cacheloaderdata_dlc\\mpspecialraces_3336915258_cache_y.dat
{ continue; } //update\\x64\\dlcpacks\\mpspecialraces\\dlc.rpf\\x64\\data\\cacheloaderdata_dlc\\mpspecialraces_3336915258_cache_y.dat (hash of: mpspecialraces_interior_additions)
AllCacheFiles.Add(dat);
foreach (var node in dat.AllMapNodes)
{
@ -1402,6 +1403,24 @@ namespace CodeWalker.GameFiles
string langstr2 = "americandlc.rpf";
string langstr3 = "american.rpf";
Gxt2Dict = new Dictionary<uint, RpfFileEntry>();
foreach (var rpf in AllRpfs)
{
foreach (var entry in rpf.AllEntries)
{
if (entry is RpfFileEntry fentry)
{
var p = entry.Path;
if (entry.NameLower.EndsWith(".gxt2") && (p.Contains(langstr) || p.Contains(langstr2) || p.Contains(langstr3)))
{
Gxt2Dict[entry.ShortNameHash] = fentry;
}
}
}
}
if (!DoFullStringIndex)
{
string globalgxt2path = "x64b.rpf\\data\\lang\\" + langstr + ".rpf\\global.gxt2";
@ -1419,24 +1438,17 @@ namespace CodeWalker.GameFiles
List<Gxt2File> gxt2files = new List<Gxt2File>();
foreach (var rpf in AllRpfs)
foreach (var entry in Gxt2Dict.Values)
{
foreach (var entry in rpf.AllEntries)
var gxt2 = RpfMan.GetFile<Gxt2File>(entry);
if (gxt2 != null)
{
var p = entry.Path;
if (entry.NameLower.EndsWith(".gxt2") && (p.Contains(langstr)|| p.Contains(langstr2)|| p.Contains(langstr3)))
for (int i = 0; i < gxt2.TextEntries.Length; i++)
{
var gxt2 = RpfMan.GetFile<Gxt2File>(entry);
if (gxt2 != null)
{
for (int i = 0; i < gxt2.TextEntries.Length; i++)
{
var e = gxt2.TextEntries[i];
GlobalText.Ensure(e.Text, e.Hash);
}
gxt2files.Add(gxt2);
}
var e = gxt2.TextEntries[i];
GlobalText.Ensure(e.Text, e.Hash);
}
gxt2files.Add(gxt2);
}
}

View File

@ -3546,6 +3546,14 @@ namespace CodeWalker.GameFiles
@null = 987444055, // how best to handle this? C# doesn't like it
exportcamera = 962998194, //cutscene related stuff

View File

@ -16276,7 +16276,7 @@ namespace CodeWalker.GameFiles
{
public MetaHash Name { get; set; } //0 Name: INT_0Bh: 0
public uint Unused0 { get; set; } //4
public Array_uint Bounds { get; set; } //8 Bounds//3298223272: Array: 8: 1 {256: INT_0Bh: 0}
public Array_uint Bounds { get; set; } //8 Bounds: Array: 8: 1 {256: INT_0Bh: 0}
public ushort Flags { get; set; } //24 Flags: SHORT_0Fh: 24: 2097155
public ushort Unused1 { get; set; }//26
public uint Unused2 { get; set; }//28
@ -16379,7 +16379,7 @@ namespace CodeWalker.GameFiles
{
public MetaHash Name { get; set; } //0 Name: INT_0Bh: 0
public uint Unused0 { get; set; } //4
public Array_uint Bounds { get; set; } //8 Bounds//3298223272: Array: 8: 1 {256: INT_0Bh: 0}
public Array_uint Bounds { get; set; } //8 Bounds: Array: 8: 1 {256: INT_0Bh: 0}
public override string ToString()
{

View File

@ -876,6 +876,70 @@ namespace CodeWalker.GameFiles
AssignSequenceBoneIds();
}
public struct FramePosition
{
public int Frame0;
public int Frame1;
public float Alpha0;
public float Alpha1;
}
public FramePosition GetFramePosition(float t)
{
bool ignoreLastFrame = true;//if last frame is equivalent to the first one, eg rollercoaster small light "globes" don't
FramePosition p = new FramePosition();
var nframes = (ignoreLastFrame) ? (Frames - 1) : Frames;
var curPos = (t / Duration) * nframes;
p.Frame0 = ((ushort)curPos) % Frames;
p.Frame1 = (p.Frame0 + 1);// % frames;
p.Alpha1 = (float)(curPos - Math.Floor(curPos));
p.Alpha0 = 1.0f - p.Alpha1;
return p;
}
public Vector4 EvaluateVector4(FramePosition frame, int boneIndex, bool interpolate)
{
var s = frame.Frame0 / SequenceFrameLimit;
int f0 = frame.Frame0 % SequenceFrameLimit;
int f1 = f0 + 1;
var seq = Sequences.data_items[s];
var aseq = seq.Sequences[boneIndex];
var v0 = aseq.EvaluateVector(f0);
var v1 = aseq.EvaluateVector(f1);
var v = interpolate ? (v0 * frame.Alpha0) + (v1 * frame.Alpha1) : v0;
return v;
}
public Quaternion EvaluateQuaternion(FramePosition frame, int boneIndex, bool interpolate)
{
var s = frame.Frame0 / SequenceFrameLimit;
int f0 = frame.Frame0 % SequenceFrameLimit;
int f1 = f0 + 1;
var seq = Sequences.data_items[s];
var aseq = seq.Sequences[boneIndex];
var q0 = aseq.EvaluateQuaternion(f0);
var q1 = aseq.EvaluateQuaternion(f1);
var q = interpolate ? Quaternion.Slerp(q0, q1, frame.Alpha1) : q0;
return q;
}
public int FindBoneIndex(ushort boneTag, byte track)
{
//TODO: make this use a dict??
if (BoneIds?.data_items != null)
{
for (int i = 0; i < BoneIds.data_items.Length; i++)
{
var b = BoneIds.data_items[i];
if ((b.BoneId == boneTag) && (b.Track == track)) return i;
}
}
return -1;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))] public struct AnimationBoneId : IMetaXmlItem
{

View File

@ -119,14 +119,14 @@ namespace CodeWalker.GameFiles
// structure data
public ulong ParametersPointer { get; set; }
public MetaHash Name { get; set; } //530103687, 2401522793, 1912906641
public MetaHash Name { get; set; } //decal_emissive_only, emissive, spec
public uint Unknown_Ch { get; set; } // 0x00000000
public byte ParameterCount { get; set; }
public byte RenderBucket { get; set; } // 2, 0,
public ushort Unknown_12h { get; set; } // 32768 HasComment?
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; } //decal_emissive_only.sps, emissive.sps, spec.sps
public uint Unknown_1Ch { get; set; } // 0x00000000
public uint RenderBucketMask { get; set; } //65284, 65281 DrawBucketMask? (1<<bucket) | 0xFF00
public ushort Unknown_24h { get; set; } //0 Instanced?

View File

@ -0,0 +1,121 @@
using CodeWalker.GameFiles;
using SharpDX;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace CodeWalker.World
{
[TypeConverter(typeof(ExpandableObjectConverter))] public class Ped
{
public string Name { get; set; } = string.Empty;
public MetaHash NameHash { get; set; } = 0;//ped name hash
public CPedModelInfo__InitData InitData { get; set; } = null; //ped init data
public YddFile Ydd { get; set; } = null; //ped drawables
public YtdFile Ytd { get; set; } = null; //ped textures
public YcdFile Ycd { get; set; } = null; //ped animations
public YftFile Yft { get; set; } = null; //ped skeleton YFT
public PedFile Ymt { get; set; } = null; //ped variation info
public Dictionary<MetaHash, RpfFileEntry> DrawableFilesDict { get; set; } = null;
public Dictionary<MetaHash, RpfFileEntry> TextureFilesDict { get; set; } = null;
public RpfFileEntry[] DrawableFiles { get; set; } = null;
public RpfFileEntry[] TextureFiles { get; set; } = null;
public ClipMapEntry AnimClip { get; set; } = null;
public string[] DrawableNames { get; set; } = new string[12];
public Drawable[] Drawables { get; set; } = new Drawable[12];
public Texture[] Textures { get; set; } = new Texture[12];
public bool EnableRootMotion { get; set; } = false; //used to toggle whether or not to include root motion when playing animations
public Vector3 Position { get; set; } = Vector3.Zero;
public Quaternion Rotation { get; set; } = Quaternion.Identity;
public void Init(string name, GameFileCache gfc)
{
var hash = JenkHash.GenHash(name.ToLowerInvariant());
Init(hash, gfc);
Name = name;
}
public void Init(MetaHash pedhash, GameFileCache gfc)
{
Name = string.Empty;
NameHash = 0;
InitData = null;
Ydd = null;
Ytd = null;
Ycd = null;
Yft = null;
Ymt = null;
AnimClip = null;
for (int i = 0; i < 12; i++)
{
Drawables[i] = null;
Textures[i] = null;
}
CPedModelInfo__InitData initdata = null;
if (!gfc.PedsInitDict.TryGetValue(pedhash, out initdata)) return;
var ycdhash = JenkHash.GenHash(initdata.ClipDictionaryName.ToLowerInvariant());
//bool pedchange = NameHash != pedhash;
//Name = pedname;
NameHash = pedhash;
InitData = initdata;
Ydd = gfc.GetYdd(pedhash);
Ytd = gfc.GetYtd(pedhash);
Ycd = gfc.GetYcd(ycdhash);
Yft = gfc.GetYft(pedhash);
PedFile pedFile = null;
gfc.PedVariationsDict?.TryGetValue(pedhash, out pedFile);
Ymt = pedFile;
Dictionary<MetaHash, RpfFileEntry> peddict = null;
gfc.PedDrawableDicts.TryGetValue(NameHash, out peddict);
DrawableFilesDict = peddict;
DrawableFiles = DrawableFilesDict?.Values.ToArray();
gfc.PedTextureDicts.TryGetValue(NameHash, out peddict);
TextureFilesDict = peddict;
TextureFiles = TextureFilesDict?.Values.ToArray();
while ((Ydd != null) && (!Ydd.Loaded))
{
Thread.Sleep(20);//kinda hacky
Ydd = gfc.GetYdd(pedhash);
}
while ((Ytd != null) && (!Ytd.Loaded))
{
Thread.Sleep(20);//kinda hacky
Ytd = gfc.GetYtd(pedhash);
}
while ((Ycd != null) && (!Ycd.Loaded))
{
Thread.Sleep(20);//kinda hacky
Ycd = gfc.GetYcd(ycdhash);
}
while ((Yft != null) && (!Yft.Loaded))
{
Thread.Sleep(20);//kinda hacky
Yft = gfc.GetYft(pedhash);
}
MetaHash cliphash = JenkHash.GenHash("idle");
ClipMapEntry cme = null;
Ycd?.ClipMap?.TryGetValue(cliphash, out cme);
AnimClip = cme;
}
}
}

View File

@ -150,9 +150,9 @@ namespace CodeWalker.World
//foreach (var dg in dataGroupDict.Values)
//{
// sb.AppendLine(dg.ToString());
// if (dg.YBNHashes_3298223272 != null)
// if (dg.Bounds != null)
// {
// foreach (var ybnh in dg.YBNHashes_3298223272)
// foreach (var ybnh in dg.Bounds)
// {
// sb.AppendLine(" " + ybnh.ToString());
// }

View File

@ -540,6 +540,12 @@
<DependentUpon>SelectFolderForm.cs</DependentUpon>
</Compile>
<Compile Include="Settings.cs" />
<Compile Include="World\CutsceneForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="World\CutsceneForm.Designer.cs">
<DependentUpon>CutsceneForm.cs</DependentUpon>
</Compile>
<Compile Include="World\SettingsForm.cs">
<SubType>Form</SubType>
</Compile>
@ -794,6 +800,9 @@
<EmbeddedResource Include="Utils\SelectFolderForm.resx">
<DependentUpon>SelectFolderForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="World\CutsceneForm.resx">
<DependentUpon>CutsceneForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="World\SettingsForm.resx">
<DependentUpon>SettingsForm.cs</DependentUpon>
</EmbeddedResource>

View File

@ -160,7 +160,7 @@
this.XmlTextBox.AutoIndentChars = false;
this.XmlTextBox.AutoIndentCharsPatterns = "";
this.XmlTextBox.AutoIndentExistingLines = false;
this.XmlTextBox.AutoScrollMinSize = new System.Drawing.Size(27, 14);
this.XmlTextBox.AutoScrollMinSize = new System.Drawing.Size(2, 14);
this.XmlTextBox.BackBrush = null;
this.XmlTextBox.CharHeight = 14;
this.XmlTextBox.CharWidth = 8;
@ -169,7 +169,6 @@
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 = '<';

View File

@ -64,7 +64,6 @@ namespace CodeWalker.Peds
int toolsPanelResizeStartLeft = 0;
int toolsPanelResizeStartRight = 0;
Dictionary<DrawableBase, bool> DrawableDrawFlags = new Dictionary<DrawableBase, bool>();
bool enableGrid = false;
float gridSize = 1.0f;
@ -75,28 +74,8 @@ namespace CodeWalker.Peds
[TypeConverter(typeof(ExpandableObjectConverter))] public class PedSelection
{
public string Name { get; set; } = string.Empty;
public MetaHash NameHash { get; set; } = 0;//ped name hash
public CPedModelInfo__InitData InitData { get; set; } = null; //ped init data
public YddFile Ydd { get; set; } = null; //ped drawables
public YtdFile Ytd { get; set; } = null; //ped textures
public YcdFile Ycd { get; set; } = null; //ped animations
public YftFile Yft { get; set; } = null; //ped skeleton YFT
public PedFile Ymt { get; set; } = null; //ped variation info
public Dictionary<MetaHash, RpfFileEntry> DrawableFilesDict { get; set; } = null;
public Dictionary<MetaHash, RpfFileEntry> TextureFilesDict { get; set; } = null;
public RpfFileEntry[] DrawableFiles { get; set; } = null;
public RpfFileEntry[] TextureFiles { get; set; } = null;
public ClipMapEntry AnimClip { get; set; } = null;
public string[] DrawableNames { get; set; } = new string[12];
public Drawable[] Drawables { get; set; } = new Drawable[12];
public Texture[] Textures { get; set; } = new Texture[12];
public bool EnableRootMotion { get; set; } = false; //used to toggle whether or not to include root motion when playing animations
}
PedSelection SelectedPed = new PedSelection();
Ped SelectedPed = new Ped();
ComboBox[] ComponentComboBoxes = null;
@ -256,7 +235,7 @@ namespace CodeWalker.Peds
Renderer.SelectedDrawable = null;// SelectedItem.Drawable;
RenderPed();
Renderer.RenderPed(SelectedPed);
//UpdateMouseHitsFromRenderer();
//RenderSelection();
@ -616,14 +595,14 @@ namespace CodeWalker.Peds
{
if (rem)
{
if (DrawableDrawFlags.ContainsKey(drwbl))
if (Renderer.SelectionDrawableDrawFlags.ContainsKey(drwbl))
{
DrawableDrawFlags.Remove(drwbl);
Renderer.SelectionDrawableDrawFlags.Remove(drwbl);
}
}
else
{
DrawableDrawFlags[drwbl] = false;
Renderer.SelectionDrawableDrawFlags[drwbl] = false;
}
}
if (model != null)
@ -709,7 +688,7 @@ namespace CodeWalker.Peds
{
//TODO: change to go through each component and add/update/remove treeview item accordingly?
DrawableDrawFlags.Clear();
Renderer.SelectionDrawableDrawFlags.Clear();
Renderer.SelectionModelDrawFlags.Clear();
Renderer.SelectionGeometryDrawFlags.Clear();
ModelsTreeView.Nodes.Clear();
@ -739,75 +718,17 @@ namespace CodeWalker.Peds
public void LoadPed()
{
var pedname = PedNameComboBox.Text;
var pednamel = pedname.ToLowerInvariant();
MetaHash pedhash = JenkHash.GenHash(pednamel);
var pedhash = JenkHash.GenHash(pedname.ToLowerInvariant());
var pedchange = SelectedPed.NameHash != pedhash;
SelectedPed.Name = string.Empty;
SelectedPed.NameHash = 0;
SelectedPed.InitData = null;
SelectedPed.Ydd = null;
SelectedPed.Ytd = null;
SelectedPed.Ycd = null;
SelectedPed.Yft = null;
SelectedPed.Ymt = null;
SelectedPed.AnimClip = null;
for (int i = 0; i < 12; i++)
{
ClearCombo(ComponentComboBoxes[i]);
SelectedPed.Drawables[i] = null;
SelectedPed.Textures[i] = null;
}
DetailsPropertyGrid.SelectedObject = null;
CPedModelInfo__InitData initdata = null;
if (!GameFileCache.PedsInitDict.TryGetValue(pedhash, out initdata)) return;
var ycdhash = JenkHash.GenHash(initdata.ClipDictionaryName.ToLowerInvariant());
bool pedchange = SelectedPed.NameHash != pedhash;
SelectedPed.Name = pedname;
SelectedPed.NameHash = pedhash;
SelectedPed.InitData = initdata;
SelectedPed.Ydd = GameFileCache.GetYdd(pedhash);
SelectedPed.Ytd = GameFileCache.GetYtd(pedhash);
SelectedPed.Ycd = GameFileCache.GetYcd(ycdhash);
SelectedPed.Yft = GameFileCache.GetYft(pedhash);
PedFile pedFile = null;
GameFileCache.PedVariationsDict?.TryGetValue(pedhash, out pedFile);
SelectedPed.Ymt = pedFile;
Dictionary<MetaHash, RpfFileEntry> peddict = null;
GameFileCache.PedDrawableDicts.TryGetValue(SelectedPed.NameHash, out peddict);
SelectedPed.DrawableFilesDict = peddict;
SelectedPed.DrawableFiles = SelectedPed.DrawableFilesDict?.Values.ToArray();
GameFileCache.PedTextureDicts.TryGetValue(SelectedPed.NameHash, out peddict);
SelectedPed.TextureFilesDict = peddict;
SelectedPed.TextureFiles = SelectedPed.TextureFilesDict?.Values.ToArray();
while ((SelectedPed.Ydd != null) && (!SelectedPed.Ydd.Loaded))
{
Thread.Sleep(20);//kinda hacky
SelectedPed.Ydd = GameFileCache.GetYdd(pedhash);
}
while ((SelectedPed.Ytd != null) && (!SelectedPed.Ytd.Loaded))
{
Thread.Sleep(20);//kinda hacky
SelectedPed.Ytd = GameFileCache.GetYtd(pedhash);
}
while ((SelectedPed.Ycd != null) && (!SelectedPed.Ycd.Loaded))
{
Thread.Sleep(20);//kinda hacky
SelectedPed.Ycd = GameFileCache.GetYcd(ycdhash);
}
while ((SelectedPed.Yft != null) && (!SelectedPed.Yft.Loaded))
{
Thread.Sleep(20);//kinda hacky
SelectedPed.Yft = GameFileCache.GetYft(pedhash);
}
SelectedPed.Init(pedname, GameFileCache);
LoadModel(SelectedPed.Yft, pedchange);
@ -821,14 +742,8 @@ namespace CodeWalker.Peds
}
}
ClipDictComboBox.Text = SelectedPed.InitData?.ClipDictionaryName ?? "";
ClipComboBox.Text = "idle";
MetaHash cliphash = JenkHash.GenHash("idle");
ClipMapEntry cme = null;
SelectedPed.Ycd?.ClipMap?.TryGetValue(cliphash, out cme);
SelectedPed.AnimClip = cme;
DetailsPropertyGrid.SelectedObject = SelectedPed;
@ -1208,96 +1123,6 @@ namespace CodeWalker.Peds
private void RenderPed()
{
YftFile yft = SelectedPed.Yft;// GameFileCache.GetYft(SelectedModelHash);
if (yft != null)
{
if (yft.Loaded)
{
if (yft.Fragment != null)
{
//var f = yft.Fragment;
//var txdhash = 0u;// SelectedVehicleHash;// yft.RpfFileEntry?.ShortNameHash ?? 0;
//var namelower = yft.RpfFileEntry?.GetShortNameLower();
//Archetype arch = null;// TryGetArchetype(hash);
//Renderer.RenderFragment(arch, null, f, txdhash);
//seldrwbl = f.Drawable;
}
}
var vi = SelectedPed.Ymt?.VariationInfo;
if (vi != null)
{
for (int i = 0; i < 12; i++)
{
RenderPedComponent(i);
}
}
}
}
private void RenderPedComponent(int i)
{
//var compData = SelectedPed.Ymt?.VariationInfo?.GetComponentData(i);
var drawable = SelectedPed.Drawables[i];
var texture = SelectedPed.Textures[i];
//if (compData == null) return;
if (drawable == null) return;
var td = SelectedPed.Ytd?.TextureDict;
var ac = SelectedPed.AnimClip;
if (ac != null)
{
ac.EnableRootMotion = SelectedPed.EnableRootMotion;
}
var skel = SelectedPed.Yft?.Fragment?.Drawable?.Skeleton;
if (skel != null)
{
if (drawable.Skeleton == null)
{
drawable.Skeleton = skel;//force the drawable to use this skeleton.
}
else if (drawable.Skeleton != skel)
{
var dskel = drawable.Skeleton; //put the bones of the fragment into the drawable. drawable's bones in this case seem messed up!
for (int b = 0; b < skel.Bones.Count; b++)
{
var srcbone = skel.Bones[b];
var dstbone = srcbone;
if (dskel.BonesMap.TryGetValue(srcbone.Tag, out dstbone))
{
if (srcbone == dstbone) break; //bone reassignment already done!
dskel.Bones[dstbone.Index] = srcbone;
dskel.BonesMap[srcbone.Tag] = srcbone;
}
}
}
}
bool drawFlag = true;
if (!DrawableDrawFlags.TryGetValue(drawable, out drawFlag))
{ drawFlag = true; }
if (drawFlag)
{
Renderer.RenderDrawable(drawable, null, null, 0, td, texture, ac);
}
}

View File

@ -5038,7 +5038,7 @@ namespace CodeWalker.Project
room.NameHash = JenkHash.GenHash(room.Name);
room.Flags0 = 0xAAAAAAAA;
room.Unk06 = 3817852694;//??
room.Unk06 = (uint)MetaName.null_sound;
room.Unk14 = 3565506855;//?

View File

@ -483,18 +483,8 @@ namespace CodeWalker.Rendering
{ return; }
bool interpolate = true; //how to know? eg. cs4_14_hickbar_anim shouldn't
bool ignoreLastFrame = true;//if last frame is equivalent to the first one, eg rollercoaster small light "globes" don't
var duration = anim.Duration;
var frames = anim.Frames;
var nframes = (ignoreLastFrame) ? (frames - 1) : frames;
var curPos = (t/duration) * nframes;
var frame0 = ((ushort)curPos) % frames;
var frame1 = (frame0 + 1);// % frames;
var falpha = (float)(curPos - Math.Floor(curPos));
var ialpha = 1.0f - falpha;
var frame = anim.GetFramePosition(t);
var dwbl = this.Key;
var skel = dwbl?.Skeleton;
@ -502,8 +492,8 @@ namespace CodeWalker.Rendering
if (bones == null)
{ return; }
Vector4 v0, v1, v;
Quaternion q0, q1, q;
Vector4 v;
Quaternion q;
for (int i = 0; i < anim.BoneIds.data_items.Length; i++)
{
@ -513,50 +503,38 @@ namespace CodeWalker.Rendering
Bone bone = null;
skel?.BonesMap?.TryGetValue(boneiditem.BoneId, out bone);
if (bone == null)
{ continue; }
{
continue;
//skel.BoneTagsMap?.TryGetValue(boneiditem.BoneId, out bone);
//if (bone == null)
//{ continue; }
}
var sfl = anim.SequenceFrameLimit;
var s = frame0 / sfl;
int f0 = frame0 % sfl;
int f1 = f0 + 1;
var seq = anim.Sequences.data_items[s];
var aseq = seq.Sequences[i];
switch (track)
{
case 0: //bone position
v0 = aseq.EvaluateVector(f0);
v1 = aseq.EvaluateVector(f1);
v = interpolate ? (v0 * ialpha) + (v1 * falpha) : v0;
v = anim.EvaluateVector4(frame, i, interpolate);
bone.AnimTranslation = v.XYZ();
break;
case 1: //bone orientation
q0 = aseq.EvaluateQuaternion(f0);
q1 = aseq.EvaluateQuaternion(f1);
q = interpolate ? Quaternion.Slerp(q0, q1, falpha) : q0;
q = anim.EvaluateQuaternion(frame, i, interpolate);
bone.AnimRotation = q;
break;
case 2: //scale?
v0 = aseq.EvaluateVector(f0);
v1 = aseq.EvaluateVector(f1);
v = interpolate ? (v0 * ialpha) + (v1 * falpha) : v0;
v = anim.EvaluateVector4(frame, i, interpolate);
bone.AnimScale = v.XYZ();
break;
case 5://root motion vector
if (EnableRootMotion)
{
v0 = aseq.EvaluateVector(f0);
v1 = aseq.EvaluateVector(f1);
v = interpolate ? (v0 * ialpha) + (v1 * falpha) : v0;
v = anim.EvaluateVector4(frame, i, interpolate);
bone.AnimTranslation += v.XYZ();
}
break;
case 6://quaternion... root rotation
if (EnableRootMotion)
{
q0 = aseq.EvaluateQuaternion(f0);
q1 = aseq.EvaluateQuaternion(f1);
q = interpolate ? Quaternion.Slerp(q0, q1, falpha) : q0;
q = anim.EvaluateQuaternion(frame, i, interpolate);
bone.AnimRotation = q * bone.AnimRotation;
}
break;
@ -564,6 +542,12 @@ namespace CodeWalker.Rendering
break;
case 8://quaternion... (camera rotation?)
break;
case 24://face stuff?
break;
case 25://face stuff?
break;
case 26://face stuff?
break;
case 27:
case 50:
case 134://single float?
@ -655,17 +639,8 @@ namespace CodeWalker.Rendering
{ return; }
bool interpolate = true; //how to know? eg. cs4_14_hickbar_anim shouldn't
bool ignoreLastFrame = true;//if last frame is equivalent to the first one, eg rollercoaster small light "globes" don't
var duration = anim.Duration;
var frames = anim.Frames;
var nframes = (ignoreLastFrame) ? (frames - 1) : frames;
var curPos = (t / duration) * nframes;
var frame0 = ((ushort)curPos) % frames;
var frame1 = (frame0 + 1);// % frames;
var falpha = (float)(curPos - Math.Floor(curPos));
var ialpha = 1.0f - falpha;
var frame = anim.GetFramePosition(t);
var globalAnimUV0 = new Vector4(1.0f, 0.0f, 0.0f, 0.0f);
var globalAnimUV1 = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
@ -678,16 +653,8 @@ namespace CodeWalker.Rendering
if ((track != 17) && (track != 18))
{ continue; }//17 and 18 would be UV0 and UV1
var sfl = anim.SequenceFrameLimit;
var s = frame0 / sfl;
int f0 = frame0 % sfl;
int f1 = f0 + 1;
var v = anim.EvaluateVector4(frame, i, interpolate);
var seq = anim.Sequences.data_items[s];
var aseq = seq.Sequences[i];
var v0 = aseq.EvaluateVector(f0);
var v1 = aseq.EvaluateVector(f1);
var v = interpolate ? (v0 * ialpha) + (v1 * falpha) : v0;
switch (track)
{
case 17: globalAnimUV0 = v; break; //could be overwriting values here...

View File

@ -138,6 +138,7 @@ namespace CodeWalker.Rendering
private YmapEntityDef SelectedCarGenEntity = new YmapEntityDef(); //placeholder entity object for drawing cars
public DrawableBase SelectedDrawable = null;
public Dictionary<DrawableBase, bool> SelectionDrawableDrawFlags = new Dictionary<DrawableBase, bool>();
public Dictionary<DrawableModel, bool> SelectionModelDrawFlags = new Dictionary<DrawableModel, bool>();
public Dictionary<DrawableGeometry, bool> SelectionGeometryDrawFlags = new Dictionary<DrawableGeometry, bool>();
public bool SelectionFlagsTestAll = false; //to test all renderables for draw flags; for model form
@ -2718,6 +2719,97 @@ namespace CodeWalker.Rendering
public void RenderPed(Ped ped)
{
YftFile yft = ped.Yft;// GameFileCache.GetYft(SelectedModelHash);
if (yft != null)
{
if (yft.Loaded)
{
if (yft.Fragment != null)
{
//var f = yft.Fragment;
//var txdhash = 0u;// SelectedVehicleHash;// yft.RpfFileEntry?.ShortNameHash ?? 0;
//var namelower = yft.RpfFileEntry?.GetShortNameLower();
//Archetype arch = null;// TryGetArchetype(hash);
//Renderer.RenderFragment(arch, null, f, txdhash);
//seldrwbl = f.Drawable;
}
}
var vi = ped.Ymt?.VariationInfo;
if (vi != null)
{
for (int i = 0; i < 12; i++)
{
RenderPedComponent(ped, i);
}
}
}
}
private void RenderPedComponent(Ped ped, int i)
{
//var compData = ped.Ymt?.VariationInfo?.GetComponentData(i);
var drawable = ped.Drawables[i];
var texture = ped.Textures[i];
//if (compData == null) return;
if (drawable == null) return;
var td = ped.Ytd?.TextureDict;
var ac = ped.AnimClip;
if (ac != null)
{
ac.EnableRootMotion = ped.EnableRootMotion;
}
var skel = ped.Yft?.Fragment?.Drawable?.Skeleton;
if (skel != null)
{
if (drawable.Skeleton == null)
{
drawable.Skeleton = skel;//force the drawable to use this skeleton.
}
else if (drawable.Skeleton != skel)
{
var dskel = drawable.Skeleton; //put the bones of the fragment into the drawable. drawable's bones in this case seem messed up!
for (int b = 0; b < skel.Bones.Count; b++)
{
var srcbone = skel.Bones[b];
var dstbone = srcbone;
if (dskel.BonesMap.TryGetValue(srcbone.Tag, out dstbone))
{
if (srcbone == dstbone) break; //bone reassignment already done!
dskel.Bones[dstbone.Index] = srcbone;
dskel.BonesMap[srcbone.Tag] = srcbone;
}
}
}
}
bool drawFlag = true;
if (!SelectionDrawableDrawFlags.TryGetValue(drawable, out drawFlag))
{ drawFlag = true; }
if (drawFlag)
{
RenderDrawable(drawable, null, null, 0, td, texture, ac);
}
}
private void RenderInteriorCollisionMesh(YmapEntityDef mlo)

203
World/CutsceneForm.Designer.cs generated Normal file
View File

@ -0,0 +1,203 @@
namespace CodeWalker.World
{
partial class CutsceneForm
{
/// <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()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CutsceneForm));
this.label3 = new System.Windows.Forms.Label();
this.CutsceneComboBox = new System.Windows.Forms.ComboBox();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.CutsceneTreeView = new System.Windows.Forms.TreeView();
this.InfoPropertyGrid = new System.Windows.Forms.PropertyGrid();
this.AnimateCameraCheckBox = new System.Windows.Forms.CheckBox();
this.TimeTrackBar = new System.Windows.Forms.TrackBar();
this.TimeLabel = new System.Windows.Forms.Label();
this.PlayStopButton = new System.Windows.Forms.Button();
this.PlaybackTimer = new System.Windows.Forms.Timer(this.components);
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.TimeTrackBar)).BeginInit();
this.SuspendLayout();
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(10, 10);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(55, 13);
this.label3.TabIndex = 3;
this.label3.Text = "Cutscene:";
//
// CutsceneComboBox
//
this.CutsceneComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.CutsceneComboBox.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
this.CutsceneComboBox.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
this.CutsceneComboBox.FormattingEnabled = true;
this.CutsceneComboBox.Location = new System.Drawing.Point(71, 7);
this.CutsceneComboBox.Name = "CutsceneComboBox";
this.CutsceneComboBox.Size = new System.Drawing.Size(529, 21);
this.CutsceneComboBox.TabIndex = 2;
this.CutsceneComboBox.SelectedIndexChanged += new System.EventHandler(this.CutsceneComboBox_SelectedIndexChanged);
//
// splitContainer1
//
this.splitContainer1.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.splitContainer1.Location = new System.Drawing.Point(1, 70);
this.splitContainer1.Name = "splitContainer1";
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.CutsceneTreeView);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.InfoPropertyGrid);
this.splitContainer1.Size = new System.Drawing.Size(722, 330);
this.splitContainer1.SplitterDistance = 259;
this.splitContainer1.TabIndex = 4;
//
// CutsceneTreeView
//
this.CutsceneTreeView.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.CutsceneTreeView.Dock = System.Windows.Forms.DockStyle.Fill;
this.CutsceneTreeView.FullRowSelect = true;
this.CutsceneTreeView.HideSelection = false;
this.CutsceneTreeView.Location = new System.Drawing.Point(0, 0);
this.CutsceneTreeView.Name = "CutsceneTreeView";
this.CutsceneTreeView.ShowLines = false;
this.CutsceneTreeView.ShowRootLines = false;
this.CutsceneTreeView.Size = new System.Drawing.Size(259, 330);
this.CutsceneTreeView.TabIndex = 1;
this.CutsceneTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.CutsceneTreeView_AfterSelect);
//
// InfoPropertyGrid
//
this.InfoPropertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
this.InfoPropertyGrid.HelpVisible = false;
this.InfoPropertyGrid.Location = new System.Drawing.Point(0, 0);
this.InfoPropertyGrid.Name = "InfoPropertyGrid";
this.InfoPropertyGrid.Size = new System.Drawing.Size(459, 330);
this.InfoPropertyGrid.TabIndex = 0;
//
// AnimateCameraCheckBox
//
this.AnimateCameraCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.AnimateCameraCheckBox.AutoSize = true;
this.AnimateCameraCheckBox.Checked = true;
this.AnimateCameraCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.AnimateCameraCheckBox.Location = new System.Drawing.Point(617, 9);
this.AnimateCameraCheckBox.Name = "AnimateCameraCheckBox";
this.AnimateCameraCheckBox.Size = new System.Drawing.Size(102, 17);
this.AnimateCameraCheckBox.TabIndex = 5;
this.AnimateCameraCheckBox.Text = "Animate camera";
this.AnimateCameraCheckBox.UseVisualStyleBackColor = true;
this.AnimateCameraCheckBox.CheckedChanged += new System.EventHandler(this.AnimateCameraCheckBox_CheckedChanged);
//
// TimeTrackBar
//
this.TimeTrackBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.TimeTrackBar.AutoSize = false;
this.TimeTrackBar.Location = new System.Drawing.Point(91, 34);
this.TimeTrackBar.Maximum = 100;
this.TimeTrackBar.Name = "TimeTrackBar";
this.TimeTrackBar.Size = new System.Drawing.Size(509, 30);
this.TimeTrackBar.TabIndex = 7;
//
// TimeLabel
//
this.TimeLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.TimeLabel.AutoSize = true;
this.TimeLabel.Location = new System.Drawing.Point(614, 41);
this.TimeLabel.Name = "TimeLabel";
this.TimeLabel.Size = new System.Drawing.Size(60, 13);
this.TimeLabel.TabIndex = 8;
this.TimeLabel.Text = "0.00 / 0.00";
//
// PlayStopButton
//
this.PlayStopButton.Location = new System.Drawing.Point(10, 36);
this.PlayStopButton.Name = "PlayStopButton";
this.PlayStopButton.Size = new System.Drawing.Size(75, 23);
this.PlayStopButton.TabIndex = 9;
this.PlayStopButton.Text = "Play";
this.PlayStopButton.UseVisualStyleBackColor = true;
this.PlayStopButton.Click += new System.EventHandler(this.PlayStopButton_Click);
//
// PlaybackTimer
//
this.PlaybackTimer.Tick += new System.EventHandler(this.PlaybackTimer_Tick);
//
// CutsceneForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(724, 401);
this.Controls.Add(this.PlayStopButton);
this.Controls.Add(this.TimeLabel);
this.Controls.Add(this.TimeTrackBar);
this.Controls.Add(this.AnimateCameraCheckBox);
this.Controls.Add(this.splitContainer1);
this.Controls.Add(this.label3);
this.Controls.Add(this.CutsceneComboBox);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "CutsceneForm";
this.Text = "Cutscene Viewer - CodeWalker by dexyfex";
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.CutsceneForm_FormClosed);
this.Load += new System.EventHandler(this.CutsceneForm_Load);
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.TimeTrackBar)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label3;
private System.Windows.Forms.ComboBox CutsceneComboBox;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.TreeView CutsceneTreeView;
private System.Windows.Forms.PropertyGrid InfoPropertyGrid;
private System.Windows.Forms.CheckBox AnimateCameraCheckBox;
private System.Windows.Forms.TrackBar TimeTrackBar;
private System.Windows.Forms.Label TimeLabel;
private System.Windows.Forms.Button PlayStopButton;
private System.Windows.Forms.Timer PlaybackTimer;
}
}

944
World/CutsceneForm.cs Normal file
View File

@ -0,0 +1,944 @@
using CodeWalker.GameFiles;
using SharpDX;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CodeWalker.World
{
public partial class CutsceneForm : Form
{
private WorldForm WorldForm;
private GameFileCache GameFileCache;
private Cutscene Cutscene = null;
private bool AnimateCamera = true;
private bool Playing = false;
class CutsceneDropdownItem
{
public RpfEntry RpfEntry { get; set; }
public override string ToString()
{
return RpfEntry?.Path ?? "";
}
}
public CutsceneForm(WorldForm worldForm)
{
WorldForm = worldForm;
GameFileCache = WorldForm.GameFileCache;
InitializeComponent();
}
public void UpdateAnimation(float elapsed)
{
if (Cutscene != null)
{
if (Playing)
{
var newt = Cutscene.PlaybackTime + elapsed;
if (newt > Cutscene.Duration)
{
newt = 0.0f; //stop or loop?
}
Cutscene.Update(newt);
}
if (AnimateCamera && (Cutscene.CameraObject != null))
{
var cori = Quaternion.RotationAxis(Vector3.UnitX, -1.57079632679f) * Quaternion.RotationAxis(Vector3.UnitZ, 3.141592653f);
var pos = Cutscene.Position + Cutscene.CameraObject.Position;
var rot = Cutscene.Rotation * Cutscene.CameraObject.Rotation * cori;
WorldForm.SetCameraTransform(pos, rot);
}
}
}
public void GetVisibleYmaps(Camera camera, Dictionary<MetaHash, YmapFile> ymaps)
{
//use a temporary ymap for entities.
}
private void SelectCutscene(CutsceneDropdownItem dditem)
{
Cursor = Cursors.WaitCursor;
Task.Run(() =>
{
CutFile cutFile = null;
Cutscene cutscene = null;
if (GameFileCache.IsInited)
{
var entry = dditem?.RpfEntry as RpfFileEntry;
if (entry != null)
{
cutFile = new CutFile(entry);
GameFileCache.RpfMan.LoadFile(cutFile, entry);
cutscene = new Cutscene();
cutscene.Init(cutFile, GameFileCache);
}
}
CutsceneLoaded(cutscene);
});
}
private void CutsceneLoaded(Cutscene cs)
{
if (InvokeRequired)
{
try
{
Invoke(new Action(() => { CutsceneLoaded(cs); }));
}
catch
{ }
return;
}
Cutscene = cs;
LoadTreeView(cs);
TimeTrackBar.Maximum = (int)(cs.Duration * 10.0f);
TimeTrackBar.Value = 0;
UpdateTimeLabel();
Cursor = Cursors.Default;
}
private void LoadTreeView(Cutscene cs)
{
CutsceneTreeView.Nodes.Clear();
var cutFile = cs?.CutFile;
var cf = cutFile?.CutsceneFile2;
if (cf != null)
{
var csnode = CutsceneTreeView.Nodes.Add(cutFile.FileEntry?.Name);
csnode.Tag = cs;
if (cf.pCutsceneObjects != null)
{
var objsnode = csnode.Nodes.Add("Objects");
objsnode.Name = "Objects";
foreach (var obj in cf.pCutsceneObjects)
{
var objnode = objsnode.Nodes.Add(obj.ToString());
objnode.Tag = obj;
}
}
if (cf.pCutsceneEventList != null)
{
var evtsnode = csnode.Nodes.Add("Events");
evtsnode.Name = "Events";
foreach (var evt in cf.pCutsceneEventList)
{
var evtnode = evtsnode.Nodes.Add(evt.ToString());
evtnode.Tag = evt;
}
}
if (cf.pCutsceneLoadEventList != null)
{
var ldesnode = csnode.Nodes.Add("Load Events");
ldesnode.Name = "Load Events";
foreach (var lev in cf.pCutsceneLoadEventList)
{
var ldenode = ldesnode.Nodes.Add(lev.ToString());
ldenode.Tag = lev;
}
}
csnode.Expand();
CutsceneTreeView.SelectedNode = csnode;
}
}
private void UpdateTimeTrackBar()
{
var tim = Cutscene?.PlaybackTime ?? 0.0f;
var itim = (int)(tim * 10.0f);
TimeTrackBar.Value = itim;
}
private void UpdateTimeLabel()
{
var tim = Cutscene?.PlaybackTime ?? 0.0f;
var dur = Cutscene?.Duration ?? 0.0f;
TimeLabel.Text = tim.ToString("0.00") + " / " + dur.ToString("0.00");
}
private void CutsceneForm_Load(object sender, EventArgs e)
{
if (!GameFileCache.IsInited) return;//what to do here?
var rpfman = GameFileCache.RpfMan;
var rpflist = rpfman.AllRpfs; //loadedOnly ? gfc.ActiveMapRpfFiles.Values.ToList() :
var dditems = new List<CutsceneDropdownItem>();
foreach (var rpf in rpflist)
{
foreach (var entry in rpf.AllEntries)
{
if (entry.NameLower.EndsWith(".cut"))
{
var dditem = new CutsceneDropdownItem();
dditem.RpfEntry = entry;
dditems.Add(dditem);
}
}
}
CutsceneComboBox.Items.Clear();
CutsceneComboBox.Items.AddRange(dditems.ToArray());
}
private void CutsceneForm_FormClosed(object sender, FormClosedEventArgs e)
{
WorldForm?.OnCutsceneFormClosed();
}
private void CutsceneComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
var item = CutsceneComboBox.SelectedItem as CutsceneDropdownItem;
SelectCutscene(item);
}
private void CutsceneTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
InfoPropertyGrid.SelectedObject = CutsceneTreeView.SelectedNode?.Tag;
}
private void AnimateCameraCheckBox_CheckedChanged(object sender, EventArgs e)
{
AnimateCamera = AnimateCameraCheckBox.Checked;
}
private void PlayStopButton_Click(object sender, EventArgs e)
{
if (Playing)
{
Playing = false;
PlayStopButton.Text = "Play";
PlaybackTimer.Enabled = false;
}
else
{
Playing = true;
PlayStopButton.Text = "Stop";
PlaybackTimer.Enabled = true;
}
}
private void PlaybackTimer_Tick(object sender, EventArgs e)
{
if (Playing)
{
UpdateTimeTrackBar();
UpdateTimeLabel();
}
}
}
[TypeConverter(typeof(ExpandableObjectConverter))] public class Cutscene
{
public CutFile CutFile { get; set; } = null;
private GameFileCache GameFileCache = null;
public float[] CameraCutList { get; set; } = null;
public YcdFile[] Ycds { get; set; } = null;
public float Duration { get; set; } = 0.0f;
public float PlaybackTime { get; set; } = 0.0f;
public Dictionary<int, CutObject> Objects { get; set; } = null;
public Dictionary<int, CutsceneObject> SceneObjects { get; set; } = null;
public CutEvent[] LoadEvents { get; set; } = null;
public CutEvent[] PlayEvents { get; set; } = null;
public int NextLoadEvent { get; set; } = 0;
public int NextPlayEvent { get; set; } = 0;
public int NextCameraCut { get; set; } = 0;
public Gxt2File Gxt2File { get; set; } = null;
public Vector3 Position { get; set; }
public Quaternion Rotation { get; set; }
public CutsceneObject CameraObject = null;
public void Init(CutFile cutFile, GameFileCache gfc)
{
CutFile = cutFile;
GameFileCache = gfc;
var csf = cutFile?.CutsceneFile2;
if (csf == null) return;
if (gfc == null) return;
Duration = csf.fTotalDuration;
CameraCutList = csf.cameraCutList;
Position = csf.vOffset;
Rotation = Quaternion.RotationAxis(Vector3.UnitZ, csf.fRotation);
Objects = csf.ObjectsDict;
LoadEvents = RecastArray<CutEvent>(csf.pCutsceneLoadEventList);
PlayEvents = RecastArray<CutEvent>(csf.pCutsceneEventList);
LoadYcds();
CreateSceneObjects();
RaiseEvents(0.0f);
}
private void LoadYcds()
{
int cutListCount = (CameraCutList?.Length ?? 0) + 1;
var shortName = CutFile.FileEntry?.GetShortNameLower() ?? "";
Ycds = new YcdFile[cutListCount];
if (!string.IsNullOrEmpty(shortName))
{
for (int i = 0; i < cutListCount; i++)
{
var ycdname = shortName + "-" + i.ToString();
var ycdhash = JenkHash.GenHash(ycdname);
var ycd = GameFileCache.GetYcd(ycdhash);
while ((ycd != null) && (!ycd.Loaded))
{
Thread.Sleep(20);//bite me
ycd = GameFileCache.GetYcd(ycdhash);
}
if (ycd != null)
{
ycd.BuildCutsceneMap(i);
}
Ycds[i] = ycd;
}
}
}
public void Update(float newTime)
{
if (newTime >= PlaybackTime)
{
RaiseEvents(newTime);
}
else
{
//reset playback to beginning, and seek to newTime
}
PlaybackTime = newTime;
int cutIndex = 0;
float cutStart = 0.0f;
for (cutIndex = 0; cutIndex < CameraCutList?.Length; cutIndex++)
{
var cutTime = CameraCutList[cutIndex];
if (cutTime > newTime) break;
cutStart = cutTime;
}
float cutOffset = newTime - cutStart;//offset into the current cut
var ycd = (cutIndex < (Ycds?.Length ?? 0)) ? Ycds[cutIndex] : null;
if (ycd?.CutsceneMap != null)
{
if (CameraObject != null)
{
ClipMapEntry cme = null;
ycd.CutsceneMap.TryGetValue(CameraObject.Name, out cme);
if (cme != null)
{
if (cme.Clip is ClipAnimation canim)
{
if (canim.Animation != null)
{
var t = canim.GetPlaybackTime(PlaybackTime);
var f = canim.Animation.GetFramePosition(t);
var p = canim.Animation.FindBoneIndex(0, 7);//camera position
var r = canim.Animation.FindBoneIndex(0, 8);//camera rotation
if (p >= 0) CameraObject.Position = canim.Animation.EvaluateVector4(f, p, true).XYZ();
if (r >= 0) CameraObject.Rotation = canim.Animation.EvaluateQuaternion(f, r, true);
}
}
}
//var animname = CameraObject.Name.ToString() + "-" + cutIndex.ToString();
//MetaHash animhash = JenkHash.GenHash()
}
}
}
private void RaiseEvents(float upToTime)
{
int i;
for (i = NextLoadEvent; i < LoadEvents?.Length; i++)
{
var e = LoadEvents[i];
if (e != null)
{
if (e.fTime > upToTime) break;
RaiseEvent(e);
}
}
NextLoadEvent = i;
for (i = NextPlayEvent; i < PlayEvents?.Length; i++)
{
var e = PlayEvents[i];
if (e != null)
{
if (e.fTime > upToTime) break;
RaiseEvent(e);
}
}
NextPlayEvent = i;
for (i = NextCameraCut; i < CameraCutList?.Length; i++)
{
var c = CameraCutList[i];
if (c > upToTime) break;
}
NextCameraCut = i;
}
private void RaiseEvent(CutEvent e)
{
switch (e.iEventId)
{
case CutEventType.LoadScene: LoadScene(e); break;
case CutEventType.LoadAnimation: LoadAnimation(e); break;
case CutEventType.LoadAudio: LoadAudio(e); break;
case CutEventType.LoadModels: LoadModels(e); break;
case CutEventType.LoadRayfireDes: LoadRayfireDes(e); break;
case CutEventType.LoadParticles: LoadParticles(e); break;
case CutEventType.LoadOverlays: LoadOverlays(e); break;
case CutEventType.LoadGxt2: LoadGxt2(e); break;
case CutEventType.UnloadModels: UnloadModels(e); break;
case CutEventType.UnloadRayfireDes: UnloadRayfireDes(e); break;
case CutEventType.EnableScreenFade: EnableScreenFade(e); break;
case CutEventType.EnableHideObject: EnableHideObject(e); break;
case CutEventType.EnableFixupModel: EnableFixupModel(e); break;
case CutEventType.EnableBlockBounds: EnableBlockBounds(e); break;
case CutEventType.EnableAnimation: EnableAnimation(e); break;
case CutEventType.EnableParticleEffect: EnableParticleEffect(e); break;
case CutEventType.EnableOverlay: EnableOverlay(e); break;
case CutEventType.EnableAudio: EnableAudio(e); break;
case CutEventType.EnableCamera: EnableCamera(e); break;
case CutEventType.EnableLight: EnableLight(e); break;
case CutEventType.DisableScreenFade: DisableScreenFade(e); break;
case CutEventType.DisableHideObject: DisableHideObject(e); break;
case CutEventType.DisableBlockBounds: DisableBlockBounds(e); break;
case CutEventType.DisableAnimation: DisableAnimation(e); break;
case CutEventType.DisableParticleEffect: DisableParticleEffect(e); break;
case CutEventType.DisableOverlay: DisableOverlay(e); break;
case CutEventType.DisableAudio: DisableAudio(e); break;
case CutEventType.DisableCamera: DisableCamera(e); break;
case CutEventType.DisableLight: DisableLight(e); break;
case CutEventType.Subtitle: Subtitle(e); break;
case CutEventType.PedVariation: PedVariation(e); break;
case CutEventType.CameraCut: CameraCut(e); break;
case CutEventType.CameraShadowCascade: CameraShadowCascade(e); break;
case CutEventType.CameraUnk1: CameraUnk1(e); break;
case CutEventType.CameraUnk2: CameraUnk2(e); break;
case CutEventType.CameraUnk3: CameraUnk3(e); break;
case CutEventType.CameraUnk4: CameraUnk4(e); break;
case CutEventType.CameraUnk5: CameraUnk5(e); break;
case CutEventType.CameraUnk6: CameraUnk6(e); break;
case CutEventType.CameraUnk7: CameraUnk7(e); break;
case CutEventType.CameraUnk8: CameraUnk8(e); break;
case CutEventType.DecalUnk1: DecalUnk1(e); break;
case CutEventType.DecalUnk2: DecalUnk2(e); break;
case CutEventType.PropUnk1: PropUnk1(e); break;
case CutEventType.Unk1: Unk1(e); break;
case CutEventType.Unk2: Unk2(e); break;
case CutEventType.VehicleUnk1: VehicleUnk1(e); break;
case CutEventType.PedUnk1: PedUnk1(e); break;
default: break;
}
}
private void LoadScene(CutEvent e)
{
var args = e.EventArgs as CutLoadSceneEventArgs;
if (args == null)
{ return; }
Position = args.vOffset;
Rotation = Quaternion.RotationAxis(Vector3.UnitZ, args.fRotation * 0.0174532925f);//is this right?
}
private void LoadAnimation(CutEvent e)
{
var args = e.EventArgs as CutNameEventArgs;
if (args == null)
{ return; }
}
private void LoadAudio(CutEvent e)
{
var args = e.EventArgs as CutNameEventArgs;
if (args == null)
{ return; }
}
private void LoadModels(CutEvent e)
{
var args = e.EventArgs as CutObjectIdListEventArgs;
if (args == null)
{ return; }
}
private void LoadRayfireDes(CutEvent e)
{
}
private void LoadParticles(CutEvent e)
{
var args = e.EventArgs as CutObjectIdListEventArgs;
if (args == null)
{ return; }
}
private void LoadOverlays(CutEvent e)
{
var args = e.EventArgs as CutObjectIdListEventArgs;
if (args == null)
{ return; }
}
private void LoadGxt2(CutEvent e)
{
if (GameFileCache == null)
{ return; }
if (Gxt2File != null)
{ }
var args = e.EventArgs as CutFinalNameEventArgs;
if (args == null)
{ return; }
var namel = args.cName?.ToLowerInvariant();
var namehash = JenkHash.GenHash(namel);
RpfFileEntry gxt2entry = null;
GameFileCache.Gxt2Dict.TryGetValue(namehash, out gxt2entry);
if (gxt2entry != null) //probably should do this load async
{
Gxt2File = GameFileCache.RpfMan.GetFile<Gxt2File>(gxt2entry);
if (Gxt2File != null)
{
for (int i = 0; i < Gxt2File.TextEntries.Length; i++)
{
var te = Gxt2File.TextEntries[i];
GlobalText.Ensure(te.Text, te.Hash);
}
}
}
}
private void UnloadModels(CutEvent e)
{
var args = e.EventArgs as CutObjectIdListEventArgs;
if (args == null)
{ return; }
}
private void UnloadRayfireDes(CutEvent e)
{
}
private void EnableHideObject(CutEvent e)
{
var args = e.EventArgs as CutObjectIdEventArgs;
if (args == null)
{ return; }
var obj = args.Object;
}
private void EnableFixupModel(CutEvent e)
{
}
private void EnableBlockBounds(CutEvent e)
{
var args = e.EventArgs as CutObjectIdEventArgs;
if (args == null)
{ return; }
var obj = args.Object;
}
private void EnableScreenFade(CutEvent e)
{
}
private void EnableAnimation(CutEvent e)
{
var args = e.EventArgs as CutObjectIdEventArgs;
if (args == null)
{ return; }
var obj = args.Object;
}
private void EnableParticleEffect(CutEvent e)
{
}
private void EnableOverlay(CutEvent e)
{
}
private void EnableAudio(CutEvent e)
{
var args = e.EventArgs as CutNameEventArgs;
if (args == null)
{ return; }
}
private void EnableCamera(CutEvent e)
{
var args = e.EventArgs as CutObjectIdEventArgs;
if (args == null)
{ return; }
var obj = args.Object;
}
private void EnableLight(CutEvent e)
{
}
private void DisableHideObject(CutEvent e)
{
var args = e.EventArgs as CutObjectIdEventArgs;
if (args == null)
{ return; }
var obj = args.Object;
}
private void DisableBlockBounds(CutEvent e)
{
var args = e.EventArgs as CutObjectIdEventArgs;
if (args == null)
{ return; }
var obj = args.Object;
}
private void DisableScreenFade(CutEvent e)
{
}
private void DisableAnimation(CutEvent e)
{
var args = e.EventArgs as CutObjectIdEventArgs;
if (args == null)
{ return; }
var obj = args.Object;
}
private void DisableParticleEffect(CutEvent e)
{
}
private void DisableOverlay(CutEvent e)
{
}
private void DisableAudio(CutEvent e)
{
var args = e.EventArgs as CutNameEventArgs;
if (args == null)
{ return; }
}
private void DisableCamera(CutEvent e)
{
var args = e.EventArgs as CutObjectIdEventArgs;
if (args == null)
{ return; }
var obj = args.Object;
}
private void DisableLight(CutEvent e)
{
}
private void Subtitle(CutEvent e)
{
var args = e.EventArgs as CutSubtitleEventArgs;
if (args == null)
{ return; }
}
private void PedVariation(CutEvent e)
{
var args = e.EventArgs as CutObjectVariationEventArgs;
if (args == null)
{ return; }
var oe = e as CutObjectIdEvent;
if (oe == null)
{ return; }
}
private void CameraCut(CutEvent e)
{
var args = e.EventArgs as CutCameraCutEventArgs;
if (args == null)
{ return; }
var oe = e as CutObjectIdEvent;
if (oe == null)
{ return; }
CutsceneObject obj = null;
SceneObjects.TryGetValue(oe.iObjectId, out obj);
if (obj == null)
{ return; }
obj.Position = args.vPosition;
obj.Rotation = args.vRotationQuaternion;
CameraObject = obj;
}
private void CameraShadowCascade(CutEvent e)
{
}
private void CameraUnk1(CutEvent e)
{
}
private void CameraUnk2(CutEvent e)
{
}
private void CameraUnk3(CutEvent e)
{
}
private void CameraUnk4(CutEvent e)
{
}
private void CameraUnk5(CutEvent e)
{
}
private void CameraUnk6(CutEvent e)
{
}
private void CameraUnk7(CutEvent e)
{
}
private void CameraUnk8(CutEvent e)
{
}
private void DecalUnk1(CutEvent e)
{
}
private void DecalUnk2(CutEvent e)
{
}
private void PropUnk1(CutEvent e)
{
}
private void Unk1(CutEvent e)
{
}
private void Unk2(CutEvent e)
{
}
private void VehicleUnk1(CutEvent e)
{
}
private void PedUnk1(CutEvent e)
{
}
private T[] RecastArray<T>(object[] arr) where T : class
{
if (arr == null) return null;
var r = new T[arr.Length];
for (int i = 0; i < arr.Length; i++)
{
r[i] = arr[i] as T;
}
return r;
}
private void CreateSceneObjects()
{
SceneObjects = new Dictionary<int, CutsceneObject>();
if (Objects == null) return;
foreach (var obj in Objects.Values)
{
var sobj = new CutsceneObject();
sobj.Init(obj);
SceneObjects[sobj.ObjectID] = sobj;
}
}
}
[TypeConverter(typeof(ExpandableObjectConverter))] public class CutsceneObject
{
public int ObjectID { get; set; }
public CutObject CutObject { get; set; }
public MetaHash Name { get; set; }
public Vector3 Position { get; set; }
public Quaternion Rotation { get; set; }
public void Init(CutObject obj)
{
CutObject = obj;
ObjectID = obj?.iObjectId ?? -1;
if (obj is CutNamedObject nobj)
{
Name = nobj.cName;
}
if (obj is CutAnimationManagerObject anim)
{
}
else if (obj is CutAssetManagerObject ass)
{
}
else if (obj is CutCameraObject cam)
{
}
else if (obj is CutPedModelObject ped)
{
}
else if (obj is CutPropModelObject prop)
{
}
else if (obj is CutVehicleModelObject veh)
{
}
else if (obj is CutWeaponModelObject weap)
{
}
else if (obj is CutHiddenModelObject hid)
{
}
else if (obj is CutFixupModelObject fix)
{
}
else if (obj is CutRayfireObject rayf)
{
}
else if (obj is CutParticleEffectObject eff)
{
}
else if (obj is CutAnimatedParticleEffectObject aeff)
{
}
else if (obj is CutLightObject light)
{
}
else if (obj is CutAnimatedLightObject alight)
{
}
else if (obj is CutDecalObject dec)
{
}
else if (obj is CutOverlayObject ovr)
{
}
else if (obj is CutAudioObject aud)
{
}
else if (obj is CutSubtitleObject sub)
{
}
else if (obj is CutBlockingBoundsObject blk)
{
}
else if (obj is CutScreenFadeObject fad)
{
}
else
{ }
}
public override string ToString()
{
return CutObject?.ToString() ?? (ObjectID.ToString() + ": " + Name.ToString());
}
}
}

412
World/CutsceneForm.resx Normal file
View File

@ -0,0 +1,412 @@
<?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>
<metadata name="PlaybackTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<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>

201
WorldForm.Designer.cs generated
View File

@ -136,6 +136,10 @@ namespace CodeWalker
this.TimedEntitiesCheckBox = new System.Windows.Forms.CheckBox();
this.FieldOfViewTrackBar = new System.Windows.Forms.TrackBar();
this.tabPage14 = new System.Windows.Forms.TabPage();
this.FarClipUpDown = new System.Windows.Forms.NumericUpDown();
this.label32 = new System.Windows.Forms.Label();
this.NearClipUpDown = new System.Windows.Forms.NumericUpDown();
this.label31 = new System.Windows.Forms.Label();
this.HDTexturesCheckBox = new System.Windows.Forms.CheckBox();
this.WireframeCheckBox = new System.Windows.Forms.CheckBox();
this.RenderModeComboBox = new System.Windows.Forms.ComboBox();
@ -288,10 +292,7 @@ namespace CodeWalker
this.ToolbarCameraMapViewButton = new System.Windows.Forms.ToolStripMenuItem();
this.ToolbarCameraOrthographicButton = new System.Windows.Forms.ToolStripMenuItem();
this.ToolbarPanel = new System.Windows.Forms.Panel();
this.NearClipUpDown = new System.Windows.Forms.NumericUpDown();
this.label31 = new System.Windows.Forms.Label();
this.FarClipUpDown = new System.Windows.Forms.NumericUpDown();
this.label32 = new System.Windows.Forms.Label();
this.ToolsMenuCutsceneViewer = new System.Windows.Forms.ToolStripMenuItem();
this.StatusStrip.SuspendLayout();
this.ToolsPanel.SuspendLayout();
this.ToolsTabControl.SuspendLayout();
@ -321,6 +322,8 @@ namespace CodeWalker
((System.ComponentModel.ISupportInitialize)(this.CollisionMeshRangeTrackBar)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.FieldOfViewTrackBar)).BeginInit();
this.tabPage14.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.FarClipUpDown)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.NearClipUpDown)).BeginInit();
this.tabPage9.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.SnapGridSizeUpDown)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.BoundsRangeTrackBar)).BeginInit();
@ -333,8 +336,6 @@ namespace CodeWalker
this.ToolsMenu.SuspendLayout();
this.Toolbar.SuspendLayout();
this.ToolbarPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.NearClipUpDown)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.FarClipUpDown)).BeginInit();
this.SuspendLayout();
//
// StatusStrip
@ -1673,6 +1674,81 @@ namespace CodeWalker
this.tabPage14.Text = "Render";
this.tabPage14.UseVisualStyleBackColor = true;
//
// FarClipUpDown
//
this.FarClipUpDown.Increment = new decimal(new int[] {
100,
0,
0,
0});
this.FarClipUpDown.Location = new System.Drawing.Point(80, 346);
this.FarClipUpDown.Maximum = new decimal(new int[] {
100000,
0,
0,
0});
this.FarClipUpDown.Minimum = new decimal(new int[] {
100,
0,
0,
0});
this.FarClipUpDown.Name = "FarClipUpDown";
this.FarClipUpDown.Size = new System.Drawing.Size(114, 20);
this.FarClipUpDown.TabIndex = 61;
this.FarClipUpDown.Value = new decimal(new int[] {
12000,
0,
0,
0});
this.FarClipUpDown.ValueChanged += new System.EventHandler(this.FarClipUpDown_ValueChanged);
//
// label32
//
this.label32.AutoSize = true;
this.label32.Location = new System.Drawing.Point(4, 348);
this.label32.Name = "label32";
this.label32.Size = new System.Drawing.Size(45, 13);
this.label32.TabIndex = 60;
this.label32.Text = "Far Clip:";
//
// NearClipUpDown
//
this.NearClipUpDown.DecimalPlaces = 3;
this.NearClipUpDown.Increment = new decimal(new int[] {
1,
0,
0,
65536});
this.NearClipUpDown.Location = new System.Drawing.Point(80, 320);
this.NearClipUpDown.Maximum = new decimal(new int[] {
10,
0,
0,
0});
this.NearClipUpDown.Minimum = new decimal(new int[] {
1,
0,
0,
196608});
this.NearClipUpDown.Name = "NearClipUpDown";
this.NearClipUpDown.Size = new System.Drawing.Size(114, 20);
this.NearClipUpDown.TabIndex = 59;
this.NearClipUpDown.Value = new decimal(new int[] {
5,
0,
0,
65536});
this.NearClipUpDown.ValueChanged += new System.EventHandler(this.NearClipUpDown_ValueChanged);
//
// label31
//
this.label31.AutoSize = true;
this.label31.Location = new System.Drawing.Point(4, 322);
this.label31.Name = "label31";
this.label31.Size = new System.Drawing.Size(53, 13);
this.label31.TabIndex = 58;
this.label31.Text = "Near Clip:";
//
// HDTexturesCheckBox
//
this.HDTexturesCheckBox.AutoSize = true;
@ -2594,6 +2670,7 @@ namespace CodeWalker
this.ToolsMenuRPFExplorer,
this.ToolsMenuSelectionInfo,
this.ToolsMenuProjectWindow,
this.ToolsMenuCutsceneViewer,
this.ToolsMenuWorldSearch,
this.ToolsMenuBinarySearch,
this.ToolsMenuJenkGen,
@ -2604,12 +2681,12 @@ namespace CodeWalker
this.ToolsMenuExtractShaders,
this.ToolsMenuOptions});
this.ToolsMenu.Name = "ToolsMenu";
this.ToolsMenu.Size = new System.Drawing.Size(166, 290);
this.ToolsMenu.Size = new System.Drawing.Size(181, 334);
//
// ToolsMenuRPFBrowser
//
this.ToolsMenuRPFBrowser.Name = "ToolsMenuRPFBrowser";
this.ToolsMenuRPFBrowser.Size = new System.Drawing.Size(165, 22);
this.ToolsMenuRPFBrowser.Size = new System.Drawing.Size(180, 22);
this.ToolsMenuRPFBrowser.Text = "RPF Browser...";
this.ToolsMenuRPFBrowser.Visible = false;
this.ToolsMenuRPFBrowser.Click += new System.EventHandler(this.ToolsMenuRPFBrowser_Click);
@ -2617,14 +2694,14 @@ namespace CodeWalker
// ToolsMenuRPFExplorer
//
this.ToolsMenuRPFExplorer.Name = "ToolsMenuRPFExplorer";
this.ToolsMenuRPFExplorer.Size = new System.Drawing.Size(165, 22);
this.ToolsMenuRPFExplorer.Size = new System.Drawing.Size(180, 22);
this.ToolsMenuRPFExplorer.Text = "RPF Explorer...";
this.ToolsMenuRPFExplorer.Click += new System.EventHandler(this.ToolsMenuRPFExplorer_Click);
//
// ToolsMenuSelectionInfo
//
this.ToolsMenuSelectionInfo.Name = "ToolsMenuSelectionInfo";
this.ToolsMenuSelectionInfo.Size = new System.Drawing.Size(165, 22);
this.ToolsMenuSelectionInfo.Size = new System.Drawing.Size(180, 22);
this.ToolsMenuSelectionInfo.Text = "Selection info...";
this.ToolsMenuSelectionInfo.Click += new System.EventHandler(this.ToolsMenuSelectionInfo_Click);
//
@ -2632,14 +2709,14 @@ namespace CodeWalker
//
this.ToolsMenuProjectWindow.Enabled = false;
this.ToolsMenuProjectWindow.Name = "ToolsMenuProjectWindow";
this.ToolsMenuProjectWindow.Size = new System.Drawing.Size(165, 22);
this.ToolsMenuProjectWindow.Size = new System.Drawing.Size(180, 22);
this.ToolsMenuProjectWindow.Text = "Project window...";
this.ToolsMenuProjectWindow.Click += new System.EventHandler(this.ToolsMenuProjectWindow_Click);
//
// ToolsMenuWorldSearch
//
this.ToolsMenuWorldSearch.Name = "ToolsMenuWorldSearch";
this.ToolsMenuWorldSearch.Size = new System.Drawing.Size(165, 22);
this.ToolsMenuWorldSearch.Size = new System.Drawing.Size(180, 22);
this.ToolsMenuWorldSearch.Text = "World search...";
this.ToolsMenuWorldSearch.Click += new System.EventHandler(this.ToolsMenuWorldSearch_Click);
//
@ -2647,14 +2724,14 @@ namespace CodeWalker
//
this.ToolsMenuBinarySearch.Enabled = false;
this.ToolsMenuBinarySearch.Name = "ToolsMenuBinarySearch";
this.ToolsMenuBinarySearch.Size = new System.Drawing.Size(165, 22);
this.ToolsMenuBinarySearch.Size = new System.Drawing.Size(180, 22);
this.ToolsMenuBinarySearch.Text = "Binary search...";
this.ToolsMenuBinarySearch.Click += new System.EventHandler(this.ToolsMenuBinarySearch_Click);
//
// ToolsMenuJenkGen
//
this.ToolsMenuJenkGen.Name = "ToolsMenuJenkGen";
this.ToolsMenuJenkGen.Size = new System.Drawing.Size(165, 22);
this.ToolsMenuJenkGen.Size = new System.Drawing.Size(180, 22);
this.ToolsMenuJenkGen.Text = "JenkGen...";
this.ToolsMenuJenkGen.Click += new System.EventHandler(this.ToolsMenuJenkGen_Click);
//
@ -2662,42 +2739,42 @@ namespace CodeWalker
//
this.ToolsMenuJenkInd.Enabled = false;
this.ToolsMenuJenkInd.Name = "ToolsMenuJenkInd";
this.ToolsMenuJenkInd.Size = new System.Drawing.Size(165, 22);
this.ToolsMenuJenkInd.Size = new System.Drawing.Size(180, 22);
this.ToolsMenuJenkInd.Text = "JenkInd...";
this.ToolsMenuJenkInd.Click += new System.EventHandler(this.ToolsMenuJenkInd_Click);
//
// ToolsMenuExtractScripts
//
this.ToolsMenuExtractScripts.Name = "ToolsMenuExtractScripts";
this.ToolsMenuExtractScripts.Size = new System.Drawing.Size(165, 22);
this.ToolsMenuExtractScripts.Size = new System.Drawing.Size(180, 22);
this.ToolsMenuExtractScripts.Text = "Extract scripts...";
this.ToolsMenuExtractScripts.Click += new System.EventHandler(this.ToolsMenuExtractScripts_Click);
//
// ToolsMenuExtractTextures
//
this.ToolsMenuExtractTextures.Name = "ToolsMenuExtractTextures";
this.ToolsMenuExtractTextures.Size = new System.Drawing.Size(165, 22);
this.ToolsMenuExtractTextures.Size = new System.Drawing.Size(180, 22);
this.ToolsMenuExtractTextures.Text = "Extract textures...";
this.ToolsMenuExtractTextures.Click += new System.EventHandler(this.ToolsMenuExtractTextures_Click);
//
// ToolsMenuExtractRawFiles
//
this.ToolsMenuExtractRawFiles.Name = "ToolsMenuExtractRawFiles";
this.ToolsMenuExtractRawFiles.Size = new System.Drawing.Size(165, 22);
this.ToolsMenuExtractRawFiles.Size = new System.Drawing.Size(180, 22);
this.ToolsMenuExtractRawFiles.Text = "Extract raw files...";
this.ToolsMenuExtractRawFiles.Click += new System.EventHandler(this.ToolsMenuExtractRawFiles_Click);
//
// ToolsMenuExtractShaders
//
this.ToolsMenuExtractShaders.Name = "ToolsMenuExtractShaders";
this.ToolsMenuExtractShaders.Size = new System.Drawing.Size(165, 22);
this.ToolsMenuExtractShaders.Size = new System.Drawing.Size(180, 22);
this.ToolsMenuExtractShaders.Text = "Extract shaders...";
this.ToolsMenuExtractShaders.Click += new System.EventHandler(this.ToolsMenuExtractShaders_Click);
//
// ToolsMenuOptions
//
this.ToolsMenuOptions.Name = "ToolsMenuOptions";
this.ToolsMenuOptions.Size = new System.Drawing.Size(165, 22);
this.ToolsMenuOptions.Size = new System.Drawing.Size(180, 22);
this.ToolsMenuOptions.Text = "Options...";
this.ToolsMenuOptions.Click += new System.EventHandler(this.ToolsMenuOptions_Click);
//
@ -3306,80 +3383,13 @@ namespace CodeWalker
this.ToolbarPanel.TabIndex = 7;
this.ToolbarPanel.Visible = false;
//
// NearClipUpDown
// ToolsMenuCutsceneViewer
//
this.NearClipUpDown.DecimalPlaces = 3;
this.NearClipUpDown.Increment = new decimal(new int[] {
1,
0,
0,
65536});
this.NearClipUpDown.Location = new System.Drawing.Point(80, 320);
this.NearClipUpDown.Maximum = new decimal(new int[] {
10,
0,
0,
0});
this.NearClipUpDown.Minimum = new decimal(new int[] {
1,
0,
0,
196608});
this.NearClipUpDown.Name = "NearClipUpDown";
this.NearClipUpDown.Size = new System.Drawing.Size(114, 20);
this.NearClipUpDown.TabIndex = 59;
this.NearClipUpDown.Value = new decimal(new int[] {
5,
0,
0,
65536});
this.NearClipUpDown.ValueChanged += new System.EventHandler(this.NearClipUpDown_ValueChanged);
//
// label31
//
this.label31.AutoSize = true;
this.label31.Location = new System.Drawing.Point(4, 322);
this.label31.Name = "label31";
this.label31.Size = new System.Drawing.Size(53, 13);
this.label31.TabIndex = 58;
this.label31.Text = "Near Clip:";
//
// FarClipUpDown
//
this.FarClipUpDown.Increment = new decimal(new int[] {
100,
0,
0,
0});
this.FarClipUpDown.Location = new System.Drawing.Point(80, 346);
this.FarClipUpDown.Maximum = new decimal(new int[] {
100000,
0,
0,
0});
this.FarClipUpDown.Minimum = new decimal(new int[] {
100,
0,
0,
0});
this.FarClipUpDown.Name = "FarClipUpDown";
this.FarClipUpDown.Size = new System.Drawing.Size(114, 20);
this.FarClipUpDown.TabIndex = 61;
this.FarClipUpDown.Value = new decimal(new int[] {
12000,
0,
0,
0});
this.FarClipUpDown.ValueChanged += new System.EventHandler(this.FarClipUpDown_ValueChanged);
//
// label32
//
this.label32.AutoSize = true;
this.label32.Location = new System.Drawing.Point(4, 348);
this.label32.Name = "label32";
this.label32.Size = new System.Drawing.Size(45, 13);
this.label32.TabIndex = 60;
this.label32.Text = "Far Clip:";
this.ToolsMenuCutsceneViewer.Enabled = false;
this.ToolsMenuCutsceneViewer.Name = "ToolsMenuCutsceneViewer";
this.ToolsMenuCutsceneViewer.Size = new System.Drawing.Size(180, 22);
this.ToolsMenuCutsceneViewer.Text = "Cutscene viewer...";
this.ToolsMenuCutsceneViewer.Click += new System.EventHandler(this.ToolsMenuCutsceneViewer_Click);
//
// WorldForm
//
@ -3444,6 +3454,8 @@ namespace CodeWalker
((System.ComponentModel.ISupportInitialize)(this.FieldOfViewTrackBar)).EndInit();
this.tabPage14.ResumeLayout(false);
this.tabPage14.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.FarClipUpDown)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.NearClipUpDown)).EndInit();
this.tabPage9.ResumeLayout(false);
this.tabPage9.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.SnapGridSizeUpDown)).EndInit();
@ -3462,8 +3474,6 @@ namespace CodeWalker
this.Toolbar.PerformLayout();
this.ToolbarPanel.ResumeLayout(false);
this.ToolbarPanel.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.NearClipUpDown)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.FarClipUpDown)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
@ -3731,5 +3741,6 @@ namespace CodeWalker
private System.Windows.Forms.Label label32;
private System.Windows.Forms.NumericUpDown NearClipUpDown;
private System.Windows.Forms.Label label31;
private System.Windows.Forms.ToolStripMenuItem ToolsMenuCutsceneViewer;
}
}

View File

@ -197,6 +197,7 @@ namespace CodeWalker
WorldSearchForm SearchForm = null;
CutsceneForm CutsceneForm = null;
InputManager Input = new InputManager();
@ -404,7 +405,10 @@ namespace CodeWalker
space.Update(elapsed);
if (CutsceneForm != null)
{
CutsceneForm.UpdateAnimation(elapsed);
}
Renderer.Update(elapsed, MouseLastPoint.X, MouseLastPoint.Y);
@ -678,6 +682,10 @@ namespace CodeWalker
ProjectForm.GetVisibleYmaps(camera, renderworldVisibleYmapDict);
}
if (CutsceneForm != null)
{
CutsceneForm.GetVisibleYmaps(camera, renderworldVisibleYmapDict);
}
Renderer.RenderWorld(renderworldVisibleYmapDict, spaceEnts);
@ -1876,6 +1884,15 @@ namespace CodeWalker
}
public void SetCameraTransform(Vector3 pos, Quaternion rot)
{
camera.FollowEntity.Position = pos;
camera.FollowEntity.Orientation = rot;
camera.FollowEntity.OrientationInv = Quaternion.Invert(rot);
camera.TargetRotation = Vector3.Zero;
camera.TargetDistance = 0.01f;
}
public Vector3 GetCameraPosition()
{
//currently used by ProjectForm when creating entities
@ -4098,6 +4115,29 @@ namespace CodeWalker
//ToolbarSearchWindowButton.Checked = false;
}
private void ShowCutsceneForm()
{
if (CutsceneForm == null)
{
CutsceneForm = new CutsceneForm(this);
CutsceneForm.Show(this);
}
else
{
if (CutsceneForm.WindowState == FormWindowState.Minimized)
{
CutsceneForm.WindowState = FormWindowState.Normal;
}
CutsceneForm.Focus();
}
//ToolbarCutsceneWindowButton.Checked = true;
}
public void OnCutsceneFormClosed()
{
CutsceneForm = null;
//ToolbarCutsceneWindowButton.Checked = false;
}
public void ShowModel(string name)
{
ViewModeComboBox.Text = "Model view";
@ -4904,6 +4944,7 @@ namespace CodeWalker
ToolbarOpenButton.Enabled = true;
ToolbarProjectWindowButton.Enabled = true;
ToolsMenuProjectWindow.Enabled = true;
ToolsMenuCutsceneViewer.Enabled = true;
ToolsMenuBinarySearch.Enabled = true;
ToolsMenuJenkInd.Enabled = true;
}
@ -6984,6 +7025,11 @@ namespace CodeWalker
ShowProjectForm();
}
private void ToolsMenuCutsceneViewer_Click(object sender, EventArgs e)
{
ShowCutsceneForm();
}
private void ToolsMenuWorldSearch_Click(object sender, EventArgs e)
{
ShowSearchForm();

View File

@ -240,14 +240,6 @@ ufo
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB4SURBVDhP3ZC7DcAgDEQZKTMwHOvSIFriS7BlEB+HMic9
QJbvFThLUkpXzjkSpaeuzMPlEELx3jdsBauyCHBY6UWYPQI93KEljQD3jL6EGzN6x0bASyNYwkKU8Udm
gd6TMnIikDJyIqjVNz8T7FgKrAwFX6lVinM3aJ05lWDPRRcAAAAASUVORK5CYII=
</value>
</data>
<data name="ToolbarTransformSpaceButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB0SURBVDhP7ZNBCoAgEEXnSJ3BqxmetNpaMLhVv5DNRJS2
CxIeuvA9XSjtg5mHEILPxB6U7JyLxphmSkDK1o5x9dst87SUfTXwRsYsA+paT0BGDGsVOJ92hdz3Bz4f
wGPC48uu7w5IGd+gBlpRMgYCnRwyESUj3CsQkYNFDwAAAABJRU5ErkJggg==
</value>
</data>
<data name="ToolbarObjectSpaceButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
@ -269,13 +261,12 @@ ufo
WBXYx9R1nV75RuyHKrrnzCcGjE1u9ZyD4BugoZigQ9xrngAAAABJRU5ErkJggg==
</value>
</data>
<data name="ToolbarSnapButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="ToolbarTransformSpaceButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACtSURBVDhPrZBBEsIgEAR5Gy/wFV55T/wHr+KgHuCKNsVY
ZI2JiU7VVIVlp7OL+1mllIr7cb8Ie++PQwQYITnnM24NWxoBgsQYm/l+gk699bMsRA4h1JTSPsg0Xert
em/mGwh3vW1Z7MvIABSWqXG3+iZHAEw1m4wD49oVANgVOL/VeSgeDAiX1mpWeKy9BIQiI+OxWQF77tG5
2Fc729BmeElf/3lNhORe+oecewDObEqX49RqCgAAAABJRU5ErkJggg==
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB0SURBVDhP7ZNBCoAgEEXnSJ3BqxmetNpaMLhVv5DNRJS2
CxIeuvA9XSjtg5mHEILPxB6U7JyLxphmSkDK1o5x9dst87SUfTXwRsYsA+paT0BGDGsVOJ92hdz3Bz4f
wGPC48uu7w5IGd+gBlpRMgYCnRwyESUj3CsQkYNFDwAAAABJRU5ErkJggg==
</value>
</data>
<data name="ToolbarSnapToGroundButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
@ -304,6 +295,15 @@ ufo
EcMw2DzPDMEke9AsYBrHs10vN4I1QqImwwDcFyMjQGaBHr5Bo8nEoYCnCQTGzVeI4oj6fIi+KHgoPBhC
4knCjTww9vxfbIUQNDEyiGIZ8t6tW/k0vC/AOpuiueNOLwVkUeylvju9FJCg8E1vM/2PlTv5UoervVTJ
uQAAAABJRU5ErkJggg==
</value>
</data>
<data name="ToolbarSnapButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACtSURBVDhPrZBBEsIgEAR5Gy/wFV55T/wHr+KgHuCKNsVY
ZI2JiU7VVIVlp7OL+1mllIr7cb8Ie++PQwQYITnnM24NWxoBgsQYm/l+gk699bMsRA4h1JTSPsg0Xert
em/mGwh3vW1Z7MvIABSWqXG3+iZHAEw1m4wD49oVANgVOL/VeSgeDAiX1mpWeKy9BIQiI+OxWQF77tG5
2Fc729BmeElf/3lNhORe+oecewDObEqX49RqCgAAAABJRU5ErkJggg==
</value>
</data>
<data name="ToolbarUndoButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
@ -389,17 +389,6 @@ ufo
4BJN+IjGo5O8ZJndGVhKxpjWWts551aih0fre+0BLaVchRAezPB2NXSSV/gVwXGYPJiVUt6ns1ghCDjn
UQG86w3FToVgDcWCWS9Fvi/Ao0RVAcwUjwpyhzmf4n8BFApS5HZRwRuONGMbrIJ1JIN8O2QAAAAASUVO
RK5CYII=
</value>
</data>
<data name="ToolbarCameraModeButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEvSURBVDhP3dK/K0dRGMfxKxRJopCSEkLya/guUhQRmQwG
WfwIkYySgYUSKUKJlOK/MBoMFMofYLUIsfJ+f3NuF3+A8tRree5zP/fcc070f6oHT/jAPTqQj6WvXvCM
TZQgG3H58gFGcYVLtGIN15jBNDbwiGNUIg4pQx8GsQuHhrCDW8yjHyns4Q0DcCXpykM5bFzgHGPYxw1G
UIVMtMHfWUUj4nIg/KurGIYrSAZYOXDGlbhXcZlegUO8Yxzb+BlQAwNW0G0jVAYK0AwHtnCEOyQDZvGC
ObTbKIIvLMA9WIYDizhFMsDjfsAZptCA9JcdfoVBvryOSbgCe4HPTuCz+BQMKEUvJmCy96ET1ehCuAf2
5ZF+uwdZKEYtmuBGFSIXhtejBe5PHX7dxL+qKPoEppRHcXOtiDsAAAAASUVORK5CYII=
</value>
</data>
<data name="ToolbarCameraPerspectiveButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
@ -435,6 +424,17 @@ ufo
rp3fhGJScIRLzKMLFTC9cMIu3nCDVUyjB6WkYA93mEWbAyH9cMImPuA+rWMA31YwBU82kF6BS32Er/aO
M8zAh+OEghpcwQ2bg3uwBW8ewFd7xQkm0IA4oaAS7bh2KHjBIZbhV/D6GJkFphrdcIP8lFrAGPwPOjCO
QdQiTqrAWNICd7gPnUj+xBKaU9dxfhTkjwV/FxU+AbsiGnc46OYIAAAAAElFTkSuQmCC
</value>
</data>
<data name="ToolbarCameraModeButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEvSURBVDhP3dK/K0dRGMfxKxRJopCSEkLya/guUhQRmQwG
WfwIkYySgYUSKUKJlOK/MBoMFMofYLUIsfJ+f3NuF3+A8tRree5zP/fcc070f6oHT/jAPTqQj6WvXvCM
TZQgG3H58gFGcYVLtGIN15jBNDbwiGNUIg4pQx8GsQuHhrCDW8yjHyns4Q0DcCXpykM5bFzgHGPYxw1G
UIVMtMHfWUUj4nIg/KurGIYrSAZYOXDGlbhXcZlegUO8Yxzb+BlQAwNW0G0jVAYK0AwHtnCEOyQDZvGC
ObTbKIIvLMA9WIYDizhFMsDjfsAZptCA9JcdfoVBvryOSbgCe4HPTuCz+BQMKEUvJmCy96ET1ehCuAf2
5ZF+uwdZKEYtmuBGFSIXhtejBe5PHX7dxL+qKPoEppRHcXOtiDsAAAAASUVORK5CYII=
</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">