diff --git a/CodeWalker.Core/CodeWalker.Core.csproj b/CodeWalker.Core/CodeWalker.Core.csproj index 5b267aa..440993b 100644 --- a/CodeWalker.Core/CodeWalker.Core.csproj +++ b/CodeWalker.Core/CodeWalker.Core.csproj @@ -61,6 +61,7 @@ + diff --git a/CodeWalker.Core/GameFiles/FileTypes/CarColsFile.cs b/CodeWalker.Core/GameFiles/FileTypes/CarColsFile.cs index 7625e29..09dc80b 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/CarColsFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/CarColsFile.cs @@ -44,7 +44,7 @@ namespace CodeWalker.GameFiles } else { - Xml = Encoding.UTF8.GetString(data); + Xml = TextUtil.GetUTF8Text(data); } XmlDocument xdoc = new XmlDocument(); diff --git a/CodeWalker.Core/GameFiles/FileTypes/CarVariationsFile.cs b/CodeWalker.Core/GameFiles/FileTypes/CarVariationsFile.cs index 6002c24..b092b39 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/CarVariationsFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/CarVariationsFile.cs @@ -43,7 +43,7 @@ namespace CodeWalker.GameFiles } else { - Xml = Encoding.UTF8.GetString(data); + Xml = TextUtil.GetUTF8Text(data); } XmlDocument xdoc = new XmlDocument(); diff --git a/CodeWalker.Core/GameFiles/FileTypes/GtxdFile.cs b/CodeWalker.Core/GameFiles/FileTypes/GtxdFile.cs index 4c47102..1d7932e 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/GtxdFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/GtxdFile.cs @@ -60,13 +60,7 @@ namespace CodeWalker.GameFiles else if (entry.NameLower.EndsWith(".meta")) { //required for update\x64\dlcpacks\mpheist\dlc.rpf\common\data\gtxd.meta and update\x64\dlcpacks\mpluxe\dlc.rpf\common\data\gtxd.meta - string bom = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble()); - string xml = Encoding.UTF8.GetString(data); - - if (xml.StartsWith(bom, StringComparison.Ordinal)) - { - xml = xml.Remove(0, bom.Length); - } + string xml = TextUtil.GetUTF8Text(data); LoadTxdRelationships(xml); Loaded = true; diff --git a/CodeWalker.Core/GameFiles/FileTypes/PedsFile.cs b/CodeWalker.Core/GameFiles/FileTypes/PedsFile.cs new file mode 100644 index 0000000..439134f --- /dev/null +++ b/CodeWalker.Core/GameFiles/FileTypes/PedsFile.cs @@ -0,0 +1,348 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SharpDX; +using System.IO; +using System.Xml; + +using TC = System.ComponentModel.TypeConverterAttribute; +using EXP = System.ComponentModel.ExpandableObjectConverter; + + +namespace CodeWalker.GameFiles +{ + [TC(typeof(EXP))] public class PedsFile : GameFile, PackedFile + { + public PsoFile Pso { get; set; } + public string Xml { get; set; } + + public CPedModelInfo__InitDataList InitDataList { get; set; } + + public PedsFile() : base(null, GameFileType.Peds) + { } + public PedsFile(RpfFileEntry entry) : base(entry, GameFileType.Peds) + { + } + + public void Load(byte[] data, RpfFileEntry entry) + { + RpfFileEntry = entry; + Name = entry.Name; + FilePath = Name; + + + + //can be PSO .ymt or XML .meta + MemoryStream ms = new MemoryStream(data); + if (PsoFile.IsPSO(ms)) + { + Pso = new PsoFile(); + Pso.Load(data); + Xml = PsoXml.GetXml(Pso); //yep let's just convert that to XML :P + } + else + { + Xml = TextUtil.GetUTF8Text(data); + } + + XmlDocument xdoc = new XmlDocument(); + if (!string.IsNullOrEmpty(Xml)) + { + try + { + xdoc.LoadXml(Xml); + } + catch (Exception ex) + { + var msg = ex.Message; + } + } + else + { } + + + if (xdoc.DocumentElement != null) + { + InitDataList = new CPedModelInfo__InitDataList(xdoc.DocumentElement); + } + + + + + Loaded = true; + } + } + + + + [TC(typeof(EXP))] public class CPedModelInfo__InitDataList + { + public string residentTxd { get; set; } + public string[] residentAnims { get; set; } + public CPedModelInfo__InitData[] InitDatas { get; set; } + public CTxdRelationship[] txdRelationships { get; set; } + public CMultiTxdRelationship[] multiTxdRelationships { get; set; } + + public CPedModelInfo__InitDataList(XmlNode node) + { + XmlNodeList items; + + residentTxd = Xml.GetChildInnerText(node, "residentTxd"); + + items = node.SelectSingleNode("residentAnims")?.SelectNodes("Item"); + if (items?.Count > 0) + { + residentAnims = new string[items.Count]; + for (int i = 0; i < items.Count; i++) + { + residentAnims[i] = items[i].InnerText; + } + } + items = node.SelectSingleNode("InitDatas")?.SelectNodes("Item"); + if (items?.Count > 0) + { + InitDatas = new CPedModelInfo__InitData[items.Count]; + for (int i = 0; i < items.Count; i++) + { + InitDatas[i] = new CPedModelInfo__InitData(items[i]); + } + } + items = node.SelectSingleNode("txdRelationships")?.SelectNodes("Item"); + if (items?.Count > 0) + { + txdRelationships = new CTxdRelationship[items.Count]; + for (int i = 0; i < items.Count; i++) + { + txdRelationships[i] = new CTxdRelationship(items[i]); + } + } + items = node.SelectSingleNode("multiTxdRelationships")?.SelectNodes("Item"); + if (items?.Count > 0) + { + multiTxdRelationships = new CMultiTxdRelationship[items.Count]; + for (int i = 0; i < items.Count; i++) + { + multiTxdRelationships[i] = new CMultiTxdRelationship(items[i]); + } + } + + } + } + + [TC(typeof(EXP))] public class CPedModelInfo__InitData + { + public string Name { get; set; } + public string PropsName { get; set; } + public string ClipDictionaryName { get; set; } + public string BlendShapeFileName { get; set; } + public string ExpressionSetName { get; set; } + public string ExpressionDictionaryName { get; set; } + public string ExpressionName { get; set; } + public string Pedtype { get; set; } + public string MovementClipSet { get; set; } + public string[] MovementClipSets { get; set; } + public string StrafeClipSet { get; set; } + public string MovementToStrafeClipSet { get; set; } + public string InjuredStrafeClipSet { get; set; } + public string FullBodyDamageClipSet { get; set; } + public string AdditiveDamageClipSet { get; set; } + public string DefaultGestureClipSet { get; set; } + public string FacialClipsetGroupName { get; set; } + public string DefaultVisemeClipSet { get; set; } + public string SidestepClipSet { get; set; } + public string PoseMatcherName { get; set; } + public string PoseMatcherProneName { get; set; } + public string GetupSetHash { get; set; } + public string CreatureMetadataName { get; set; } + public string DecisionMakerName { get; set; } + public string MotionTaskDataSetName { get; set; } + public string DefaultTaskDataSetName { get; set; } + public string PedCapsuleName { get; set; } + public string PedLayoutName { get; set; } + public string PedComponentSetName { get; set; } + public string PedComponentClothName { get; set; } + public string PedIKSettingsName { get; set; } + public string TaskDataName { get; set; } + public bool IsStreamedGfx { get; set; } + public bool AmbulanceShouldRespondTo { get; set; } + public bool CanRideBikeWithNoHelmet { get; set; } + public bool CanSpawnInCar { get; set; } + public bool IsHeadBlendPed { get; set; } + public bool bOnlyBulkyItemVariations { get; set; } + public string RelationshipGroup { get; set; } + public string NavCapabilitiesName { get; set; } + public string PerceptionInfo { get; set; } + public string DefaultBrawlingStyle { get; set; } + public string DefaultUnarmedWeapon { get; set; } + public string Personality { get; set; } + public string CombatInfo { get; set; } + public string VfxInfoName { get; set; } + public string AmbientClipsForFlee { get; set; } + public string Radio1 { get; set; } // MetaName.ePedRadioGenre + public string Radio2 { get; set; } // MetaName.ePedRadioGenre + public float FUpOffset { get; set; } + public float RUpOffset { get; set; } + public float FFrontOffset { get; set; } + public float RFrontOffset { get; set; } + public float MinActivationImpulse { get; set; } + public float Stubble { get; set; } + public float HDDist { get; set; } + public float TargetingThreatModifier { get; set; } + public float KilledPerceptionRangeModifer { get; set; } + public string Sexiness { get; set; } // MetaTypeName.ARRAYINFO MetaName.eSexinessFlags + public byte Age { get; set; } + public byte MaxPassengersInCar { get; set; } + public string ExternallyDrivenDOFs { get; set; } // MetaTypeName.ARRAYINFO MetaName.eExternallyDrivenDOFs + public string PedVoiceGroup { get; set; } + public string AnimalAudioObject { get; set; } + public string AbilityType { get; set; } // MetaName.SpecialAbilityType + public string ThermalBehaviour { get; set; } // MetaName.ThermalBehaviour + public string SuperlodType { get; set; } // MetaName.eSuperlodType + public string ScenarioPopStreamingSlot { get; set; } // MetaName.eScenarioPopStreamingSlot + public string DefaultSpawningPreference { get; set; } // MetaName.DefaultSpawnPreference + public float DefaultRemoveRangeMultiplier { get; set; } + public bool AllowCloseSpawning { get; set; } + + + public CPedModelInfo__InitData(XmlNode node) + { + Name = Xml.GetChildInnerText(node, "Name"); + PropsName = Xml.GetChildInnerText(node, "PropsName"); + ClipDictionaryName = Xml.GetChildInnerText(node, "ClipDictionaryName"); + BlendShapeFileName = Xml.GetChildInnerText(node, "BlendShapeFileName"); + ExpressionSetName = Xml.GetChildInnerText(node, "ExpressionSetName"); + ExpressionDictionaryName = Xml.GetChildInnerText(node, "ExpressionDictionaryName"); + ExpressionName = Xml.GetChildInnerText(node, "ExpressionName"); + Pedtype = Xml.GetChildInnerText(node, "Pedtype"); + MovementClipSet = Xml.GetChildInnerText(node, "MovementClipSet"); + var items = node.SelectSingleNode("MovementClipSets")?.SelectNodes("Item"); + if (items?.Count > 0) + { + MovementClipSets = new string[items.Count]; + for (int i = 0; i < items.Count; i++) + { + MovementClipSets[i] = items[i].InnerText; + } + } + StrafeClipSet = Xml.GetChildInnerText(node, "StrafeClipSet"); + MovementToStrafeClipSet = Xml.GetChildInnerText(node, "MovementToStrafeClipSet"); + InjuredStrafeClipSet = Xml.GetChildInnerText(node, "InjuredStrafeClipSet"); + FullBodyDamageClipSet = Xml.GetChildInnerText(node, "FullBodyDamageClipSet"); + AdditiveDamageClipSet = Xml.GetChildInnerText(node, "AdditiveDamageClipSet"); + DefaultGestureClipSet = Xml.GetChildInnerText(node, "DefaultGestureClipSet"); + FacialClipsetGroupName = Xml.GetChildInnerText(node, "FacialClipsetGroupName"); + DefaultVisemeClipSet = Xml.GetChildInnerText(node, "DefaultVisemeClipSet"); + SidestepClipSet = Xml.GetChildInnerText(node, "SidestepClipSet"); + PoseMatcherName = Xml.GetChildInnerText(node, "PoseMatcherName"); + PoseMatcherProneName = Xml.GetChildInnerText(node, "PoseMatcherProneName"); + GetupSetHash = Xml.GetChildInnerText(node, "GetupSetHash"); + CreatureMetadataName = Xml.GetChildInnerText(node, "CreatureMetadataName"); + DecisionMakerName = Xml.GetChildInnerText(node, "DecisionMakerName"); + MotionTaskDataSetName = Xml.GetChildInnerText(node, "MotionTaskDataSetName"); + DefaultTaskDataSetName = Xml.GetChildInnerText(node, "DefaultTaskDataSetName"); + PedCapsuleName = Xml.GetChildInnerText(node, "PedCapsuleName"); + PedLayoutName = Xml.GetChildInnerText(node, "PedLayoutName"); + PedComponentSetName = Xml.GetChildInnerText(node, "PedComponentSetName"); + PedComponentClothName = Xml.GetChildInnerText(node, "PedComponentClothName"); + PedIKSettingsName = Xml.GetChildInnerText(node, "PedIKSettingsName"); + TaskDataName = Xml.GetChildInnerText(node, "TaskDataName"); + IsStreamedGfx = Xml.GetChildBoolAttribute(node, "IsStreamedGfx", "value"); + AmbulanceShouldRespondTo = Xml.GetChildBoolAttribute(node, "AmbulanceShouldRespondTo", "value"); + CanRideBikeWithNoHelmet = Xml.GetChildBoolAttribute(node, "CanRideBikeWithNoHelmet", "value"); + CanSpawnInCar = Xml.GetChildBoolAttribute(node, "CanSpawnInCar", "value"); + IsHeadBlendPed = Xml.GetChildBoolAttribute(node, "IsHeadBlendPed", "value"); + bOnlyBulkyItemVariations = Xml.GetChildBoolAttribute(node, "bOnlyBulkyItemVariations", "value"); + RelationshipGroup = Xml.GetChildInnerText(node, "RelationshipGroup"); + NavCapabilitiesName = Xml.GetChildInnerText(node, "NavCapabilitiesName"); + PerceptionInfo = Xml.GetChildInnerText(node, "PerceptionInfo"); + DefaultBrawlingStyle = Xml.GetChildInnerText(node, "DefaultBrawlingStyle"); + DefaultUnarmedWeapon = Xml.GetChildInnerText(node, "DefaultUnarmedWeapon"); + Personality = Xml.GetChildInnerText(node, "Personality"); + CombatInfo = Xml.GetChildInnerText(node, "CombatInfo"); + VfxInfoName = Xml.GetChildInnerText(node, "VfxInfoName"); + AmbientClipsForFlee = Xml.GetChildInnerText(node, "AmbientClipsForFlee"); + Radio1 = Xml.GetChildInnerText(node, "Radio1"); // MetaName.ePedRadioGenre + Radio2 = Xml.GetChildInnerText(node, "Radio2"); // MetaName.ePedRadioGenre + FUpOffset = Xml.GetChildFloatAttribute(node, "FUpOffset", "value"); + RUpOffset = Xml.GetChildFloatAttribute(node, "RUpOffset", "value"); + FFrontOffset = Xml.GetChildFloatAttribute(node, "FFrontOffset", "value"); + RFrontOffset = Xml.GetChildFloatAttribute(node, "RFrontOffset", "value"); + MinActivationImpulse = Xml.GetChildFloatAttribute(node, "MinActivationImpulse", "value"); + Stubble = Xml.GetChildFloatAttribute(node, "Stubble", "value"); + HDDist = Xml.GetChildFloatAttribute(node, "HDDist", "value"); + TargetingThreatModifier = Xml.GetChildFloatAttribute(node, "TargetingThreatModifier", "value"); + KilledPerceptionRangeModifer = Xml.GetChildFloatAttribute(node, "KilledPerceptionRangeModifer", "value"); + Sexiness = Xml.GetChildInnerText(node, "Sexiness"); // MetaTypeName.ARRAYINFO MetaName.eSexinessFlags + Age = (byte)Xml.GetChildUIntAttribute(node, "Age", "value"); + MaxPassengersInCar = (byte)Xml.GetChildUIntAttribute(node, "MaxPassengersInCar", "value"); + ExternallyDrivenDOFs = Xml.GetChildInnerText(node, "ExternallyDrivenDOFs"); // MetaTypeName.ARRAYINFO MetaName.eExternallyDrivenDOFs + PedVoiceGroup = Xml.GetChildInnerText(node, "PedVoiceGroup"); + AnimalAudioObject = Xml.GetChildInnerText(node, "AnimalAudioObject"); + AbilityType = Xml.GetChildInnerText(node, "AbilityType"); // MetaName.SpecialAbilityType + ThermalBehaviour = Xml.GetChildInnerText(node, "ThermalBehaviour"); // MetaName.ThermalBehaviour + SuperlodType = Xml.GetChildInnerText(node, "SuperlodType"); // MetaName.eSuperlodType + ScenarioPopStreamingSlot = Xml.GetChildInnerText(node, "ScenarioPopStreamingSlot"); // MetaName.eScenarioPopStreamingSlot + DefaultSpawningPreference = Xml.GetChildInnerText(node, "DefaultSpawningPreference"); // MetaName.DefaultSpawnPreference + DefaultRemoveRangeMultiplier = Xml.GetChildFloatAttribute(node, "DefaultRemoveRangeMultiplier", "value"); + AllowCloseSpawning = Xml.GetChildBoolAttribute(node, "AllowCloseSpawning", "value"); + } + + + public override string ToString() + { + return Name; + } + } + + [TC(typeof(EXP))] public class CTxdRelationship + { + public string parent { get; set; } + public string child { get; set; } + + public CTxdRelationship(XmlNode node) + { + parent = Xml.GetChildInnerText(node, "parent"); + child = Xml.GetChildInnerText(node, "child"); + } + + public override string ToString() + { + return parent + ": " + child; + } + } + + [TC(typeof(EXP))] public class CMultiTxdRelationship + { + public string parent { get; set; } + public string[] children { get; set; } + + public CMultiTxdRelationship(XmlNode node) + { + parent = Xml.GetChildInnerText(node, "parent"); + var items = node.SelectSingleNode("children")?.SelectNodes("Item"); + if (items?.Count > 0) + { + children = new string[items.Count]; + for (int i = 0; i < items.Count; i++) + { + children[i] = items[i].InnerText; + } + } + } + + public override string ToString() + { + return parent + ": " + (children?.Length ?? 0).ToString() + " children"; + } + } + + + + + + +} + + diff --git a/CodeWalker.Core/GameFiles/FileTypes/VehicleLayoutsFile.cs b/CodeWalker.Core/GameFiles/FileTypes/VehicleLayoutsFile.cs index d5dcf8c..f6b4f3e 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/VehicleLayoutsFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/VehicleLayoutsFile.cs @@ -26,7 +26,7 @@ namespace CodeWalker.GameFiles //always XML .meta - Xml = Encoding.UTF8.GetString(data); + Xml = TextUtil.GetUTF8Text(data); //TODO: parse CVehicleMetadataMgr XML diff --git a/CodeWalker.Core/GameFiles/FileTypes/VehiclesFile.cs b/CodeWalker.Core/GameFiles/FileTypes/VehiclesFile.cs index bcd18db..d80485c 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/VehiclesFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/VehiclesFile.cs @@ -37,14 +37,7 @@ namespace CodeWalker.GameFiles if (entry.NameLower.EndsWith(".meta")) { - //required for update\x64\dlcpacks\mpheist\dlc.rpf\common\data\gtxd.meta and update\x64\dlcpacks\mpluxe\dlc.rpf\common\data\gtxd.meta - string bom = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble()); - string xml = Encoding.UTF8.GetString(data); - - if (xml.StartsWith(bom, StringComparison.Ordinal)) - { - xml = xml.Remove(0, bom.Length); - } + string xml = TextUtil.GetUTF8Text(data); XmlDocument xmldoc = new XmlDocument(); xmldoc.LoadXml(xml); diff --git a/CodeWalker.Core/GameFiles/GameFile.cs b/CodeWalker.Core/GameFiles/GameFile.cs index e941522..025f192 100644 --- a/CodeWalker.Core/GameFiles/GameFile.cs +++ b/CodeWalker.Core/GameFiles/GameFile.cs @@ -75,6 +75,7 @@ namespace CodeWalker.GameFiles CarModCols = 19, CarVariations = 20, VehicleLayouts = 21, + Peds = 22, } diff --git a/CodeWalker.Core/GameFiles/GameFileCache.cs b/CodeWalker.Core/GameFiles/GameFileCache.cs index 5051392..c286025 100644 --- a/CodeWalker.Core/GameFiles/GameFileCache.cs +++ b/CodeWalker.Core/GameFiles/GameFileCache.cs @@ -79,7 +79,7 @@ namespace CodeWalker.GameFiles public Dictionary TimeCycleModsDict = new Dictionary(); public Dictionary VehiclesInitDict { get; set; } - + public Dictionary PedsInitDict { get; set; } public List BaseRpfs { get; private set; } public List AllRpfs { get; private set; } @@ -89,6 +89,7 @@ namespace CodeWalker.GameFiles public bool BuildExtendedJenkIndex = true; public bool LoadArchetypes = true; public bool LoadVehicles = false; + public bool LoadPeds = false; private bool PreloadedMode = false; private string GTAFolder; @@ -273,6 +274,10 @@ namespace CodeWalker.GameFiles UpdateStatus("Loading vehicles..."); InitVehicles(); + + UpdateStatus("Loading peds..."); + InitPeds(); + } private void InitDlcList() @@ -1592,6 +1597,69 @@ namespace CodeWalker.GameFiles } + public void InitPeds() + { + if (!LoadPeds) return; + + IEnumerable rpfs = PreloadedMode ? AllRpfs : (IEnumerable)ActiveMapRpfFiles.Values; + + var allPeds = new Dictionary(); + var allPedsFiles = new List(); + + var addPedsFiles = new Action>((from) => + { + foreach (RpfFile file in from) + { + if (file.AllEntries == null) continue; + foreach (RpfEntry entry in file.AllEntries) + { +#if !DEBUG + try +#endif + { + if ((entry.NameLower == "peds.ymt") || (entry.NameLower == "peds.meta")) + { + var pf = RpfMan.GetFile(entry); + if (pf.InitDataList?.InitDatas != null) + { + foreach (var initData in pf.InitDataList.InitDatas) + { + var name = initData.Name.ToLowerInvariant(); + var hash = JenkHash.GenHash(name); + if (allPeds.ContainsKey(hash)) + { } + allPeds[hash] = initData; + } + } + allPedsFiles.Add(pf); + } + } +#if !DEBUG + catch (Exception ex) + { + string errstr = entry.Path + "\n" + ex.ToString(); + ErrorLog(errstr); + } +#endif + } + } + + }); + + + addPedsFiles(rpfs); + + if (EnableDlc) + { + addPedsFiles(DlcActiveRpfs); + } + + + PedsInitDict = allPeds; + + + } + public bool SetDlcLevel(string dlc, bool enable) { diff --git a/CodeWalker.Core/GameFiles/MetaTypes/Meta.cs b/CodeWalker.Core/GameFiles/MetaTypes/Meta.cs index 4d378c1..5c7cf49 100644 --- a/CodeWalker.Core/GameFiles/MetaTypes/Meta.cs +++ b/CodeWalker.Core/GameFiles/MetaTypes/Meta.cs @@ -1110,10 +1110,7 @@ namespace CodeWalker.GameFiles { var str = JenkIndex.TryGetString(Hash); if (!string.IsNullOrEmpty(str)) return str; - if (Enum.IsDefined(typeof(MetaName), Hash)) - { - return ((MetaName)Hash).ToString(); - } + if (MetaNames.TryGetString(Hash, out str)) return str; return GlobalText.GetString(Hash); } diff --git a/CodeWalker.Core/GameFiles/MetaTypes/MetaNames.cs b/CodeWalker.Core/GameFiles/MetaTypes/MetaNames.cs index b68dd72..8dc8524 100644 --- a/CodeWalker.Core/GameFiles/MetaTypes/MetaNames.cs +++ b/CodeWalker.Core/GameFiles/MetaTypes/MetaNames.cs @@ -8,6 +8,21 @@ using System.Threading.Tasks; namespace CodeWalker.GameFiles { + public static class MetaNames + { + public static bool TryGetString(uint h, out string str) + { + if (Enum.IsDefined(typeof(MetaName), h)) + { + str = ((MetaName)h).ToString(); + if (str.StartsWith("@")) str = str.Substring(1); //mainly to handle the @null entry + return true; + } + str = null; + return false; + } + } + public class MetaNamesUtil { @@ -3468,11 +3483,60 @@ namespace CodeWalker.GameFiles ePedVarComp = 884254308, ePropRenderFlags = 4212977111, CPedPropTexData = 254518642, + eScenarioPopStreamingSlot = 3029795674, + eFadeCurveType = 3057039286, + eSuperlodType = 4015041481, + ePedRadioGenre = 2942646938, + eSexinessFlags = 374769227, + eExternallyDrivenDOFs = 637184392, + SpecialAbilityType = 2011786168, + DefaultSpawnPreference = 888587604, CScenarioChainingEdge__eAction = 3609807418, CScenarioChainingEdge__eNavMode = 3971773454, CScenarioChainingEdge__eNavSpeed = 941086046, + standard_ped = 2703423328, //in peds.ymt + standard_male = 1860494962, //in peds.ymt PedCapsuleName + standard_female = 3778684510, //in peds.ymt PedCapsuleName + facial_clipset_group_gen_male = 2968316036, //in peds.ymt FacialClipsetGroupName + facial_clipset_group_gen_female = 984918963, //in peds.ymt FacialClipsetGroupName + facial_clipset_group_p_m_zero = 3839850645, //in peds.ymt FacialClipsetGroupName + facial_clipset_group_p_m_one = 3697506179, //in peds.ymt FacialClipsetGroupName + facial_clipset_group_p_m_two = 3958944905, //in peds.ymt FacialClipsetGroupName + anim_group_gesture_m_generic = 4080627616, //in peds.ymt DefaultGestureClipSet + anim_group_gesture_f_generic = 1375166916, //in peds.ymt DefaultGestureClipSet + anim_group_visemes_m_lo = 3326036851, //in peds.ymt DefaultVisemeClipSet + anim_group_visemes_f_lo = 2783456433, //in peds.ymt DefaultVisemeClipSet + nmbs_slow_getups = 69709351, //peds.ymt GetupSetHash + clip_set_id_invalid = 2106583169, //in peds.ymt + move_strafe_injured = 1434752434, //in peds.ymt InjuredStrafeClipSet + move_ped_to_strafe = 3943634031, //in peds.ymt MovementToStrafeClipSet + move_ped_strafing = 2464962150, //in peds.ymt StrafeClipSet + civmale = 45677184, //in peds.ymt Pedtype + civfemale = 1191392768, //in peds.ymt Pedtype + vfxpedinfo_human_generic = 1167185222, //in peds.ymt VfxInfoName + expr_set_ambient_male = 2495275024, //in peds.ymt ExpressionSetName + expr_set_ambient_female = 3793172393, //in peds.ymt ExpressionSetName + default_perception = 3537703288, //in peds.ymt PerceptionInfo + streamed_male = 4014297412, //in peds.ymt Personality + streamed_female = 991949850, //in peds.ymt Personality + fitnessmale = 921466782, //in peds.ymt Personality + fitnessfemale = 419688606, //in peds.ymt Personality + youngrichman = 3818603935, //in peds.ymt Personality + youngrichwoman = 367809573, //in peds.ymt Personality + youngaverageweakman = 3971800366, //in peds.ymt Personality + youngaverageweakwoman = 806694113, //in peds.ymt Personality + bs_ai = 2150391885, //in peds.ymt DefaultBrawlingStyle + bs_franklin = 1037948029, //in peds.ymt DefaultBrawlingStyle + bs_michael = 2057220685, //in peds.ymt DefaultBrawlingStyle + bs_trevor = 1249954968, //in peds.ymt DefaultBrawlingStyle + weapon_unarmed = 2725352035, //in peds.ymt DefaultUnarmedWeapon + silent_pvg = 423993118, //in peds.ymt PedVoiceGroup + silent_cutscene_pvg = 1896822940, //in peds.ymt PedVoiceGroup + + @null = 987444055, // how best to handle this? C# doesn't like it + diff --git a/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs b/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs index a39a167..869dc32 100644 --- a/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs +++ b/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs @@ -1827,12 +1827,10 @@ namespace CodeWalker.GameFiles uint uh = (uint)h; if (uh == 0) return ""; - if (Enum.IsDefined(typeof(MetaName), h)) - { - return h.ToString(); - } + string str; + if (MetaNames.TryGetString(uh, out str)) return str; - var str = JenkIndex.TryGetString(uh); + str = JenkIndex.TryGetString(uh); if (!string.IsNullOrEmpty(str)) return str; //TODO: do extra hash lookup here @@ -1849,11 +1847,7 @@ namespace CodeWalker.GameFiles if (string.IsNullOrEmpty(str)) { - var nh = (MetaName)(uint)h; - if (Enum.IsDefined(typeof(MetaName), nh)) - { - return nh.ToString(); - } + if (MetaNames.TryGetString(h, out str)) return str; } //todo: make sure JenkIndex is built! @@ -1880,12 +1874,10 @@ namespace CodeWalker.GameFiles public static string UintString(uint h) { - if (Enum.IsDefined(typeof(MetaName), h)) - { - return ((MetaName)h).ToString(); - } + string str; + if (MetaNames.TryGetString(h, out str)) return str; - var str = JenkIndex.TryGetString(h); + str = JenkIndex.TryGetString(h); if (!string.IsNullOrEmpty(str)) return str; //TODO: do extra hash lookup here diff --git a/CodeWalker.Core/GameFiles/MetaTypes/PsoTypes.cs b/CodeWalker.Core/GameFiles/MetaTypes/PsoTypes.cs index ba432f3..419e2cf 100644 --- a/CodeWalker.Core/GameFiles/MetaTypes/PsoTypes.cs +++ b/CodeWalker.Core/GameFiles/MetaTypes/PsoTypes.cs @@ -800,8 +800,8 @@ namespace CodeWalker.GameFiles new PsoStructureEntryInfo(MetaName.CombatInfo, PsoDataType.String, 192, 7, 0), new PsoStructureEntryInfo(MetaName.VfxInfoName, PsoDataType.String, 196, 7, 0), new PsoStructureEntryInfo(MetaName.AmbientClipsForFlee, PsoDataType.String, 200, 7, 0), - new PsoStructureEntryInfo(MetaName.Radio1, PsoDataType.Enum, 204, 0, (MetaName)2942646938), - new PsoStructureEntryInfo(MetaName.Radio2, PsoDataType.Enum, 208, 0, (MetaName)2942646938), + new PsoStructureEntryInfo(MetaName.Radio1, PsoDataType.Enum, 204, 0, MetaName.ePedRadioGenre), + new PsoStructureEntryInfo(MetaName.Radio2, PsoDataType.Enum, 208, 0, MetaName.ePedRadioGenre), new PsoStructureEntryInfo(MetaName.FUpOffset, PsoDataType.Float, 212, 0, 0), new PsoStructureEntryInfo(MetaName.RUpOffset, PsoDataType.Float, 216, 0, 0), new PsoStructureEntryInfo(MetaName.FFrontOffset, PsoDataType.Float, 220, 0, 0), @@ -811,19 +811,19 @@ namespace CodeWalker.GameFiles new PsoStructureEntryInfo(MetaName.HDDist, PsoDataType.Float, 236, 0, 0), new PsoStructureEntryInfo(MetaName.TargetingThreatModifier, PsoDataType.Float, 240, 0, 0), new PsoStructureEntryInfo(MetaName.KilledPerceptionRangeModifer, PsoDataType.Float, 244, 0, 0), - new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.Enum, 0, 0, (MetaName)374769227), + new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.Enum, 0, 0, MetaName.eSexinessFlags), new PsoStructureEntryInfo(MetaName.Sexiness, PsoDataType.Flags, 248, 0, (MetaName)2097211), new PsoStructureEntryInfo(MetaName.Age, PsoDataType.UByte, 252, 0, 0), new PsoStructureEntryInfo(MetaName.MaxPassengersInCar, PsoDataType.UByte, 253, 0, 0), - new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.Enum, 0, 0, (MetaName)637184392), + new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.Enum, 0, 0, MetaName.eExternallyDrivenDOFs), new PsoStructureEntryInfo(MetaName.ExternallyDrivenDOFs, PsoDataType.Flags, 254, 2, (MetaName)327743), new PsoStructureEntryInfo(MetaName.PedVoiceGroup, PsoDataType.String, 256, 7, 0), new PsoStructureEntryInfo(MetaName.AnimalAudioObject, PsoDataType.String, 260, 7, 0), - new PsoStructureEntryInfo(MetaName.AbilityType, PsoDataType.Enum, 264, 0, (MetaName)2011786168), + new PsoStructureEntryInfo(MetaName.AbilityType, PsoDataType.Enum, 264, 0, MetaName.SpecialAbilityType), new PsoStructureEntryInfo(MetaName.ThermalBehaviour, PsoDataType.Enum, 268, 0, MetaName.ThermalBehaviour), - new PsoStructureEntryInfo(MetaName.SuperlodType, PsoDataType.Enum, 272, 0, (MetaName)4015041481), - new PsoStructureEntryInfo(MetaName.ScenarioPopStreamingSlot, PsoDataType.Enum, 276, 0, (MetaName)3029795674), - new PsoStructureEntryInfo(MetaName.DefaultSpawningPreference, PsoDataType.Enum, 280, 0, (MetaName)888587604), + new PsoStructureEntryInfo(MetaName.SuperlodType, PsoDataType.Enum, 272, 0, MetaName.eSuperlodType), + new PsoStructureEntryInfo(MetaName.ScenarioPopStreamingSlot, PsoDataType.Enum, 276, 0, MetaName.eScenarioPopStreamingSlot), + new PsoStructureEntryInfo(MetaName.DefaultSpawningPreference, PsoDataType.Enum, 280, 0, MetaName.DefaultSpawnPreference), new PsoStructureEntryInfo(MetaName.DefaultRemoveRangeMultiplier, PsoDataType.Float, 284, 0, 0), new PsoStructureEntryInfo(MetaName.AllowCloseSpawning, PsoDataType.Bool, 288, 0, 0) ); @@ -841,7 +841,7 @@ namespace CodeWalker.GameFiles new PsoStructureEntryInfo(MetaName.mediumCharge, PsoDataType.SInt, 28, 0, 0), new PsoStructureEntryInfo(MetaName.largeCharge, PsoDataType.SInt, 32, 0, 0), new PsoStructureEntryInfo(MetaName.continuousCharge, PsoDataType.SInt, 36, 0, 0), - new PsoStructureEntryInfo(MetaName.fadeCurveType, PsoDataType.Enum, 40, 0, (MetaName)3057039286), + new PsoStructureEntryInfo(MetaName.fadeCurveType, PsoDataType.Enum, 40, 0, MetaName.eFadeCurveType), new PsoStructureEntryInfo(MetaName.halfSigmoidConstant, PsoDataType.Float, 44, 0, 0), new PsoStructureEntryInfo(MetaName.sigmoidConstant, PsoDataType.Float, 48, 0, 0), new PsoStructureEntryInfo(MetaName.fadeInTime, PsoDataType.Float, 52, 0, 0), @@ -14849,8 +14849,8 @@ namespace CodeWalker.GameFiles new PsoEnumEntryInfo(MetaName.PARTITION_2, 2), new PsoEnumEntryInfo(MetaName.PARTITION_MAX, 3) ); - case (MetaName)2942646938: - return new PsoEnumInfo((MetaName)2942646938, 1, + case MetaName.ePedRadioGenre: + return new PsoEnumInfo(MetaName.ePedRadioGenre, 1, new PsoEnumEntryInfo(MetaName.RADIO_GENRE_OFF, 0), new PsoEnumEntryInfo(MetaName.RADIO_GENRE_MODERN_ROCK, 1), new PsoEnumEntryInfo(MetaName.RADIO_GENRE_CLASSIC_ROCK, 2), @@ -14869,20 +14869,20 @@ namespace CodeWalker.GameFiles new PsoEnumEntryInfo(MetaName.RADIO_GENRE_SURF, 15), new PsoEnumEntryInfo(MetaName.RADIO_GENRE_UNSPECIFIED, 16) ); - case (MetaName)374769227: - return new PsoEnumInfo((MetaName)374769227, 1, + case MetaName.eSexinessFlags: + return new PsoEnumInfo(MetaName.eSexinessFlags, 1, new PsoEnumEntryInfo(MetaName.SF_JEER_AT_HOT_PED, 0), new PsoEnumEntryInfo((MetaName)296569367, 1), new PsoEnumEntryInfo(MetaName.SF_HOT_PERSON, 2) ); - case (MetaName)637184392: - return new PsoEnumInfo((MetaName)637184392, 1, + case MetaName.eExternallyDrivenDOFs: + return new PsoEnumInfo(MetaName.eExternallyDrivenDOFs, 1, new PsoEnumEntryInfo(MetaName.EMPTY, 0), new PsoEnumEntryInfo(MetaName.HIGH_HEELS, 1), new PsoEnumEntryInfo(MetaName.COLLAR, 2) ); - case (MetaName)2011786168: - return new PsoEnumInfo((MetaName)2011786168, 1, + case MetaName.SpecialAbilityType: //CPedModelInfo__InitData AbilityType + return new PsoEnumInfo(MetaName.SpecialAbilityType, 1, new PsoEnumEntryInfo(MetaName.SAT_NONE, -1), new PsoEnumEntryInfo(MetaName.SAT_CAR_SLOWDOWN, 0), new PsoEnumEntryInfo(MetaName.SAT_RAGE, 1), @@ -14897,28 +14897,28 @@ namespace CodeWalker.GameFiles new PsoEnumEntryInfo(MetaName.TB_WARM, 2), new PsoEnumEntryInfo(MetaName.TB_HOT, 3) ); - case (MetaName)4015041481: - return new PsoEnumInfo((MetaName)4015041481, 1, + case MetaName.eSuperlodType: + return new PsoEnumInfo(MetaName.eSuperlodType, 1, new PsoEnumEntryInfo(MetaName.SLOD_HUMAN, 0), new PsoEnumEntryInfo(MetaName.SLOD_SMALL_QUADPED, 1), new PsoEnumEntryInfo(MetaName.SLOD_LARGE_QUADPED, 2), new PsoEnumEntryInfo(MetaName.SLOD_NULL, 3), new PsoEnumEntryInfo(MetaName.SLOD_KEEP_LOWEST, 4) ); - case (MetaName)3029795674: //CPedModelInfo__InitData ScenarioPopStreamingSlot - return new PsoEnumInfo((MetaName)3029795674, 1, + case MetaName.eScenarioPopStreamingSlot: //CPedModelInfo__InitData ScenarioPopStreamingSlot + return new PsoEnumInfo(MetaName.eScenarioPopStreamingSlot, 1, new PsoEnumEntryInfo(MetaName.SCENARIO_POP_STREAMING_NORMAL, 0), new PsoEnumEntryInfo(MetaName.SCENARIO_POP_STREAMING_SMALL, 1) ); - case (MetaName)888587604: - return new PsoEnumInfo((MetaName)888587604, 1, + case MetaName.DefaultSpawnPreference: //CPedModelInfo__InitData DefaultSpawningPreference + return new PsoEnumInfo(MetaName.DefaultSpawnPreference, 1, new PsoEnumEntryInfo(MetaName.DSP_AERIAL, 0), new PsoEnumEntryInfo(MetaName.DSP_AQUATIC, 1), new PsoEnumEntryInfo(MetaName.DSP_GROUND_WILDLIFE, 2), new PsoEnumEntryInfo(MetaName.DSP_NORMAL, 3) ); - case (MetaName)3057039286: - return new PsoEnumInfo((MetaName)3057039286, 1, + case MetaName.eFadeCurveType: + return new PsoEnumInfo(MetaName.eFadeCurveType, 1, new PsoEnumEntryInfo(MetaName.FCT_NONE, 0), new PsoEnumEntryInfo(MetaName.FCT_LINEAR, 1), new PsoEnumEntryInfo(MetaName.FCT_HALF_SIGMOID, 2), diff --git a/CodeWalker.Core/GameFiles/Resources/Drawable.cs b/CodeWalker.Core/GameFiles/Resources/Drawable.cs index afd034b..ad44539 100644 --- a/CodeWalker.Core/GameFiles/Resources/Drawable.cs +++ b/CodeWalker.Core/GameFiles/Resources/Drawable.cs @@ -541,13 +541,13 @@ namespace CodeWalker.GameFiles public Matrix[] TransformationsInverted { get; set; } public Matrix[] Transformations { get; set; } - public ushort[] ParentIndices { get; set; } - public ushort[] ChildIndices { get; set; }//mapping child->parent indices, first child index, then parent + public short[] ParentIndices { get; set; } + public short[] ChildIndices { get; set; }//mapping child->parent indices, first child index, then parent private ResourceSystemStructBlock TransformationsInvertedBlock = null;//for saving only private ResourceSystemStructBlock TransformationsBlock = null; - private ResourceSystemStructBlock ParentIndicesBlock = null; - private ResourceSystemStructBlock ChildIndicesBlock = null; + private ResourceSystemStructBlock ParentIndicesBlock = null; + private ResourceSystemStructBlock ChildIndicesBlock = null; public Dictionary BonesMap { get; set; }//for convienience finding bones by tag @@ -597,8 +597,8 @@ namespace CodeWalker.GameFiles ); this.TransformationsInverted = reader.ReadStructsAt(this.TransformationsInvertedPointer, this.BonesCount); this.Transformations = reader.ReadStructsAt(this.TransformationsPointer, this.BonesCount); - this.ParentIndices = reader.ReadUshortsAt(this.ParentIndicesPointer, this.BonesCount); - this.ChildIndices = reader.ReadUshortsAt(this.ChildIndicesPointer, this.ChildIndicesCount); + this.ParentIndices = reader.ReadShortsAt(this.ParentIndicesPointer, this.BonesCount); + this.ChildIndices = reader.ReadShortsAt(this.ChildIndicesPointer, this.ChildIndicesCount); if ((Bones != null) && (ParentIndices != null)) @@ -608,7 +608,7 @@ namespace CodeWalker.GameFiles { var bone = Bones[i]; var pind = ParentIndices[i]; - if (pind < Bones.Count) + if ((pind >= 0) && (pind < Bones.Count)) { bone.Parent = Bones[pind]; } @@ -698,12 +698,12 @@ namespace CodeWalker.GameFiles } if (ParentIndices != null) { - ParentIndicesBlock = new ResourceSystemStructBlock(ParentIndices); + ParentIndicesBlock = new ResourceSystemStructBlock(ParentIndices); list.Add(ParentIndicesBlock); } if (ChildIndices != null) { - ChildIndicesBlock = new ResourceSystemStructBlock(ChildIndices); + ChildIndicesBlock = new ResourceSystemStructBlock(ChildIndices); list.Add(ChildIndicesBlock); } return list.ToArray(); @@ -771,6 +771,27 @@ namespace CodeWalker.GameFiles } } + [Flags] public enum EBoneFlags : ushort + { + None = 0, + RotX = 0x1, + RotY = 0x2, + RotZ = 0x4, + LimitRotation = 0x8, + TransX = 0x10, + TransY = 0x20, + TransZ = 0x40, + LimitTranslation = 0x80, + ScaleX = 0x100, + ScaleY = 0x200, + ScaleZ = 0x400, + LimitScale = 0x800, + Unk0 = 0x1000, + Unk1 = 0x2000, + Unk2 = 0x4000, + Unk3 = 0x8000, + } + [TypeConverter(typeof(ExpandableObjectConverter))] public class Bone : ResourceSystemBlock { public override long BlockLength @@ -788,14 +809,14 @@ namespace CodeWalker.GameFiles public uint Unknown_1Ch { get; set; } // 0x00000000 RHW? public Vector3 Scale { get; set; } public float Unknown_2Ch { get; set; } // 1.0 RHW? - public ushort NextSiblingIndex { get; set; } //limb end index? IK chain? + public short NextSiblingIndex { get; set; } //limb end index? IK chain? public short ParentIndex { get; set; } public uint Unknown_34h { get; set; } // 0x00000000 public ulong NamePointer { get; set; } - public ushort Flags { get; set; } - public ushort Index { get; set; } + public EBoneFlags Flags { get; set; } + public short Index { get; set; } public ushort Tag { get; set; } - public ushort Index2 { get; set; }//same as Index? + public short Index2 { get; set; }//same as Index? public uint Unknown_48h { get; set; } // 0x00000000 public uint Unknown_4Ch { get; set; } // 0x00000000 @@ -826,14 +847,14 @@ namespace CodeWalker.GameFiles this.Unknown_1Ch = reader.ReadUInt32(); this.Scale = reader.ReadVector3(); this.Unknown_2Ch = reader.ReadSingle(); - this.NextSiblingIndex = reader.ReadUInt16(); + this.NextSiblingIndex = reader.ReadInt16(); this.ParentIndex = reader.ReadInt16(); this.Unknown_34h = reader.ReadUInt32(); this.NamePointer = reader.ReadUInt64(); - this.Flags = reader.ReadUInt16(); - this.Index = reader.ReadUInt16(); + this.Flags = (EBoneFlags)reader.ReadUInt16(); + this.Index = reader.ReadInt16(); this.Tag = reader.ReadUInt16(); - this.Index2 = reader.ReadUInt16(); + this.Index2 = reader.ReadInt16(); this.Unknown_48h = reader.ReadUInt32(); this.Unknown_4Ch = reader.ReadUInt32(); @@ -866,7 +887,7 @@ namespace CodeWalker.GameFiles writer.Write(this.ParentIndex); writer.Write(this.Unknown_34h); writer.Write(this.NamePointer); - writer.Write(this.Flags); + writer.Write((ushort)this.Flags); writer.Write(this.Index); writer.Write(this.Tag); writer.Write(this.Index2); diff --git a/CodeWalker.Core/GameFiles/Resources/ResourceData.cs b/CodeWalker.Core/GameFiles/Resources/ResourceData.cs index c34bc44..2a92f68 100644 --- a/CodeWalker.Core/GameFiles/Resources/ResourceData.cs +++ b/CodeWalker.Core/GameFiles/Resources/ResourceData.cs @@ -266,6 +266,15 @@ namespace CodeWalker.GameFiles //Position = posbackup; return result; } + public short[] ReadShortsAt(ulong position, uint count) + { + if ((position <= 0) || (count == 0)) return null; + var result = new short[count]; + var length = count * 2; + byte[] data = ReadBytesAt(position, length); + Buffer.BlockCopy(data, 0, result, 0, (int)length); + return result; + } public uint[] ReadUintsAt(ulong position, uint count) { if ((position <= 0) || (count == 0)) return null; diff --git a/CodeWalker.Core/GameFiles/RpfManager.cs b/CodeWalker.Core/GameFiles/RpfManager.cs index 3f7d8fc..78075c6 100644 --- a/CodeWalker.Core/GameFiles/RpfManager.cs +++ b/CodeWalker.Core/GameFiles/RpfManager.cs @@ -283,18 +283,7 @@ namespace CodeWalker.GameFiles public string GetFileUTF8Text(string path) { byte[] bytes = GetFileData(path); - if (bytes == null) - { return string.Empty; } //file not found.. - if ((bytes.Length > 3) && (bytes[0] == 0xEF) && (bytes[1] == 0xBB) && (bytes[2] == 0xBF)) - { - byte[] newb = new byte[bytes.Length - 3]; - for (int i = 3; i < bytes.Length; i++) - { - newb[i - 3] = bytes[i]; - } - bytes = newb; //trim starting 3 "magic" bytes? - } - return Encoding.UTF8.GetString(bytes); + return TextUtil.GetUTF8Text(bytes); } public XmlDocument GetFileXml(string path) { diff --git a/CodeWalker.Core/Utils/Utils.cs b/CodeWalker.Core/Utils/Utils.cs index 2f0ef16..2138fbe 100644 --- a/CodeWalker.Core/Utils/Utils.cs +++ b/CodeWalker.Core/Utils/Utils.cs @@ -81,6 +81,25 @@ namespace CodeWalker // Return formatted number with suffix return readable.ToString(fmt) + suffix; } + + + + public static string GetUTF8Text(byte[] bytes) + { + if (bytes == null) + { return string.Empty; } //file not found.. + if ((bytes.Length > 3) && (bytes[0] == 0xEF) && (bytes[1] == 0xBB) && (bytes[2] == 0xBF)) + { + byte[] newb = new byte[bytes.Length - 3]; + for (int i = 3; i < bytes.Length; i++) + { + newb[i - 3] = bytes[i]; + } + bytes = newb; //trim starting byte order mark + } + return Encoding.UTF8.GetString(bytes); + } + } diff --git a/CodeWalker.csproj b/CodeWalker.csproj index de19481..9758a4c 100644 --- a/CodeWalker.csproj +++ b/CodeWalker.csproj @@ -149,6 +149,12 @@ ModelMatForm.cs + + Form + + + PedsForm.cs + Form @@ -592,6 +598,9 @@ ModelMatForm.cs + + PedsForm.cs + GenerateLODLightsPanel.cs diff --git a/Peds/PedsForm.Designer.cs b/Peds/PedsForm.Designer.cs new file mode 100644 index 0000000..a82d4f5 --- /dev/null +++ b/Peds/PedsForm.Designer.cs @@ -0,0 +1,758 @@ +namespace CodeWalker.Peds +{ + partial class PedsForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PedsForm)); + this.ConsoleTextBox = new CodeWalker.WinForms.TextBoxFix(); + this.ToolsPanelShowButton = new System.Windows.Forms.Button(); + this.ToolsPanelHideButton = new System.Windows.Forms.Button(); + this.ToolsDragPanel = new System.Windows.Forms.Panel(); + this.ConsolePanel = new System.Windows.Forms.Panel(); + this.HDTexturesCheckBox = new System.Windows.Forms.CheckBox(); + this.SkeletonsCheckBox = new System.Windows.Forms.CheckBox(); + this.TimeOfDayLabel = new System.Windows.Forms.Label(); + this.ToolsOptionsTabPage = new System.Windows.Forms.TabPage(); + this.label19 = new System.Windows.Forms.Label(); + this.TimeOfDayTrackBar = new System.Windows.Forms.TrackBar(); + this.ControlLightDirCheckBox = new System.Windows.Forms.CheckBox(); + this.ShowCollisionMeshesCheckBox = new System.Windows.Forms.CheckBox(); + this.GridCheckBox = new System.Windows.Forms.CheckBox(); + this.GridCountComboBox = new System.Windows.Forms.ComboBox(); + this.label2 = new System.Windows.Forms.Label(); + this.GridSizeComboBox = new System.Windows.Forms.ComboBox(); + this.label1 = new System.Windows.Forms.Label(); + this.StatusBarCheckBox = new System.Windows.Forms.CheckBox(); + this.ErrorConsoleCheckBox = new System.Windows.Forms.CheckBox(); + this.HDRRenderingCheckBox = new System.Windows.Forms.CheckBox(); + this.SkydomeCheckBox = new System.Windows.Forms.CheckBox(); + this.ShadowsCheckBox = new System.Windows.Forms.CheckBox(); + this.WireframeCheckBox = new System.Windows.Forms.CheckBox(); + this.RenderModeComboBox = new System.Windows.Forms.ComboBox(); + this.label11 = new System.Windows.Forms.Label(); + this.TextureSamplerComboBox = new System.Windows.Forms.ComboBox(); + this.TextureCoordsComboBox = new System.Windows.Forms.ComboBox(); + this.label10 = new System.Windows.Forms.Label(); + this.AnisotropicFilteringCheckBox = new System.Windows.Forms.CheckBox(); + this.label14 = new System.Windows.Forms.Label(); + this.DetailsPropertyGrid = new CodeWalker.WinForms.ReadOnlyPropertyGrid(); + this.ToolsDetailsTabPage = new System.Windows.Forms.TabPage(); + this.TextureViewerButton = new System.Windows.Forms.Button(); + this.TexturesTreeView = new CodeWalker.WinForms.TreeViewFix(); + this.ToolsTexturesTabPage = new System.Windows.Forms.TabPage(); + this.ModelsTreeView = new CodeWalker.WinForms.TreeViewFix(); + this.StatusStrip = new System.Windows.Forms.StatusStrip(); + this.StatusLabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.MousedLabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.StatsLabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.ToolsModelsTabPage = new System.Windows.Forms.TabPage(); + this.label3 = new System.Windows.Forms.Label(); + this.PedNameComboBox = new System.Windows.Forms.ComboBox(); + this.StatsUpdateTimer = new System.Windows.Forms.Timer(this.components); + this.ToolsPedTabPage = new System.Windows.Forms.TabPage(); + this.ToolsTabControl = new System.Windows.Forms.TabControl(); + this.ToolsPanel = new System.Windows.Forms.Panel(); + this.ConsolePanel.SuspendLayout(); + this.ToolsOptionsTabPage.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.TimeOfDayTrackBar)).BeginInit(); + this.ToolsDetailsTabPage.SuspendLayout(); + this.ToolsTexturesTabPage.SuspendLayout(); + this.StatusStrip.SuspendLayout(); + this.ToolsModelsTabPage.SuspendLayout(); + this.ToolsPedTabPage.SuspendLayout(); + this.ToolsTabControl.SuspendLayout(); + this.ToolsPanel.SuspendLayout(); + this.SuspendLayout(); + // + // ConsoleTextBox + // + this.ConsoleTextBox.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.ConsoleTextBox.Location = new System.Drawing.Point(3, 3); + this.ConsoleTextBox.Multiline = true; + this.ConsoleTextBox.Name = "ConsoleTextBox"; + this.ConsoleTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this.ConsoleTextBox.Size = new System.Drawing.Size(695, 95); + this.ConsoleTextBox.TabIndex = 0; + // + // ToolsPanelShowButton + // + this.ToolsPanelShowButton.Location = new System.Drawing.Point(15, 15); + this.ToolsPanelShowButton.Name = "ToolsPanelShowButton"; + this.ToolsPanelShowButton.Size = new System.Drawing.Size(30, 23); + this.ToolsPanelShowButton.TabIndex = 8; + this.ToolsPanelShowButton.Text = ">>"; + this.ToolsPanelShowButton.UseVisualStyleBackColor = true; + this.ToolsPanelShowButton.Click += new System.EventHandler(this.ToolsPanelShowButton_Click); + // + // ToolsPanelHideButton + // + this.ToolsPanelHideButton.Location = new System.Drawing.Point(3, 3); + this.ToolsPanelHideButton.Name = "ToolsPanelHideButton"; + this.ToolsPanelHideButton.Size = new System.Drawing.Size(30, 23); + this.ToolsPanelHideButton.TabIndex = 0; + this.ToolsPanelHideButton.Text = "<<"; + this.ToolsPanelHideButton.UseVisualStyleBackColor = true; + this.ToolsPanelHideButton.Click += new System.EventHandler(this.ToolsPanelHideButton_Click); + // + // ToolsDragPanel + // + this.ToolsDragPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Right))); + this.ToolsDragPanel.Cursor = System.Windows.Forms.Cursors.VSplit; + this.ToolsDragPanel.Location = new System.Drawing.Point(249, 0); + this.ToolsDragPanel.Name = "ToolsDragPanel"; + this.ToolsDragPanel.Size = new System.Drawing.Size(4, 666); + this.ToolsDragPanel.TabIndex = 17; + this.ToolsDragPanel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ToolsDragPanel_MouseDown); + this.ToolsDragPanel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ToolsDragPanel_MouseMove); + this.ToolsDragPanel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ToolsDragPanel_MouseUp); + // + // ConsolePanel + // + this.ConsolePanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.ConsolePanel.BackColor = System.Drawing.SystemColors.Control; + this.ConsolePanel.Controls.Add(this.ConsoleTextBox); + this.ConsolePanel.Location = new System.Drawing.Point(271, 577); + this.ConsolePanel.Name = "ConsolePanel"; + this.ConsolePanel.Size = new System.Drawing.Size(701, 101); + this.ConsolePanel.TabIndex = 9; + this.ConsolePanel.Visible = false; + // + // HDTexturesCheckBox + // + this.HDTexturesCheckBox.AutoSize = true; + this.HDTexturesCheckBox.Checked = true; + this.HDTexturesCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.HDTexturesCheckBox.Location = new System.Drawing.Point(19, 242); + this.HDTexturesCheckBox.Name = "HDTexturesCheckBox"; + this.HDTexturesCheckBox.Size = new System.Drawing.Size(82, 17); + this.HDTexturesCheckBox.TabIndex = 10; + this.HDTexturesCheckBox.Text = "HD textures"; + this.HDTexturesCheckBox.UseVisualStyleBackColor = true; + this.HDTexturesCheckBox.CheckedChanged += new System.EventHandler(this.HDTexturesCheckBox_CheckedChanged); + // + // SkeletonsCheckBox + // + this.SkeletonsCheckBox.AutoSize = true; + this.SkeletonsCheckBox.Location = new System.Drawing.Point(19, 444); + this.SkeletonsCheckBox.Name = "SkeletonsCheckBox"; + this.SkeletonsCheckBox.Size = new System.Drawing.Size(103, 17); + this.SkeletonsCheckBox.TabIndex = 22; + this.SkeletonsCheckBox.Text = "Show Skeletons"; + this.SkeletonsCheckBox.UseVisualStyleBackColor = true; + this.SkeletonsCheckBox.CheckedChanged += new System.EventHandler(this.SkeletonsCheckBox_CheckedChanged); + // + // TimeOfDayLabel + // + this.TimeOfDayLabel.AutoSize = true; + this.TimeOfDayLabel.Location = new System.Drawing.Point(78, 109); + this.TimeOfDayLabel.Name = "TimeOfDayLabel"; + this.TimeOfDayLabel.Size = new System.Drawing.Size(34, 13); + this.TimeOfDayLabel.TabIndex = 5; + this.TimeOfDayLabel.Text = "12:00"; + // + // ToolsOptionsTabPage + // + this.ToolsOptionsTabPage.Controls.Add(this.HDTexturesCheckBox); + this.ToolsOptionsTabPage.Controls.Add(this.SkeletonsCheckBox); + this.ToolsOptionsTabPage.Controls.Add(this.TimeOfDayLabel); + this.ToolsOptionsTabPage.Controls.Add(this.label19); + this.ToolsOptionsTabPage.Controls.Add(this.TimeOfDayTrackBar); + this.ToolsOptionsTabPage.Controls.Add(this.ControlLightDirCheckBox); + this.ToolsOptionsTabPage.Controls.Add(this.ShowCollisionMeshesCheckBox); + this.ToolsOptionsTabPage.Controls.Add(this.GridCheckBox); + this.ToolsOptionsTabPage.Controls.Add(this.GridCountComboBox); + this.ToolsOptionsTabPage.Controls.Add(this.label2); + this.ToolsOptionsTabPage.Controls.Add(this.GridSizeComboBox); + this.ToolsOptionsTabPage.Controls.Add(this.label1); + this.ToolsOptionsTabPage.Controls.Add(this.StatusBarCheckBox); + this.ToolsOptionsTabPage.Controls.Add(this.ErrorConsoleCheckBox); + this.ToolsOptionsTabPage.Controls.Add(this.HDRRenderingCheckBox); + this.ToolsOptionsTabPage.Controls.Add(this.SkydomeCheckBox); + this.ToolsOptionsTabPage.Controls.Add(this.ShadowsCheckBox); + this.ToolsOptionsTabPage.Controls.Add(this.WireframeCheckBox); + this.ToolsOptionsTabPage.Controls.Add(this.RenderModeComboBox); + this.ToolsOptionsTabPage.Controls.Add(this.label11); + this.ToolsOptionsTabPage.Controls.Add(this.TextureSamplerComboBox); + this.ToolsOptionsTabPage.Controls.Add(this.TextureCoordsComboBox); + this.ToolsOptionsTabPage.Controls.Add(this.label10); + this.ToolsOptionsTabPage.Controls.Add(this.AnisotropicFilteringCheckBox); + this.ToolsOptionsTabPage.Controls.Add(this.label14); + this.ToolsOptionsTabPage.Location = new System.Drawing.Point(4, 22); + this.ToolsOptionsTabPage.Name = "ToolsOptionsTabPage"; + this.ToolsOptionsTabPage.Size = new System.Drawing.Size(239, 607); + this.ToolsOptionsTabPage.TabIndex = 3; + this.ToolsOptionsTabPage.Text = "Options"; + this.ToolsOptionsTabPage.UseVisualStyleBackColor = true; + // + // label19 + // + this.label19.AutoSize = true; + this.label19.Location = new System.Drawing.Point(7, 109); + this.label19.Name = "label19"; + this.label19.Size = new System.Drawing.Size(65, 13); + this.label19.TabIndex = 4; + this.label19.Text = "Time of day:"; + // + // TimeOfDayTrackBar + // + this.TimeOfDayTrackBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.TimeOfDayTrackBar.BackColor = System.Drawing.SystemColors.ControlLightLight; + this.TimeOfDayTrackBar.LargeChange = 60; + this.TimeOfDayTrackBar.Location = new System.Drawing.Point(9, 125); + this.TimeOfDayTrackBar.Maximum = 1440; + this.TimeOfDayTrackBar.Name = "TimeOfDayTrackBar"; + this.TimeOfDayTrackBar.Size = new System.Drawing.Size(222, 45); + this.TimeOfDayTrackBar.TabIndex = 6; + this.TimeOfDayTrackBar.TickFrequency = 60; + this.TimeOfDayTrackBar.Value = 720; + this.TimeOfDayTrackBar.Scroll += new System.EventHandler(this.TimeOfDayTrackBar_Scroll); + // + // ControlLightDirCheckBox + // + this.ControlLightDirCheckBox.AutoSize = true; + this.ControlLightDirCheckBox.Location = new System.Drawing.Point(19, 83); + this.ControlLightDirCheckBox.Name = "ControlLightDirCheckBox"; + this.ControlLightDirCheckBox.Size = new System.Drawing.Size(124, 17); + this.ControlLightDirCheckBox.TabIndex = 3; + this.ControlLightDirCheckBox.Text = "Control light direction"; + this.ControlLightDirCheckBox.UseVisualStyleBackColor = true; + this.ControlLightDirCheckBox.CheckedChanged += new System.EventHandler(this.ControlLightDirCheckBox_CheckedChanged); + // + // ShowCollisionMeshesCheckBox + // + this.ShowCollisionMeshesCheckBox.AutoSize = true; + this.ShowCollisionMeshesCheckBox.Location = new System.Drawing.Point(19, 173); + this.ShowCollisionMeshesCheckBox.Name = "ShowCollisionMeshesCheckBox"; + this.ShowCollisionMeshesCheckBox.Size = new System.Drawing.Size(132, 17); + this.ShowCollisionMeshesCheckBox.TabIndex = 7; + this.ShowCollisionMeshesCheckBox.Text = "Show collision meshes"; + this.ShowCollisionMeshesCheckBox.UseVisualStyleBackColor = true; + this.ShowCollisionMeshesCheckBox.CheckedChanged += new System.EventHandler(this.ShowCollisionMeshesCheckBox_CheckedChanged); + // + // GridCheckBox + // + this.GridCheckBox.AutoSize = true; + this.GridCheckBox.Location = new System.Drawing.Point(19, 364); + this.GridCheckBox.Name = "GridCheckBox"; + this.GridCheckBox.Size = new System.Drawing.Size(45, 17); + this.GridCheckBox.TabIndex = 17; + this.GridCheckBox.Text = "Grid"; + this.GridCheckBox.UseVisualStyleBackColor = true; + this.GridCheckBox.CheckedChanged += new System.EventHandler(this.GridCheckBox_CheckedChanged); + // + // GridCountComboBox + // + this.GridCountComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.GridCountComboBox.FormattingEnabled = true; + this.GridCountComboBox.Items.AddRange(new object[] { + "20", + "40", + "60", + "100"}); + this.GridCountComboBox.Location = new System.Drawing.Point(83, 411); + this.GridCountComboBox.Name = "GridCountComboBox"; + this.GridCountComboBox.Size = new System.Drawing.Size(114, 21); + this.GridCountComboBox.TabIndex = 21; + this.GridCountComboBox.SelectedIndexChanged += new System.EventHandler(this.GridCountComboBox_SelectedIndexChanged); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(7, 414); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(59, 13); + this.label2.TabIndex = 20; + this.label2.Text = "Grid count:"; + // + // GridSizeComboBox + // + this.GridSizeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.GridSizeComboBox.FormattingEnabled = true; + this.GridSizeComboBox.Items.AddRange(new object[] { + "0.1", + "1.0", + "10", + "100"}); + this.GridSizeComboBox.Location = new System.Drawing.Point(83, 384); + this.GridSizeComboBox.Name = "GridSizeComboBox"; + this.GridSizeComboBox.Size = new System.Drawing.Size(114, 21); + this.GridSizeComboBox.TabIndex = 19; + this.GridSizeComboBox.SelectedIndexChanged += new System.EventHandler(this.GridSizeComboBox_SelectedIndexChanged); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(7, 387); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(70, 13); + this.label1.TabIndex = 18; + this.label1.Text = "Grid unit size:"; + // + // StatusBarCheckBox + // + this.StatusBarCheckBox.AutoSize = true; + this.StatusBarCheckBox.Checked = true; + this.StatusBarCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.StatusBarCheckBox.Location = new System.Drawing.Point(19, 480); + this.StatusBarCheckBox.Name = "StatusBarCheckBox"; + this.StatusBarCheckBox.Size = new System.Drawing.Size(74, 17); + this.StatusBarCheckBox.TabIndex = 23; + this.StatusBarCheckBox.Text = "Status bar"; + this.StatusBarCheckBox.UseVisualStyleBackColor = true; + this.StatusBarCheckBox.CheckedChanged += new System.EventHandler(this.StatusBarCheckBox_CheckedChanged); + // + // ErrorConsoleCheckBox + // + this.ErrorConsoleCheckBox.AutoSize = true; + this.ErrorConsoleCheckBox.Location = new System.Drawing.Point(105, 480); + this.ErrorConsoleCheckBox.Name = "ErrorConsoleCheckBox"; + this.ErrorConsoleCheckBox.Size = new System.Drawing.Size(88, 17); + this.ErrorConsoleCheckBox.TabIndex = 24; + this.ErrorConsoleCheckBox.Text = "Error console"; + this.ErrorConsoleCheckBox.UseVisualStyleBackColor = true; + this.ErrorConsoleCheckBox.CheckedChanged += new System.EventHandler(this.ErrorConsoleCheckBox_CheckedChanged); + // + // HDRRenderingCheckBox + // + this.HDRRenderingCheckBox.AutoSize = true; + this.HDRRenderingCheckBox.Checked = true; + this.HDRRenderingCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.HDRRenderingCheckBox.Location = new System.Drawing.Point(19, 14); + this.HDRRenderingCheckBox.Name = "HDRRenderingCheckBox"; + this.HDRRenderingCheckBox.Size = new System.Drawing.Size(97, 17); + this.HDRRenderingCheckBox.TabIndex = 0; + this.HDRRenderingCheckBox.Text = "HDR rendering"; + this.HDRRenderingCheckBox.UseVisualStyleBackColor = true; + this.HDRRenderingCheckBox.CheckedChanged += new System.EventHandler(this.HDRRenderingCheckBox_CheckedChanged); + // + // SkydomeCheckBox + // + this.SkydomeCheckBox.AutoSize = true; + this.SkydomeCheckBox.Location = new System.Drawing.Point(19, 60); + this.SkydomeCheckBox.Name = "SkydomeCheckBox"; + this.SkydomeCheckBox.Size = new System.Drawing.Size(70, 17); + this.SkydomeCheckBox.TabIndex = 2; + this.SkydomeCheckBox.Text = "Skydome"; + this.SkydomeCheckBox.UseVisualStyleBackColor = true; + this.SkydomeCheckBox.CheckedChanged += new System.EventHandler(this.SkydomeCheckBox_CheckedChanged); + // + // ShadowsCheckBox + // + this.ShadowsCheckBox.AutoSize = true; + this.ShadowsCheckBox.Checked = true; + this.ShadowsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.ShadowsCheckBox.Location = new System.Drawing.Point(19, 37); + this.ShadowsCheckBox.Name = "ShadowsCheckBox"; + this.ShadowsCheckBox.Size = new System.Drawing.Size(70, 17); + this.ShadowsCheckBox.TabIndex = 1; + this.ShadowsCheckBox.Text = "Shadows"; + this.ShadowsCheckBox.UseVisualStyleBackColor = true; + this.ShadowsCheckBox.CheckedChanged += new System.EventHandler(this.ShadowsCheckBox_CheckedChanged); + // + // WireframeCheckBox + // + this.WireframeCheckBox.AutoSize = true; + this.WireframeCheckBox.Location = new System.Drawing.Point(19, 196); + this.WireframeCheckBox.Name = "WireframeCheckBox"; + this.WireframeCheckBox.Size = new System.Drawing.Size(74, 17); + this.WireframeCheckBox.TabIndex = 8; + this.WireframeCheckBox.Text = "Wireframe"; + this.WireframeCheckBox.UseVisualStyleBackColor = true; + this.WireframeCheckBox.CheckedChanged += new System.EventHandler(this.WireframeCheckBox_CheckedChanged); + // + // RenderModeComboBox + // + this.RenderModeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.RenderModeComboBox.FormattingEnabled = true; + this.RenderModeComboBox.Items.AddRange(new object[] { + "Default", + "Single texture", + "Vertex normals", + "Vertex tangents", + "Vertex colour 1", + "Vertex colour 2", + "Texture coord 1", + "Texture coord 2", + "Texture coord 3"}); + this.RenderModeComboBox.Location = new System.Drawing.Point(83, 274); + this.RenderModeComboBox.Name = "RenderModeComboBox"; + this.RenderModeComboBox.Size = new System.Drawing.Size(114, 21); + this.RenderModeComboBox.TabIndex = 12; + this.RenderModeComboBox.SelectedIndexChanged += new System.EventHandler(this.RenderModeComboBox_SelectedIndexChanged); + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(7, 304); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(67, 13); + this.label11.TabIndex = 13; + this.label11.Text = "Tex sampler:"; + // + // TextureSamplerComboBox + // + this.TextureSamplerComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.TextureSamplerComboBox.Enabled = false; + this.TextureSamplerComboBox.FormattingEnabled = true; + this.TextureSamplerComboBox.Location = new System.Drawing.Point(83, 301); + this.TextureSamplerComboBox.Name = "TextureSamplerComboBox"; + this.TextureSamplerComboBox.Size = new System.Drawing.Size(114, 21); + this.TextureSamplerComboBox.TabIndex = 14; + this.TextureSamplerComboBox.SelectedIndexChanged += new System.EventHandler(this.TextureSamplerComboBox_SelectedIndexChanged); + // + // TextureCoordsComboBox + // + this.TextureCoordsComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.TextureCoordsComboBox.Enabled = false; + this.TextureCoordsComboBox.FormattingEnabled = true; + this.TextureCoordsComboBox.Items.AddRange(new object[] { + "Texture coord 1", + "Texture coord 2", + "Texture coord 3"}); + this.TextureCoordsComboBox.Location = new System.Drawing.Point(83, 328); + this.TextureCoordsComboBox.Name = "TextureCoordsComboBox"; + this.TextureCoordsComboBox.Size = new System.Drawing.Size(114, 21); + this.TextureCoordsComboBox.TabIndex = 16; + this.TextureCoordsComboBox.SelectedIndexChanged += new System.EventHandler(this.TextureCoordsComboBox_SelectedIndexChanged); + // + // label10 + // + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point(7, 277); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(74, 13); + this.label10.TabIndex = 11; + this.label10.Text = "Render mode:"; + // + // AnisotropicFilteringCheckBox + // + this.AnisotropicFilteringCheckBox.AutoSize = true; + this.AnisotropicFilteringCheckBox.Checked = true; + this.AnisotropicFilteringCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.AnisotropicFilteringCheckBox.Location = new System.Drawing.Point(19, 219); + this.AnisotropicFilteringCheckBox.Name = "AnisotropicFilteringCheckBox"; + this.AnisotropicFilteringCheckBox.Size = new System.Drawing.Size(114, 17); + this.AnisotropicFilteringCheckBox.TabIndex = 9; + this.AnisotropicFilteringCheckBox.Text = "Anisotropic filtering"; + this.AnisotropicFilteringCheckBox.UseVisualStyleBackColor = true; + this.AnisotropicFilteringCheckBox.CheckedChanged += new System.EventHandler(this.AnisotropicFilteringCheckBox_CheckedChanged); + // + // label14 + // + this.label14.AutoSize = true; + this.label14.Location = new System.Drawing.Point(7, 331); + this.label14.Name = "label14"; + this.label14.Size = new System.Drawing.Size(63, 13); + this.label14.TabIndex = 15; + this.label14.Text = "Tex coords:"; + // + // DetailsPropertyGrid + // + this.DetailsPropertyGrid.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.DetailsPropertyGrid.HelpVisible = false; + this.DetailsPropertyGrid.Location = new System.Drawing.Point(0, 3); + this.DetailsPropertyGrid.Name = "DetailsPropertyGrid"; + this.DetailsPropertyGrid.PropertySort = System.Windows.Forms.PropertySort.NoSort; + this.DetailsPropertyGrid.ReadOnly = true; + this.DetailsPropertyGrid.Size = new System.Drawing.Size(239, 604); + this.DetailsPropertyGrid.TabIndex = 1; + this.DetailsPropertyGrid.ToolbarVisible = false; + // + // ToolsDetailsTabPage + // + this.ToolsDetailsTabPage.Controls.Add(this.DetailsPropertyGrid); + this.ToolsDetailsTabPage.Location = new System.Drawing.Point(4, 22); + this.ToolsDetailsTabPage.Name = "ToolsDetailsTabPage"; + this.ToolsDetailsTabPage.Size = new System.Drawing.Size(239, 607); + this.ToolsDetailsTabPage.TabIndex = 2; + this.ToolsDetailsTabPage.Text = "Details"; + this.ToolsDetailsTabPage.UseVisualStyleBackColor = true; + // + // TextureViewerButton + // + this.TextureViewerButton.Location = new System.Drawing.Point(6, 6); + this.TextureViewerButton.Name = "TextureViewerButton"; + this.TextureViewerButton.Size = new System.Drawing.Size(113, 23); + this.TextureViewerButton.TabIndex = 2; + this.TextureViewerButton.Text = "Open texture viewer"; + this.TextureViewerButton.UseVisualStyleBackColor = true; + this.TextureViewerButton.Click += new System.EventHandler(this.TextureViewerButton_Click); + // + // TexturesTreeView + // + this.TexturesTreeView.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.TexturesTreeView.Location = new System.Drawing.Point(0, 34); + this.TexturesTreeView.Name = "TexturesTreeView"; + this.TexturesTreeView.ShowRootLines = false; + this.TexturesTreeView.Size = new System.Drawing.Size(239, 573); + this.TexturesTreeView.TabIndex = 1; + // + // ToolsTexturesTabPage + // + this.ToolsTexturesTabPage.Controls.Add(this.TextureViewerButton); + this.ToolsTexturesTabPage.Controls.Add(this.TexturesTreeView); + this.ToolsTexturesTabPage.Location = new System.Drawing.Point(4, 22); + this.ToolsTexturesTabPage.Name = "ToolsTexturesTabPage"; + this.ToolsTexturesTabPage.Padding = new System.Windows.Forms.Padding(3); + this.ToolsTexturesTabPage.Size = new System.Drawing.Size(239, 607); + this.ToolsTexturesTabPage.TabIndex = 1; + this.ToolsTexturesTabPage.Text = "Textures"; + this.ToolsTexturesTabPage.UseVisualStyleBackColor = true; + // + // ModelsTreeView + // + this.ModelsTreeView.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.ModelsTreeView.CheckBoxes = true; + this.ModelsTreeView.Location = new System.Drawing.Point(0, 3); + this.ModelsTreeView.Name = "ModelsTreeView"; + this.ModelsTreeView.ShowRootLines = false; + this.ModelsTreeView.Size = new System.Drawing.Size(239, 604); + this.ModelsTreeView.TabIndex = 2; + this.ModelsTreeView.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.ModelsTreeView_AfterCheck); + this.ModelsTreeView.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.ModelsTreeView_NodeMouseDoubleClick); + this.ModelsTreeView.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.ModelsTreeView_KeyPress); + // + // StatusStrip + // + this.StatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.StatusLabel, + this.MousedLabel, + this.StatsLabel}); + this.StatusStrip.Location = new System.Drawing.Point(0, 689); + this.StatusStrip.Name = "StatusStrip"; + this.StatusStrip.Size = new System.Drawing.Size(984, 22); + this.StatusStrip.TabIndex = 6; + this.StatusStrip.Text = "statusStrip1"; + // + // StatusLabel + // + this.StatusLabel.BackColor = System.Drawing.SystemColors.Control; + this.StatusLabel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.StatusLabel.Name = "StatusLabel"; + this.StatusLabel.Size = new System.Drawing.Size(878, 17); + this.StatusLabel.Spring = true; + this.StatusLabel.Text = "Initialising"; + this.StatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // MousedLabel + // + this.MousedLabel.BackColor = System.Drawing.SystemColors.Control; + this.MousedLabel.Name = "MousedLabel"; + this.MousedLabel.Size = new System.Drawing.Size(16, 17); + this.MousedLabel.Text = " "; + // + // StatsLabel + // + this.StatsLabel.BackColor = System.Drawing.SystemColors.Control; + this.StatsLabel.Name = "StatsLabel"; + this.StatsLabel.Size = new System.Drawing.Size(75, 17); + this.StatsLabel.Text = "0 geometries"; + // + // ToolsModelsTabPage + // + this.ToolsModelsTabPage.Controls.Add(this.ModelsTreeView); + this.ToolsModelsTabPage.Location = new System.Drawing.Point(4, 22); + this.ToolsModelsTabPage.Name = "ToolsModelsTabPage"; + this.ToolsModelsTabPage.Padding = new System.Windows.Forms.Padding(3); + this.ToolsModelsTabPage.Size = new System.Drawing.Size(239, 607); + this.ToolsModelsTabPage.TabIndex = 0; + this.ToolsModelsTabPage.Text = "Models"; + this.ToolsModelsTabPage.UseVisualStyleBackColor = true; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(3, 11); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(38, 13); + this.label3.TabIndex = 1; + this.label3.Text = "Name:"; + // + // PedNameComboBox + // + this.PedNameComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.PedNameComboBox.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend; + this.PedNameComboBox.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems; + this.PedNameComboBox.FormattingEnabled = true; + this.PedNameComboBox.Location = new System.Drawing.Point(54, 8); + this.PedNameComboBox.Name = "PedNameComboBox"; + this.PedNameComboBox.Size = new System.Drawing.Size(182, 21); + this.PedNameComboBox.TabIndex = 0; + // + // StatsUpdateTimer + // + this.StatsUpdateTimer.Enabled = true; + this.StatsUpdateTimer.Interval = 500; + this.StatsUpdateTimer.Tick += new System.EventHandler(this.StatsUpdateTimer_Tick); + // + // ToolsPedTabPage + // + this.ToolsPedTabPage.Controls.Add(this.label3); + this.ToolsPedTabPage.Controls.Add(this.PedNameComboBox); + this.ToolsPedTabPage.Location = new System.Drawing.Point(4, 22); + this.ToolsPedTabPage.Name = "ToolsPedTabPage"; + this.ToolsPedTabPage.Size = new System.Drawing.Size(239, 607); + this.ToolsPedTabPage.TabIndex = 4; + this.ToolsPedTabPage.Text = "Ped"; + this.ToolsPedTabPage.UseVisualStyleBackColor = true; + // + // ToolsTabControl + // + this.ToolsTabControl.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.ToolsTabControl.Controls.Add(this.ToolsPedTabPage); + this.ToolsTabControl.Controls.Add(this.ToolsModelsTabPage); + this.ToolsTabControl.Controls.Add(this.ToolsTexturesTabPage); + this.ToolsTabControl.Controls.Add(this.ToolsDetailsTabPage); + this.ToolsTabControl.Controls.Add(this.ToolsOptionsTabPage); + this.ToolsTabControl.Location = new System.Drawing.Point(2, 30); + this.ToolsTabControl.Name = "ToolsTabControl"; + this.ToolsTabControl.SelectedIndex = 0; + this.ToolsTabControl.Size = new System.Drawing.Size(247, 633); + this.ToolsTabControl.TabIndex = 1; + // + // ToolsPanel + // + this.ToolsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.ToolsPanel.BackColor = System.Drawing.SystemColors.ControlDark; + this.ToolsPanel.Controls.Add(this.ToolsTabControl); + this.ToolsPanel.Controls.Add(this.ToolsPanelHideButton); + this.ToolsPanel.Controls.Add(this.ToolsDragPanel); + this.ToolsPanel.Location = new System.Drawing.Point(12, 12); + this.ToolsPanel.Name = "ToolsPanel"; + this.ToolsPanel.Size = new System.Drawing.Size(252, 666); + this.ToolsPanel.TabIndex = 7; + this.ToolsPanel.Visible = false; + // + // PedsForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.MidnightBlue; + this.ClientSize = new System.Drawing.Size(984, 711); + this.Controls.Add(this.ConsolePanel); + this.Controls.Add(this.StatusStrip); + this.Controls.Add(this.ToolsPanel); + this.Controls.Add(this.ToolsPanelShowButton); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.KeyPreview = true; + this.Name = "PedsForm"; + this.Text = "Ped Viewer - CodeWalker by dexyfex"; + this.Deactivate += new System.EventHandler(this.PedsForm_Deactivate); + this.Load += new System.EventHandler(this.PedsForm_Load); + this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.PedsForm_KeyDown); + this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.PedsForm_KeyUp); + this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PedsForm_MouseDown); + this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PedsForm_MouseMove); + this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.PedsForm_MouseUp); + this.ConsolePanel.ResumeLayout(false); + this.ConsolePanel.PerformLayout(); + this.ToolsOptionsTabPage.ResumeLayout(false); + this.ToolsOptionsTabPage.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.TimeOfDayTrackBar)).EndInit(); + this.ToolsDetailsTabPage.ResumeLayout(false); + this.ToolsTexturesTabPage.ResumeLayout(false); + this.StatusStrip.ResumeLayout(false); + this.StatusStrip.PerformLayout(); + this.ToolsModelsTabPage.ResumeLayout(false); + this.ToolsPedTabPage.ResumeLayout(false); + this.ToolsPedTabPage.PerformLayout(); + this.ToolsTabControl.ResumeLayout(false); + this.ToolsPanel.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private WinForms.TextBoxFix ConsoleTextBox; + private System.Windows.Forms.Button ToolsPanelShowButton; + private System.Windows.Forms.Button ToolsPanelHideButton; + private System.Windows.Forms.Panel ToolsDragPanel; + private System.Windows.Forms.Panel ConsolePanel; + private System.Windows.Forms.CheckBox HDTexturesCheckBox; + private System.Windows.Forms.CheckBox SkeletonsCheckBox; + private System.Windows.Forms.Label TimeOfDayLabel; + private System.Windows.Forms.TabPage ToolsOptionsTabPage; + private System.Windows.Forms.Label label19; + private System.Windows.Forms.TrackBar TimeOfDayTrackBar; + private System.Windows.Forms.CheckBox ControlLightDirCheckBox; + private System.Windows.Forms.CheckBox ShowCollisionMeshesCheckBox; + private System.Windows.Forms.CheckBox GridCheckBox; + private System.Windows.Forms.ComboBox GridCountComboBox; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.ComboBox GridSizeComboBox; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.CheckBox StatusBarCheckBox; + private System.Windows.Forms.CheckBox ErrorConsoleCheckBox; + private System.Windows.Forms.CheckBox HDRRenderingCheckBox; + private System.Windows.Forms.CheckBox SkydomeCheckBox; + private System.Windows.Forms.CheckBox ShadowsCheckBox; + private System.Windows.Forms.CheckBox WireframeCheckBox; + private System.Windows.Forms.ComboBox RenderModeComboBox; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.ComboBox TextureSamplerComboBox; + private System.Windows.Forms.ComboBox TextureCoordsComboBox; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.CheckBox AnisotropicFilteringCheckBox; + private System.Windows.Forms.Label label14; + private WinForms.ReadOnlyPropertyGrid DetailsPropertyGrid; + private System.Windows.Forms.TabPage ToolsDetailsTabPage; + private System.Windows.Forms.Button TextureViewerButton; + private WinForms.TreeViewFix TexturesTreeView; + private System.Windows.Forms.TabPage ToolsTexturesTabPage; + private WinForms.TreeViewFix ModelsTreeView; + private System.Windows.Forms.StatusStrip StatusStrip; + private System.Windows.Forms.ToolStripStatusLabel StatusLabel; + private System.Windows.Forms.ToolStripStatusLabel MousedLabel; + private System.Windows.Forms.ToolStripStatusLabel StatsLabel; + private System.Windows.Forms.TabPage ToolsModelsTabPage; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.ComboBox PedNameComboBox; + private System.Windows.Forms.Timer StatsUpdateTimer; + private System.Windows.Forms.TabPage ToolsPedTabPage; + private System.Windows.Forms.TabControl ToolsTabControl; + private System.Windows.Forms.Panel ToolsPanel; + } +} \ No newline at end of file diff --git a/Peds/PedsForm.cs b/Peds/PedsForm.cs new file mode 100644 index 0000000..34af71f --- /dev/null +++ b/Peds/PedsForm.cs @@ -0,0 +1,1417 @@ +using CodeWalker.GameFiles; +using CodeWalker.Properties; +using CodeWalker.Rendering; +using CodeWalker.World; +using SharpDX; +using SharpDX.Direct3D11; +using SharpDX.XInput; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using Color = SharpDX.Color; + +namespace CodeWalker.Peds +{ + public partial class PedsForm : Form, DXForm + { + public Form Form { get { return this; } } //for DXForm/DXManager use + + public Renderer Renderer = null; + public object RenderSyncRoot { get { return Renderer.RenderSyncRoot; } } + + volatile bool formopen = false; + volatile bool running = false; + volatile bool pauserendering = false; + //volatile bool initialised = false; + + Stopwatch frametimer = new Stopwatch(); + Camera camera; + Timecycle timecycle; + Weather weather; + Clouds clouds; + + Entity camEntity = new Entity(); + + + bool MouseLButtonDown = false; + bool MouseRButtonDown = false; + int MouseX; + int MouseY; + System.Drawing.Point MouseDownPoint; + System.Drawing.Point MouseLastPoint; + + + public GameFileCache GameFileCache { get; } = GameFileCacheFactory.Create(); + + + InputManager Input = new InputManager(); + + + bool initedOk = false; + + + + bool toolsPanelResizing = false; + int toolsPanelResizeStartX = 0; + int toolsPanelResizeStartLeft = 0; + int toolsPanelResizeStartRight = 0; + + Dictionary DrawableDrawFlags = new Dictionary(); + + bool enableGrid = false; + float gridSize = 1.0f; + int gridCount = 40; + List gridVerts = new List(); + object gridSyncRoot = new object(); + + + + public PedsForm() + { + InitializeComponent(); + + Renderer = new Renderer(this, GameFileCache); + camera = Renderer.camera; + timecycle = Renderer.timecycle; + weather = Renderer.weather; + clouds = Renderer.clouds; + + initedOk = Renderer.Init(); + + Renderer.controllightdir = !Settings.Default.Skydome; + Renderer.rendercollisionmeshes = false; + Renderer.renderclouds = false; + //Renderer.renderclouds = true; + //Renderer.individualcloudfrag = "Contrails"; + Renderer.rendermoon = false; + Renderer.renderskeletons = false; + Renderer.SelectionFlagsTestAll = true; + + } + + public void InitScene(Device device) + { + int width = ClientSize.Width; + int height = ClientSize.Height; + + try + { + Renderer.DeviceCreated(device, width, height); + } + catch (Exception ex) + { + MessageBox.Show("Error loading shaders!\n" + ex.ToString()); + return; + } + + + camera.FollowEntity = camEntity; + camera.FollowEntity.Position = Vector3.Zero;// prevworldpos; + camera.FollowEntity.Orientation = Quaternion.LookAtLH(Vector3.Zero, Vector3.Up, Vector3.ForwardLH); + camera.TargetDistance = 2.0f; + camera.CurrentDistance = 2.0f; + camera.TargetRotation.Y = 0.2f; + camera.CurrentRotation.Y = 0.2f; + camera.TargetRotation.X = 0.5f * (float)Math.PI; + camera.CurrentRotation.X = 0.5f * (float)Math.PI; + + + LoadSettings(); + + + formopen = true; + new Thread(new ThreadStart(ContentThread)).Start(); + + frametimer.Start(); + + } + public void CleanupScene() + { + formopen = false; + + Renderer.DeviceDestroyed(); + + int count = 0; + while (running && (count < 5000)) //wait for the content thread to exit gracefully + { + Thread.Sleep(1); + count++; + } + } + public void RenderScene(DeviceContext context) + { + float elapsed = (float)frametimer.Elapsed.TotalSeconds; + frametimer.Restart(); + + if (pauserendering) return; + + if (!Monitor.TryEnter(Renderer.RenderSyncRoot, 50)) + { return; } //couldn't get a lock, try again next time + + UpdateControlInputs(elapsed); + //space.Update(elapsed); + + + Renderer.Update(elapsed, MouseLastPoint.X, MouseLastPoint.Y); + + + + //UpdateWidgets(); + //BeginMouseHitTest(); + + + + + Renderer.BeginRender(context); + + Renderer.RenderSkyAndClouds(); + + Renderer.SelectedDrawable = null;// SelectedItem.Drawable; + + + RenderPed(); + + //UpdateMouseHitsFromRenderer(); + //RenderSelection(); + + + RenderGrid(context); + + + Renderer.RenderQueued(); + + //Renderer.RenderBounds(MapSelectionMode.Entity); + + //Renderer.RenderSelectionGeometry(MapSelectionMode.Entity); + + //RenderMoused(); + + Renderer.RenderFinalPass(); + + //RenderMarkers(); + //RenderWidgets(); + + Renderer.EndRender(); + + Monitor.Exit(Renderer.RenderSyncRoot); + + //UpdateMarkerSelectionPanelInvoke(); + } + public void BuffersResized(int w, int h) + { + Renderer.BuffersResized(w, h); + } + + + + + + private void Init() + { + //called from PedForm_Load + + if (!initedOk) + { + Close(); + return; + } + + + MouseWheel += PedsForm_MouseWheel; + + if (!GTAFolder.UpdateGTAFolder(true)) + { + Close(); + return; + } + + + + ShaderParamNames[] texsamplers = RenderableGeometry.GetTextureSamplerList(); + foreach (var texsampler in texsamplers) + { + TextureSamplerComboBox.Items.Add(texsampler); + } + //TextureSamplerComboBox.SelectedIndex = 0;//LoadSettings will do this.. + + + UpdateGridVerts(); + GridSizeComboBox.SelectedIndex = 1; + GridCountComboBox.SelectedIndex = 1; + + + + Input.Init(); + + + Renderer.Start(); + } + + + private void ContentThread() + { + //main content loading thread. + running = true; + + UpdateStatus("Scanning..."); + + try + { + GTA5Keys.LoadFromPath(GTAFolder.CurrentGTAFolder, Settings.Default.Key); + } + catch + { + MessageBox.Show("Keys not found! This shouldn't happen."); + Close(); + return; + } + + GameFileCache.EnableDlc = true; + GameFileCache.LoadPeds = true; + GameFileCache.LoadArchetypes = false;//to speed things up a little + GameFileCache.BuildExtendedJenkIndex = false;//to speed things up a little + GameFileCache.DoFullStringIndex = true;//to get all global text from DLC... + GameFileCache.Init(UpdateStatus, LogError); + + //UpdateDlcListComboBox(gameFileCache.DlcNameList); + + //EnableCacheDependentUI(); + + UpdateGlobalPedsUI(); + + + LoadWorld(); + + + + //initialised = true; + + //EnableDLCModsUI(); + + //UpdateStatus("Ready"); + + + Task.Run(() => { + while (formopen && !IsDisposed) //renderer content loop + { + bool rcItemsPending = Renderer.ContentThreadProc(); + + if (!rcItemsPending) + { + Thread.Sleep(1); //sleep if there's nothing to do + } + } + }); + + while (formopen && !IsDisposed) //main asset loop + { + bool fcItemsPending = GameFileCache.ContentThreadProc(); + + if (!fcItemsPending) + { + Thread.Sleep(1); //sleep if there's nothing to do + } + } + + GameFileCache.Clear(); + + running = false; + } + + + + + private void LoadSettings() + { + var s = Settings.Default; + //WindowState = s.WindowMaximized ? FormWindowState.Maximized : WindowState; + //FullScreenCheckBox.Checked = s.FullScreen; + WireframeCheckBox.Checked = s.Wireframe; + HDRRenderingCheckBox.Checked = s.HDR; + ShadowsCheckBox.Checked = s.Shadows; + SkydomeCheckBox.Checked = s.Skydome; + RenderModeComboBox.SelectedIndex = Math.Max(RenderModeComboBox.FindString(s.RenderMode), 0); + TextureSamplerComboBox.SelectedIndex = Math.Max(TextureSamplerComboBox.FindString(s.RenderTextureSampler), 0); + TextureCoordsComboBox.SelectedIndex = Math.Max(TextureCoordsComboBox.FindString(s.RenderTextureSamplerCoord), 0); + AnisotropicFilteringCheckBox.Checked = s.AnisotropicFiltering; + //ErrorConsoleCheckBox.Checked = s.ShowErrorConsole; + //StatusBarCheckBox.Checked = s.ShowStatusBar; + } + + + + private void LoadWorld() + { + UpdateStatus("Loading timecycles..."); + timecycle.Init(GameFileCache, UpdateStatus); + timecycle.SetTime(Renderer.timeofday); + + UpdateStatus("Loading materials..."); + BoundsMaterialTypes.Init(GameFileCache); + + UpdateStatus("Loading weather..."); + weather.Init(GameFileCache, UpdateStatus, timecycle); + //UpdateWeatherTypesComboBox(weather); + + UpdateStatus("Loading clouds..."); + clouds.Init(GameFileCache, UpdateStatus, weather); + //UpdateCloudTypesComboBox(clouds); + + } + + + + + + + private void UpdateStatus(string text) + { + try + { + if (InvokeRequired) + { + BeginInvoke(new Action(() => { UpdateStatus(text); })); + } + else + { + StatusLabel.Text = text; + } + } + catch { } + } + private void LogError(string text) + { + try + { + if (InvokeRequired) + { + Invoke(new Action(() => { LogError(text); })); + } + else + { + //TODO: error logging.. + ConsoleTextBox.AppendText(text + "\r\n"); + //StatusLabel.Text = text; + //MessageBox.Show(text); + } + } + catch { } + } + + + + + private void UpdateMousePosition(MouseEventArgs e) + { + MouseX = e.X; + MouseY = e.Y; + MouseLastPoint = e.Location; + } + + private void RotateCam(int dx, int dy) + { + camera.MouseRotate(dx, dy); + } + + private void MoveCameraToView(Vector3 pos, float rad) + { + //move the camera to a default place where the given sphere is fully visible. + + rad = Math.Max(0.01f, rad); + + camera.FollowEntity.Position = pos; + camera.TargetDistance = rad * 1.6f; + camera.CurrentDistance = rad * 1.6f; + + camera.ZFar = Math.Min(rad * 200.0f, 12000.0f); + camera.ZNear = Math.Min(camera.ZFar * 5e-5f, 0.5f); + camera.UpdateProj = true; + + } + + + + + + + + private void AddDrawableTreeNode(DrawableBase drawable, uint hash, bool check) + { + MetaHash mhash = new MetaHash(hash); + + var dnode = ModelsTreeView.Nodes.Add(mhash.ToString()); + dnode.Tag = drawable; + dnode.Checked = check; + + AddDrawableModelsTreeNodes(drawable.DrawableModelsHigh, "High Detail", true, dnode); + AddDrawableModelsTreeNodes(drawable.DrawableModelsMedium, "Medium Detail", false, dnode); + AddDrawableModelsTreeNodes(drawable.DrawableModelsLow, "Low Detail", false, dnode); + AddDrawableModelsTreeNodes(drawable.DrawableModelsVeryLow, "Very Low Detail", false, dnode); + //AddSelectionDrawableModelsTreeNodes(item.Drawable.DrawableModelsX, "X Detail", false, dnode); + + } + private void AddDrawableModelsTreeNodes(ResourcePointerList64 models, string prefix, bool check, TreeNode parentDrawableNode = null) + { + if (models == null) return; + if (models.data_items == null) return; + + for (int mi = 0; mi < models.data_items.Length; mi++) + { + var tnc = (parentDrawableNode != null) ? parentDrawableNode.Nodes : ModelsTreeView.Nodes; + + var model = models.data_items[mi]; + string mprefix = prefix + " " + (mi + 1).ToString(); + var mnode = tnc.Add(mprefix + " " + model.ToString()); + mnode.Tag = model; + mnode.Checked = check; + + var tmnode = TexturesTreeView.Nodes.Add(mprefix + " " + model.ToString()); + tmnode.Tag = model; + + if (!check) + { + Renderer.SelectionModelDrawFlags[model] = false; + } + + if ((model.Geometries == null) || (model.Geometries.data_items == null)) continue; + + foreach (var geom in model.Geometries.data_items) + { + var gname = geom.ToString(); + var gnode = mnode.Nodes.Add(gname); + gnode.Tag = geom; + gnode.Checked = true;// check; + + var tgnode = tmnode.Nodes.Add(gname); + tgnode.Tag = geom; + + if ((geom.Shader != null) && (geom.Shader.ParametersList != null) && (geom.Shader.ParametersList.Hashes != null)) + { + var pl = geom.Shader.ParametersList; + var h = pl.Hashes; + var p = pl.Parameters; + for (int ip = 0; ip < h.Length; ip++) + { + var hash = pl.Hashes[ip]; + var parm = pl.Parameters[ip]; + var tex = parm.Data as TextureBase; + if (tex != null) + { + var t = tex as Texture; + var tstr = tex.Name.Trim(); + if (t != null) + { + tstr = string.Format("{0} ({1}x{2}, embedded)", tex.Name, t.Width, t.Height); + } + var tnode = tgnode.Nodes.Add(hash.ToString().Trim() + ": " + tstr); + tnode.Tag = tex; + } + } + tgnode.Expand(); + } + + } + + mnode.Expand(); + tmnode.Expand(); + } + } + private void UpdateSelectionDrawFlags(TreeNode node) + { + //update the selection draw flags depending on tag and checked/unchecked + var drwbl = node.Tag as DrawableBase; + var model = node.Tag as DrawableModel; + var geom = node.Tag as DrawableGeometry; + bool rem = node.Checked; + lock (Renderer.RenderSyncRoot) + { + if (drwbl != null) + { + if (rem) + { + if (DrawableDrawFlags.ContainsKey(drwbl)) + { + DrawableDrawFlags.Remove(drwbl); + } + } + else + { + DrawableDrawFlags[drwbl] = false; + } + } + if (model != null) + { + if (rem) + { + if (Renderer.SelectionModelDrawFlags.ContainsKey(model)) + { + Renderer.SelectionModelDrawFlags.Remove(model); + } + } + else + { + Renderer.SelectionModelDrawFlags[model] = false; + } + } + if (geom != null) + { + if (rem) + { + if (Renderer.SelectionGeometryDrawFlags.ContainsKey(geom)) + { + Renderer.SelectionGeometryDrawFlags.Remove(geom); + } + } + else + { + Renderer.SelectionGeometryDrawFlags[geom] = false; + } + } + //updateArchetypeStatus = true; + } + } + + + private void UpdateGlobalPedsUI() + { + if (InvokeRequired) + { + BeginInvoke(new Action(() => { UpdateGlobalPedsUI(); })); + } + else + { + PedNameComboBox.Items.Clear(); + + var peds = GameFileCache.PedsInitDict.Values.ToList(); + peds.Sort((a, b) => { return a.Name.CompareTo(b.Name); }); + foreach (var ped in peds) + { + PedNameComboBox.Items.Add(ped.Name); + } + if (peds.Count > 0) + { + PedNameComboBox.SelectedIndex = 0; + } + + } + + } + + + + + + private void UpdateModelsUI(DrawableBase drawable) + { + DetailsPropertyGrid.SelectedObject = drawable; + + DrawableDrawFlags.Clear(); + Renderer.SelectionModelDrawFlags.Clear(); + Renderer.SelectionGeometryDrawFlags.Clear(); + ModelsTreeView.Nodes.Clear(); + ModelsTreeView.ShowRootLines = false; + TexturesTreeView.Nodes.Clear(); + if (drawable != null) + { + AddDrawableModelsTreeNodes(drawable.DrawableModelsHigh, "High Detail", true); + AddDrawableModelsTreeNodes(drawable.DrawableModelsMedium, "Medium Detail", false); + AddDrawableModelsTreeNodes(drawable.DrawableModelsLow, "Low Detail", false); + AddDrawableModelsTreeNodes(drawable.DrawableModelsVeryLow, "Very Low Detail", false); + //AddSelectionDrawableModelsTreeNodes(item.Drawable.DrawableModelsX, "X Detail", false); + + + var fdrawable = drawable as FragDrawable; + if (fdrawable != null) + { + var plod1 = fdrawable.OwnerFragment?.PhysicsLODGroup?.PhysicsLOD1; + if ((plod1 != null) && (plod1.Children?.data_items != null)) + { + foreach (var child in plod1.Children.data_items) + { + var cdrwbl = child.Drawable1; + if ((cdrwbl != null) && (cdrwbl.AllModels?.Length > 0)) + { + if (cdrwbl.Owner is FragDrawable) continue; //it's a copied drawable... eg a wheel + + var dname = child.GroupNameHash.ToString(); + AddDrawableModelsTreeNodes(cdrwbl.DrawableModelsHigh, dname + " - High Detail", true); + AddDrawableModelsTreeNodes(cdrwbl.DrawableModelsMedium, dname + " - Medium Detail", false); + AddDrawableModelsTreeNodes(cdrwbl.DrawableModelsLow, dname + " - Low Detail", false); + AddDrawableModelsTreeNodes(cdrwbl.DrawableModelsVeryLow, dname + " - Very Low Detail", false); + } + } + } + } + + } + } + + + + public void LoadPed() + { + var pedname = PedNameComboBox.Text; + var pednamel = pedname.ToLowerInvariant(); + MetaHash pedhash = JenkHash.GenHash(pednamel); + + + //MetaHash modelhashhi = JenkHash.GenHash(pednamel + "_hi"); + //bool hidet = VehicleHighDetailCheckBox.Checked; + //var yfthash = hidet ? modelhashhi : pedhash; + //VehicleInitData vid = null; + //if (GameFileCache.VehiclesInitDict.TryGetValue(pedhash, out vid)) + //{ + // bool vehiclechange = SelectedVehicleHash != pedhash; + // SelectedModelHash = yfthash; + // SelectedVehicleHash = pedhash; + // SelectedVehicleInit = vid; + // SelectedVehicleYft = GameFileCache.GetYft(SelectedModelHash); + // while (!SelectedVehicleYft.Loaded) + // { + // Thread.Sleep(20);//kinda hacky + // SelectedVehicleYft = GameFileCache.GetYft(SelectedModelHash); + // } + // LoadModel(SelectedVehicleYft, vehiclechange); + // VehicleMakeLabel.Text = GlobalText.TryGetString(JenkHash.GenHash(vid.vehicleMakeName.ToLower())); + // VehicleNameLabel.Text = GlobalText.TryGetString(JenkHash.GenHash(vid.gameName.ToLower())); + //} + //else + //{ + // SelectedModelHash = 0; + // SelectedVehicleHash = 0; + // SelectedVehicleInit = null; + // SelectedVehicleYft = null; + // VehicleMakeLabel.Text = "-"; + // VehicleNameLabel.Text = "-"; + //} + } + + public void LoadModel(YftFile yft, bool movecamera = true) + { + if (yft == null) return; + + //FileName = yft.Name; + //Yft = yft; + + var dr = yft.Fragment?.Drawable; + if (movecamera && (dr != null)) + { + MoveCameraToView(dr.BoundingCenter, dr.BoundingSphereRadius); + } + + UpdateModelsUI(yft.Fragment.Drawable); + } + + + + private void UpdateTimeOfDayLabel() + { + int v = TimeOfDayTrackBar.Value; + float fh = v / 60.0f; + int ih = (int)fh; + int im = v - (ih * 60); + if (ih == 24) ih = 0; + TimeOfDayLabel.Text = string.Format("{0:00}:{1:00}", ih, im); + } + + + private void UpdateControlInputs(float elapsed) + { + if (elapsed > 0.1f) elapsed = 0.1f; + + var s = Settings.Default; + + float moveSpeed = 2.0f; + + + Input.Update(elapsed); + + if (Input.xbenable) + { + //if (ControllerButtonJustPressed(GamepadButtonFlags.Start)) + //{ + // SetControlMode(ControlMode == WorldControlMode.Free ? WorldControlMode.Ped : WorldControlMode.Free); + //} + } + + + + if (Input.ShiftPressed) + { + moveSpeed *= 5.0f; + } + if (Input.CtrlPressed) + { + moveSpeed *= 0.2f; + } + + Vector3 movevec = Input.KeyboardMoveVec(false); + + + //if (MapViewEnabled == true) + //{ + // movevec *= elapsed * 100.0f * Math.Min(camera.OrthographicTargetSize * 0.01f, 30.0f); + // float mapviewscale = 1.0f / camera.Height; + // float fdx = MapViewDragX * mapviewscale; + // float fdy = MapViewDragY * mapviewscale; + // movevec.X -= fdx * camera.OrthographicSize; + // movevec.Y += fdy * camera.OrthographicSize; + //} + //else + { + //normal movement + movevec *= elapsed * moveSpeed * Math.Min(camera.TargetDistance, 50.0f); + } + + + Vector3 movewvec = camera.ViewInvQuaternion.Multiply(movevec); + camEntity.Position += movewvec; + + //MapViewDragX = 0; + //MapViewDragY = 0; + + + + + if (Input.xbenable) + { + camera.ControllerRotate(Input.xblx + Input.xbrx, Input.xbly + Input.xbry); + + float zoom = 0.0f; + float zoomspd = s.XInputZoomSpeed; + float zoomamt = zoomspd * elapsed; + if (Input.ControllerButtonPressed(GamepadButtonFlags.DPadUp)) zoom += zoomamt; + if (Input.ControllerButtonPressed(GamepadButtonFlags.DPadDown)) zoom -= zoomamt; + + camera.ControllerZoom(zoom); + + float acc = 0.0f; + float accspd = s.XInputMoveSpeed;//actually accel speed... + acc += Input.xbrt * accspd; + acc -= Input.xblt * accspd; + + Vector3 newdir = camera.ViewDirection; //maybe use the "vehicle" direction...? + Input.xbcontrolvelocity += (acc * elapsed); + + if (Input.ControllerButtonPressed(GamepadButtonFlags.A | GamepadButtonFlags.RightShoulder)) //handbrake... + { + Input.xbcontrolvelocity *= Math.Max(0.75f - elapsed, 0);//not ideal for low fps... + //xbcontrolvelocity = 0.0f; + if (Math.Abs(Input.xbcontrolvelocity) < 0.001f) Input.xbcontrolvelocity = 0.0f; + } + + camEntity.Velocity = newdir * Input.xbcontrolvelocity; + camEntity.Position += camEntity.Velocity * elapsed; + + + //fire! + //if (ControllerButtonJustPressed(GamepadButtonFlags.LeftShoulder)) + //{ + // SpawnTestEntity(true); + //} + + } + + + + } + + + + private void UpdateGridVerts() + { + lock (gridSyncRoot) + { + gridVerts.Clear(); + + float s = gridSize * gridCount * 0.5f; + uint cblack = (uint)Color.Black.ToRgba(); + uint cgray = (uint)Color.DimGray.ToRgba(); + uint cred = (uint)Color.DarkRed.ToRgba(); + uint cgrn = (uint)Color.DarkGreen.ToRgba(); + int interval = 10; + + for (int i = 0; i <= gridCount; i++) + { + float o = (gridSize * i) - s; + if ((i % interval) != 0) + { + gridVerts.Add(new VertexTypePC() { Position = new Vector3(o, -s, 0), Colour = cgray }); + gridVerts.Add(new VertexTypePC() { Position = new Vector3(o, s, 0), Colour = cgray }); + gridVerts.Add(new VertexTypePC() { Position = new Vector3(-s, o, 0), Colour = cgray }); + gridVerts.Add(new VertexTypePC() { Position = new Vector3(s, o, 0), Colour = cgray }); + } + } + for (int i = 0; i <= gridCount; i++) //draw main lines last, so they are on top + { + float o = (gridSize * i) - s; + if ((i % interval) == 0) + { + var cx = (o == 0) ? cred : cblack; + var cy = (o == 0) ? cgrn : cblack; + gridVerts.Add(new VertexTypePC() { Position = new Vector3(o, -s, 0), Colour = cy }); + gridVerts.Add(new VertexTypePC() { Position = new Vector3(o, s, 0), Colour = cy }); + gridVerts.Add(new VertexTypePC() { Position = new Vector3(-s, o, 0), Colour = cx }); + gridVerts.Add(new VertexTypePC() { Position = new Vector3(s, o, 0), Colour = cx }); + } + } + + } + } + + private void RenderGrid(DeviceContext context) + { + if (!enableGrid) return; + + lock (gridSyncRoot) + { + if (gridVerts.Count > 0) + { + Renderer.RenderLines(gridVerts); + } + } + } + + + + + + + + private void RenderPed() + { + + //YftFile yft = GameFileCache.GetYft(SelectedModelHash); + //if (yft != null) + //{ + // if (yft.Loaded) + // { + // if (yft.Fragment != null) + // { + // var f = yft.Fragment; + + // var txdhash = SelectedVehicleHash;// yft.RpfFileEntry?.ShortNameHash ?? 0; + + // var namelower = yft.RpfFileEntry?.GetShortNameLower(); + // if (namelower?.EndsWith("_hi") ?? false) + // { + // txdhash = JenkHash.GenHash(namelower.Substring(0, namelower.Length - 3)); + // } + + // Archetype arch = null;// TryGetArchetype(hash); + + // Renderer.RenderFragment(arch, null, f, txdhash); + + // //seldrwbl = f.Drawable; + // } + // } + //} + + } + + + + + + + + + + + private void PedsForm_Load(object sender, EventArgs e) + { + Init(); + } + + private void PedsForm_MouseDown(object sender, MouseEventArgs e) + { + switch (e.Button) + { + case MouseButtons.Left: MouseLButtonDown = true; break; + case MouseButtons.Right: MouseRButtonDown = true; break; + } + + if (!ToolsPanelShowButton.Focused) + { + ToolsPanelShowButton.Focus(); //make sure no textboxes etc are focused! + } + + MouseDownPoint = e.Location; + MouseLastPoint = MouseDownPoint; + + if (MouseLButtonDown) + { + } + + if (MouseRButtonDown) + { + //SelectMousedItem(); + } + + MouseX = e.X; //to stop jumps happening on mousedown, sometimes the last MouseMove event was somewhere else... (eg after clicked a menu) + MouseY = e.Y; + } + + private void PedsForm_MouseUp(object sender, MouseEventArgs e) + { + switch (e.Button) + { + case MouseButtons.Left: MouseLButtonDown = false; break; + case MouseButtons.Right: MouseRButtonDown = false; break; + } + + + + if (e.Button == MouseButtons.Left) + { + } + } + + private void PedsForm_MouseMove(object sender, MouseEventArgs e) + { + int dx = e.X - MouseX; + int dy = e.Y - MouseY; + + //if (MouseInvert) + //{ + // dy = -dy; + //} + + //if (ControlMode == WorldControlMode.Free && !ControlBrushEnabled) + { + if (MouseLButtonDown) + { + RotateCam(dx, dy); + } + if (MouseRButtonDown) + { + if (Renderer.controllightdir) + { + Renderer.lightdirx += (dx * camera.Sensitivity); + Renderer.lightdiry += (dy * camera.Sensitivity); + } + else if (Renderer.controltimeofday) + { + float tod = Renderer.timeofday; + tod += (dx - dy) / 30.0f; + while (tod >= 24.0f) tod -= 24.0f; + while (tod < 0.0f) tod += 24.0f; + timecycle.SetTime(tod); + Renderer.timeofday = tod; + + float fv = tod * 60.0f; + TimeOfDayTrackBar.Value = (int)fv; + UpdateTimeOfDayLabel(); + } + } + + UpdateMousePosition(e); + + } + + + + } + + private void PedsForm_MouseWheel(object sender, MouseEventArgs e) + { + if (e.Delta != 0) + { + camera.MouseZoom(e.Delta); + } + } + + private void PedsForm_KeyDown(object sender, KeyEventArgs e) + { + if (ActiveControl is TextBox) + { + var tb = ActiveControl as TextBox; + if (!tb.ReadOnly) return; //don't move the camera when typing! + } + if (ActiveControl is ComboBox) + { + var cb = ActiveControl as ComboBox; + if (cb.DropDownStyle != ComboBoxStyle.DropDownList) return; //nontypable combobox + } + + bool enablemove = true;// (!iseditmode) || (MouseLButtonDown && (GrabbedMarker == null) && (GrabbedWidget == null)); + + Input.KeyDown(e, enablemove); + + var k = e.KeyCode; + var kb = Input.keyBindings; + bool ctrl = Input.CtrlPressed; + bool shift = Input.ShiftPressed; + + + if (!ctrl) + { + if (k == kb.MoveSlowerZoomIn) + { + camera.MouseZoom(1); + } + if (k == kb.MoveFasterZoomOut) + { + camera.MouseZoom(-1); + } + } + + + if (!Input.kbmoving) //don't trigger further actions if moving. + { + if (!ctrl) + { + + } + else + { + //switch (k) + //{ + // //case Keys.N: + // // New(); + // // break; + // //case Keys.O: + // // Open(); + // // break; + // //case Keys.S: + // // if (shift) SaveAll(); + // // else Save(); + // // break; + // //case Keys.Z: + // // Undo(); + // // break; + // //case Keys.Y: + // // Redo(); + // // break; + // //case Keys.C: + // // CopyItem(); + // // break; + // //case Keys.V: + // // PasteItem(); + // // break; + // //case Keys.U: + // // ToolsPanelShowButton.Visible = !ToolsPanelShowButton.Visible; + // // break; + //} + } + } + + //if (ControlMode != WorldControlMode.Free || ControlBrushEnabled) + //{ + // e.Handled = true; + //} + } + + private void PedsForm_KeyUp(object sender, KeyEventArgs e) + { + Input.KeyUp(e); + + if (ActiveControl is TextBox) + { + var tb = ActiveControl as TextBox; + if (!tb.ReadOnly) return; //don't move the camera when typing! + } + if (ActiveControl is ComboBox) + { + var cb = ActiveControl as ComboBox; + if (cb.DropDownStyle != ComboBoxStyle.DropDownList) return; //non-typable combobox + } + + //if (ControlMode != WorldControlMode.Free) + //{ + // e.Handled = true; + //} + } + + private void PedsForm_Deactivate(object sender, EventArgs e) + { + //try not to lock keyboard movement if the form loses focus. + Input.KeyboardStop(); + } + + private void StatsUpdateTimer_Tick(object sender, EventArgs e) + { + StatsLabel.Text = Renderer.GetStatusText(); + + if (Renderer.timerunning) + { + float fv = Renderer.timeofday * 60.0f; + //TimeOfDayTrackBar.Value = (int)fv; + UpdateTimeOfDayLabel(); + } + + //CameraPositionTextBox.Text = FloatUtil.GetVector3String(camera.Position, "0.##"); + } + + private void ToolsPanelShowButton_Click(object sender, EventArgs e) + { + ToolsPanel.Visible = true; + } + + private void ToolsPanelHideButton_Click(object sender, EventArgs e) + { + ToolsPanel.Visible = false; + } + + private void ToolsDragPanel_MouseDown(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + toolsPanelResizing = true; + toolsPanelResizeStartX = e.X + ToolsPanel.Left + ToolsDragPanel.Left; + toolsPanelResizeStartLeft = ToolsPanel.Left; + toolsPanelResizeStartRight = ToolsPanel.Right; + } + } + + private void ToolsDragPanel_MouseUp(object sender, MouseEventArgs e) + { + toolsPanelResizing = false; + } + + private void ToolsDragPanel_MouseMove(object sender, MouseEventArgs e) + { + if (toolsPanelResizing) + { + int rx = e.X + ToolsPanel.Left + ToolsDragPanel.Left; + int dx = rx - toolsPanelResizeStartX; + ToolsPanel.Width = toolsPanelResizeStartRight - toolsPanelResizeStartLeft + dx; + } + } + + private void ModelsTreeView_AfterCheck(object sender, TreeViewEventArgs e) + { + if (e.Node != null) + { + UpdateSelectionDrawFlags(e.Node); + } + } + + private void ModelsTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) + { + if (e.Node != null) + { + e.Node.Checked = !e.Node.Checked; + //UpdateSelectionDrawFlags(e.Node); + } + } + + private void ModelsTreeView_KeyPress(object sender, KeyPressEventArgs e) + { + e.Handled = true; //stops annoying ding sound... + } + + private void HDRRenderingCheckBox_CheckedChanged(object sender, EventArgs e) + { + lock (Renderer.RenderSyncRoot) + { + Renderer.shaders.hdr = HDRRenderingCheckBox.Checked; + } + } + + private void ShadowsCheckBox_CheckedChanged(object sender, EventArgs e) + { + lock (Renderer.RenderSyncRoot) + { + Renderer.shaders.shadows = ShadowsCheckBox.Checked; + } + } + + private void SkydomeCheckBox_CheckedChanged(object sender, EventArgs e) + { + Renderer.renderskydome = SkydomeCheckBox.Checked; + //Renderer.controllightdir = !Renderer.renderskydome; + } + + private void ControlLightDirCheckBox_CheckedChanged(object sender, EventArgs e) + { + Renderer.controllightdir = ControlLightDirCheckBox.Checked; + } + + private void TimeOfDayTrackBar_Scroll(object sender, EventArgs e) + { + int v = TimeOfDayTrackBar.Value; + float fh = v / 60.0f; + UpdateTimeOfDayLabel(); + lock (Renderer.RenderSyncRoot) + { + Renderer.timeofday = fh; + timecycle.SetTime(Renderer.timeofday); + } + } + + private void ShowCollisionMeshesCheckBox_CheckedChanged(object sender, EventArgs e) + { + Renderer.rendercollisionmeshes = ShowCollisionMeshesCheckBox.Checked; + Renderer.rendercollisionmeshlayerdrawable = ShowCollisionMeshesCheckBox.Checked; + } + + private void WireframeCheckBox_CheckedChanged(object sender, EventArgs e) + { + Renderer.shaders.wireframe = WireframeCheckBox.Checked; + } + + private void AnisotropicFilteringCheckBox_CheckedChanged(object sender, EventArgs e) + { + Renderer.shaders.AnisotropicFiltering = AnisotropicFilteringCheckBox.Checked; + } + + private void HDTexturesCheckBox_CheckedChanged(object sender, EventArgs e) + { + Renderer.renderhdtextures = HDTexturesCheckBox.Checked; + } + + private void RenderModeComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + TextureSamplerComboBox.Enabled = false; + TextureCoordsComboBox.Enabled = false; + switch (RenderModeComboBox.Text) + { + default: + case "Default": + Renderer.shaders.RenderMode = WorldRenderMode.Default; + break; + case "Single texture": + Renderer.shaders.RenderMode = WorldRenderMode.SingleTexture; + TextureSamplerComboBox.Enabled = true; + TextureCoordsComboBox.Enabled = true; + break; + case "Vertex normals": + Renderer.shaders.RenderMode = WorldRenderMode.VertexNormals; + break; + case "Vertex tangents": + Renderer.shaders.RenderMode = WorldRenderMode.VertexTangents; + break; + case "Vertex colour 1": + Renderer.shaders.RenderMode = WorldRenderMode.VertexColour; + Renderer.shaders.RenderVertexColourIndex = 1; + break; + case "Vertex colour 2": + Renderer.shaders.RenderMode = WorldRenderMode.VertexColour; + Renderer.shaders.RenderVertexColourIndex = 2; + break; + case "Vertex colour 3": + Renderer.shaders.RenderMode = WorldRenderMode.VertexColour; + Renderer.shaders.RenderVertexColourIndex = 3; + break; + case "Texture coord 1": + Renderer.shaders.RenderMode = WorldRenderMode.TextureCoord; + Renderer.shaders.RenderTextureCoordIndex = 1; + break; + case "Texture coord 2": + Renderer.shaders.RenderMode = WorldRenderMode.TextureCoord; + Renderer.shaders.RenderTextureCoordIndex = 2; + break; + case "Texture coord 3": + Renderer.shaders.RenderMode = WorldRenderMode.TextureCoord; + Renderer.shaders.RenderTextureCoordIndex = 3; + break; + } + } + + private void TextureSamplerComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + if (TextureSamplerComboBox.SelectedItem is ShaderParamNames) + { + Renderer.shaders.RenderTextureSampler = (ShaderParamNames)TextureSamplerComboBox.SelectedItem; + } + } + + private void TextureCoordsComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + switch (TextureCoordsComboBox.Text) + { + default: + case "Texture coord 1": + Renderer.shaders.RenderTextureSamplerCoord = 1; + break; + case "Texture coord 2": + Renderer.shaders.RenderTextureSamplerCoord = 2; + break; + case "Texture coord 3": + Renderer.shaders.RenderTextureSamplerCoord = 3; + break; + } + } + + private void GridCheckBox_CheckedChanged(object sender, EventArgs e) + { + enableGrid = GridCheckBox.Checked; + } + + private void GridSizeComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + float newgs; + float.TryParse(GridSizeComboBox.Text, out newgs); + if (newgs != gridSize) + { + gridSize = newgs; + UpdateGridVerts(); + } + } + + private void GridCountComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + int newgc; + int.TryParse(GridCountComboBox.Text, out newgc); + if (newgc != gridCount) + { + gridCount = newgc; + UpdateGridVerts(); + } + } + + private void SkeletonsCheckBox_CheckedChanged(object sender, EventArgs e) + { + Renderer.renderskeletons = SkeletonsCheckBox.Checked; + } + + private void StatusBarCheckBox_CheckedChanged(object sender, EventArgs e) + { + StatusStrip.Visible = StatusBarCheckBox.Checked; + } + + private void ErrorConsoleCheckBox_CheckedChanged(object sender, EventArgs e) + { + ConsolePanel.Visible = ErrorConsoleCheckBox.Checked; + } + + private void TextureViewerButton_Click(object sender, EventArgs e) + { + //TextureDictionary td = null; + + //if ((Ydr != null) && (Ydr.Loaded)) + //{ + // td = Ydr.Drawable?.ShaderGroup?.TextureDictionary; + //} + //else if ((Yft != null) && (Yft.Loaded)) + //{ + // td = Yft.Fragment?.Drawable?.ShaderGroup?.TextureDictionary; + //} + + //if (td != null) + //{ + // YtdForm f = new YtdForm(); + // f.Show(); + // f.LoadTexDict(td, fileName); + // //f.LoadYtd(ytd); + //} + //else + //{ + // MessageBox.Show("Couldn't find embedded texture dict."); + //} + } + + + + + } +} diff --git a/Peds/PedsForm.resx b/Peds/PedsForm.resx new file mode 100644 index 0000000..36d72f5 --- /dev/null +++ b/Peds/PedsForm.resx @@ -0,0 +1,415 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 127, 17 + + + + + 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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= + + + \ No newline at end of file diff --git a/Program.cs b/Program.cs index 6bb6187..a064e7b 100644 --- a/Program.cs +++ b/Program.cs @@ -19,6 +19,7 @@ namespace CodeWalker bool explorermode = false; bool projectmode = false; bool vehiclesmode = false; + bool pedsmode = false; if ((args != null) && (args.Length > 0)) { foreach (string arg in args) @@ -40,6 +41,10 @@ namespace CodeWalker { vehiclesmode = true; } + if (argl == "peds") + { + pedsmode = true; + } } } @@ -73,6 +78,10 @@ namespace CodeWalker { Application.Run(new Vehicles.VehicleForm()); } + else if (pedsmode) + { + Application.Run(new Peds.PedsForm()); + } else { Application.Run(new WorldForm()); diff --git a/Project/Panels/GenerateLODLightsPanel.cs b/Project/Panels/GenerateLODLightsPanel.cs index ece3fb9..7e27c42 100644 --- a/Project/Panels/GenerateLODLightsPanel.cs +++ b/Project/Panels/GenerateLODLightsPanel.cs @@ -180,14 +180,14 @@ namespace CodeWalker.Project.Panels xform = modeltransforms[boneidx]; xform.Column4 = Vector4.UnitW; //xform = Matrix.Identity; - ushort[] pinds = skeleton.ParentIndices; - ushort parentind = ((pinds != null) && (boneidx < pinds.Length)) ? pinds[boneidx] : (ushort)65535; - while (parentind < pinds.Length) + short[] pinds = skeleton.ParentIndices; + short parentind = ((pinds != null) && (boneidx < pinds.Length)) ? pinds[boneidx] : (short)-1; + while ((parentind >= 0) && (parentind < pinds.Length)) { Matrix ptrans = (parentind < modeltransforms.Length) ? modeltransforms[parentind] : Matrix.Identity; ptrans.Column4 = Vector4.UnitW; xform = Matrix.Multiply(ptrans, xform); - parentind = ((pinds != null) && (parentind < pinds.Length)) ? pinds[parentind] : (ushort)65535; + parentind = ((pinds != null) && (parentind < pinds.Length)) ? pinds[parentind] : (short)-1; } } } diff --git a/Rendering/Renderable.cs b/Rendering/Renderable.cs index 1f9e3f3..e7e07eb 100644 --- a/Rendering/Renderable.cs +++ b/Rendering/Renderable.cs @@ -279,14 +279,14 @@ namespace CodeWalker.Rendering else if (!usepose) //when using the skeleton's matrices, they need to be transformed by parent { trans.Column4 = Vector4.UnitW; - ushort[] pinds = skeleton.ParentIndices; - ushort parentind = ((pinds != null) && (boneidx < pinds.Length)) ? pinds[boneidx] : (ushort)65535; - while (parentind < pinds.Length) + short[] pinds = skeleton.ParentIndices; + short parentind = ((pinds != null) && (boneidx < pinds.Length)) ? pinds[boneidx] : (short)-1; + while ((parentind >= 0) && (parentind < pinds.Length)) { Matrix ptrans = (parentind < modeltransforms.Length) ? modeltransforms[parentind] : Matrix.Identity; ptrans.Column4 = Vector4.UnitW; trans = Matrix.Multiply(ptrans, trans); - parentind = ((pinds != null) && (parentind < pinds.Length)) ? pinds[parentind] : (ushort)65535; + parentind = ((pinds != null) && (parentind < pinds.Length)) ? pinds[parentind] : (short)-1; } } diff --git a/Rendering/Renderer.cs b/Rendering/Renderer.cs index 3c8b4e1..30924c5 100644 --- a/Rendering/Renderer.cs +++ b/Rendering/Renderer.cs @@ -1136,7 +1136,7 @@ namespace CodeWalker.Rendering if (xforms != null)//how to use xforms? bind pose? { var xform = (i < xforms.Length) ? xforms[i] : Matrix.Identity; - var pxform = (pind < xforms.Length) ? xforms[pind] : Matrix.Identity; + var pxform = ((pind >= 0) && (pind < xforms.Length)) ? xforms[pind] : Matrix.Identity; } else {