protected override void BuildContents() { ImGui.SetWindowPos((Tae.ImGuiEventInspectorPos + new System.Numerics.Vector2(0, 12)) * Main.DPIVectorN); ImGui.SetWindowSize((Tae.ImGuiEventInspectorSize - new System.Numerics.Vector2(0, 12)) * Main.DPIVectorN); if (Tae.SingleEventBoxSelected) { ImGui.PushItemWidth(256 * Main.DPIX); var ev = Tae.SelectedEventBox; if (MenuBar.ClickItem(ev.MyEvent.TypeName ?? $"[Event Type {ev.MyEvent.Type}]", shortcut: "(Change)", shortcutColor: Color.Cyan)) { Tae.QueuedChangeEventType = true; } ImGui.Separator(); int ClampInt(int v, int min, int max) { v = Math.Max(v, min); v = Math.Min(v, max); return(v); } if (ev.MyEvent.TypeName != null) { CurrentUnmappedEventHex = ""; Dictionary <string, string> event0ParameterMap = null; if (ev.MyEvent.Type == 0) { event0ParameterMap = new Dictionary <string, string>(); } foreach (var p in ev.MyEvent.Parameters.Template) { string parameterName = $"{p.Value.Type} {p.Key}"; if (p.Value.ValueToAssert != null) { continue; } bool intSigned = p.Value.Type == TaeParamType.s8 || p.Value.Type == TaeParamType.s16 || p.Value.Type == TaeParamType.s32; bool intUnsigned = p.Value.Type == TaeParamType.u8 || p.Value.Type == TaeParamType.u16 || p.Value.Type == TaeParamType.u32; bool intHex = p.Value.Type == TaeParamType.x8 || p.Value.Type == TaeParamType.x16 || p.Value.Type == TaeParamType.x32; if (intSigned || intUnsigned || intHex) { int currentVal = Convert.ToInt32(ev.MyEvent.Parameters[p.Key]); int prevVal = currentVal; if (p.Value.EnumEntries != null && p.Value.EnumEntries.Count > 0) { string[] items = p.Value.EnumEntries.Keys.ToArray(); string[] dispItems = new string[items.Length]; int currentItemIndex = -1; for (int i = 0; i < items.Length; i++) { if (Convert.ToInt32(p.Value.EnumEntries[items[i]]) == currentVal) { currentItemIndex = i; } if (ev.MyEvent.Type == 0 && items[i].Contains("|")) { var allArgsSplit = items[i].Split('|').Select(x => x.Trim()).ToList(); dispItems[i] = allArgsSplit[0]; for (int j = 1; j < allArgsSplit.Count; j++) { var argSplit = allArgsSplit[j].Split(':').Select(x => x.Trim()).ToList(); var argParameter = argSplit[0]; var argName = argSplit[1]; if (i == currentItemIndex && !event0ParameterMap.ContainsKey(argParameter)) { event0ParameterMap.Add(argParameter, argName); } } } else { dispItems[i] = items[i]; } } ImGui.Combo(parameterName, ref currentItemIndex, dispItems, items.Length); if (currentItemIndex >= 0 && currentItemIndex < items.Length) { currentVal = Convert.ToInt32(p.Value.EnumEntries[items[currentItemIndex]]); } else { currentVal = 0; } } else { string dispName = parameterName; bool grayedOut = false; if (ev.MyEvent.Type == 0) { if (event0ParameterMap.ContainsKey(p.Key)) { dispName = event0ParameterMap[p.Key]; } else { grayedOut = true; } } if (grayedOut) { Tools.PushGrayedOut(); } ImGui.InputInt(dispName, ref currentVal, 1, 5, intHex ? (ImGuiInputTextFlags.CharsHexadecimal | ImGuiInputTextFlags.CharsUppercase) : ImGuiInputTextFlags.None); if (grayedOut) { Tools.PopGrayedOut(); } } if (currentVal < 0 && intUnsigned) { currentVal = 0; } if (p.Value.Type == TaeParamType.u8) { ev.MyEvent.Parameters[p.Key] = (byte)ClampInt(currentVal, byte.MinValue, byte.MaxValue); } else if (p.Value.Type == TaeParamType.s8) { ev.MyEvent.Parameters[p.Key] = (sbyte)ClampInt(currentVal, sbyte.MinValue, sbyte.MaxValue); } else if (p.Value.Type == TaeParamType.s16) { ev.MyEvent.Parameters[p.Key] = (short)ClampInt(currentVal, short.MinValue, short.MaxValue); } else if (p.Value.Type == TaeParamType.u16) { ev.MyEvent.Parameters[p.Key] = (ushort)ClampInt(currentVal, ushort.MinValue, ushort.MaxValue); } else if (p.Value.Type == TaeParamType.s32) { ev.MyEvent.Parameters[p.Key] = (int)ClampInt(currentVal, int.MinValue, int.MaxValue); } else if (p.Value.Type == TaeParamType.u32) { ev.MyEvent.Parameters[p.Key] = (uint)ClampInt(currentVal, (int)uint.MinValue, int.MaxValue); } if (currentVal != prevVal) { Tae.SelectedTaeAnim?.SetIsModified(true); } } else if (p.Value.Type == TaeParamType.f32) { string dispName = parameterName; bool grayedOut = false; if (ev.MyEvent.Type == 0) { if (event0ParameterMap.ContainsKey(p.Key)) { dispName = event0ParameterMap[p.Key]; } else { grayedOut = true; } } float current = Convert.ToSingle(ev.MyEvent.Parameters[p.Key]); float prevValue = current; if (grayedOut) { Tools.PushGrayedOut(); } ImGui.InputFloat(dispName, ref current); if (grayedOut) { Tools.PopGrayedOut(); } ev.MyEvent.Parameters[p.Key] = current; if (current != prevValue) { Tae.SelectedTaeAnim?.SetIsModified(true); } } else if (p.Value.Type == TaeParamType.b) { bool current = Convert.ToBoolean(ev.MyEvent.Parameters[p.Key]); bool prevValue = current; ImGui.Checkbox(parameterName, ref current); ev.MyEvent.Parameters[p.Key] = current; if (current != prevValue) { Tae.SelectedTaeAnim?.SetIsModified(true); } } else if (p.Value.Type == TaeParamType.aob) { byte[] buf = (byte[])(ev.MyEvent.Parameters[p.Key]); byte[] newBuf = new byte[buf.Length]; string current = string.Join("", buf.Select(bb => bb.ToString("X2"))); ImGui.InputText($"{parameterName}[{p.Value.AobLength}]", ref current, (uint)((p.Value.AobLength * 2) - 0), ImGuiInputTextFlags.CharsHexadecimal | ImGuiInputTextFlags.CharsUppercase); //current = current.Replace(" ", ""); if (current.Length < p.Value.AobLength * 2) { current += new string('0', (p.Value.AobLength * 2) - current.Length); } bool wasModified = false; for (int i = 0; i < buf.Length; i++) { newBuf[i] = byte.Parse(current.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber); if (newBuf[i] != buf[i]) { wasModified = true; } } ev.MyEvent.Parameters[p.Key] = newBuf; if (wasModified) { Tae.SelectedTaeAnim?.SetIsModified(true); } } } } else { CurrentUnmappedEventHex = ""; // temp idk when i'm gonna bother ImGui.Button("Copy to clipboard"); if (ImGui.IsItemClicked()) { System.Windows.Forms.Clipboard.SetText(string.Join(" ", ev.MyEvent.GetParameterBytes(GameDataManager.IsBigEndianGame).Select(xx => xx.ToString("X2")))); } } if (Tae?.Graph?.IsSimpleRemoGroupMode == true) { ImGui.Separator(); ImGui.LabelText("", "CUTSCENE DATA"); int groupTypeIndex = listBox_EventGroupDataTypes.IndexOf(ev.MyEvent.Group.GroupData.DataType); ImGui.ListBox("Cutscene Event Context", ref groupTypeIndex, listBox_EventGroupDataTypeNames, listBox_EventGroupDataTypeNames.Length); ev.MyEvent.Group.GroupData.DataType = groupTypeIndex < 0 ? SoulsAssetPipeline.Animation.TAE.EventGroup.EventGroupDataType.GroupData0 : listBox_EventGroupDataTypes[groupTypeIndex]; ev.MyEvent.Group.GroupType = (int)ev.MyEvent.Group.GroupData.DataType; if (ev.MyEvent.Group.GroupData.DataType == SoulsAssetPipeline.Animation.TAE.EventGroup.EventGroupDataType.ApplyToSpecificCutsceneEntity) { ImGui.Separator(); ImGui.LabelText("", "CUTSCENE ENTITY SELECTION"); int entityTypeIndex = listBox_EntityTypes.IndexOf(ev.MyEvent.Group.GroupData.CutsceneEntityType); ImGui.ListBox("Entity Type", ref entityTypeIndex, listBox_EntityTypeNames, listBox_EntityTypeNames.Length); ev.MyEvent.Group.GroupData.CutsceneEntityType = entityTypeIndex < 0 ? SoulsAssetPipeline.Animation.TAE.EventGroup.EventGroupDataStruct.EntityTypes.Character : listBox_EntityTypes[entityTypeIndex]; int x = ev.MyEvent.Group.GroupData.CutsceneEntityIDPart1; ImGui.InputInt("Entity ID First Half (XXXX)", ref x); x = Math.Min(Math.Max(x, 0), 9999); ev.MyEvent.Group.GroupData.CutsceneEntityIDPart1 = (short)x; x = ev.MyEvent.Group.GroupData.CutsceneEntityIDPart2; ImGui.InputInt("Entity ID Second Half (YYYY)", ref x); x = Math.Min(Math.Max(x, 0), 9999); ev.MyEvent.Group.GroupData.CutsceneEntityIDPart2 = (short)x; x = ev.MyEvent.Group.GroupData.Area; ImGui.InputInt("Entity Area (-1: Default)", ref x); x = Math.Min(Math.Max(x, -1), 99); ev.MyEvent.Group.GroupData.Area = (sbyte)x; x = ev.MyEvent.Group.GroupData.Block; ImGui.InputInt("Entity Block (-1: Default)", ref x); x = Math.Min(Math.Max(x, -1), 99); ev.MyEvent.Group.GroupData.Block = (sbyte)x; } } ImGui.PopItemWidth(); } }
protected override void BuildContents() { var entityType = Tae.Graph?.ViewportInteractor?.EntityType; if (entityType == TaeViewportInteractor.TaeEntityType.NPC) { ImGui.Button("Load Additional Texture File(s)..."); if (ImGui.IsItemClicked()) { Tae.BrowseForMoreTextures(); } var mdl = Tae.Graph?.ViewportInteractor?.CurrentModel; if (mdl != null) { if (ImGui.TreeNode("NPC Param Selection")) { lock (mdl._lock_NpcParams) { foreach (var npc in mdl.PossibleNpcParams) { bool oldSelected = npc == mdl.NpcParam; var selected = MenuBar.CheckboxBig(npc.GetDisplayName(), oldSelected); ImGui.Indent(); ImGui.PushStyleColor(ImGuiCol.Text, new System.Numerics.Vector4(0, 1, 1, 1)); { ImGui.Text($"BehaviorVariationID: {npc.BehaviorVariationID}"); if (mdl.NpcMaterialNamesPerMask.Any(kvp => kvp.Key >= 0)) { ImGui.Text($"Meshes Visible:"); ImGui.Indent(); { foreach (var kvp in mdl.NpcMaterialNamesPerMask) { if (kvp.Key < 0) { continue; } if (mdl.NpcMasksEnabledOnAllNpcParams.Contains(kvp.Key)) { continue; } if (npc.DrawMask[kvp.Key]) { foreach (var v in kvp.Value) { ImGui.BulletText(v); } } } } ImGui.Unindent(); } } ImGui.PopStyleColor(); ImGui.Unindent(); if (selected != oldSelected) { mdl.NpcParam = npc; npc.ApplyToNpcModel(mdl); } } } ImGui.TreePop(); } } ImGui.Separator(); ImGui.Button("Open NPC Model Importer"); if (ImGui.IsItemClicked()) { Tae.BringUpImporter_FLVER2(); } } else if (entityType == TaeViewportInteractor.TaeEntityType.OBJ) { ImGui.Button("Load Additional Texture File(s)..."); if (ImGui.IsItemClicked()) { Tae.BrowseForMoreTextures(); } } else if (entityType == TaeViewportInteractor.TaeEntityType.PC) { OSD.WindowEditPlayerEquip.IsOpen = MenuBar.CheckboxBig("Show Player Equipment Editor Window", OSD.WindowEditPlayerEquip.IsOpen); if (Tae.Graph?.ViewportInteractor?.EventSim != null) { var currentHitViewSource = Tae.Config.HitViewDummyPolySource; int currentHitViewSourceIndex = BehaviorHitboxSrcEnum_Values.IndexOf(currentHitViewSource); ImGui.ListBox("Behavior / Hitbox Source", ref currentHitViewSourceIndex, BehaviorHitboxSrcEnum_Names, BehaviorHitboxSrcEnum_Names.Length); var newHitViewSource = currentHitViewSourceIndex >= 0 ? BehaviorHitboxSrcEnum_Values[currentHitViewSourceIndex] : ParamData.AtkParam.DummyPolySource.Body; if (currentHitViewSource != newHitViewSource) { lock (Tae.Graph._lock_EventBoxManagement) { Tae.Graph.ViewportInteractor.EventSim.OnNewAnimSelected(Tae.Graph.EventBoxes); Tae.Config.HitViewDummyPolySource = newHitViewSource; Tae.Graph.ViewportInteractor.EventSim.OnNewAnimSelected(Tae.Graph.EventBoxes); Tae.Graph.ViewportInteractor.OnScrubFrameChange(); } } } } else if (entityType == TaeViewportInteractor.TaeEntityType.REMO) { RemoManager.EnableRemoCameraInViewport = MenuBar.CheckboxBig("Show Cutscene Camera View", RemoManager.EnableRemoCameraInViewport); RemoManager.EnableDummyPrims = MenuBar.CheckboxBig("Enable Dummy Node Helpers", RemoManager.EnableDummyPrims); Main.Config.LockAspectRatioDuringRemo = MenuBar.CheckboxBig("Lock Aspect Ratio to 16:9", Main.Config.LockAspectRatioDuringRemo); ImGui.Button("Preview Full Cutscene With Streamed Audio"); if (ImGui.IsItemClicked()) { RemoManager.StartFullPreview(); } } else { ImGui.Text("No entity loaded."); } }
protected override void BuildInsideOfWindow() { if (TaeAnimID_Value != null) { TaeAnimID_Error = null; } if (ImportFromAnimID_Value != null) { ImportFromAnimID_Error = null; } bool isCurrentlyStandard = TaeAnimHeader.Type == TAE.Animation.MiniHeaderType.Standard; bool isCurrentlyImportOther = TaeAnimHeader.Type == TAE.Animation.MiniHeaderType.ImportOtherAnim; if (TaeAnimID_Value == null) { ImGui.PushStyleColor(ImGuiCol.Text, new System.Numerics.Vector4(1, 0, 0, 1)); } ImGui.InputText("Animation ID", ref TaeAnimID_String, 256); if (ImGui.IsItemHovered() && TaeAnimID_Error != null) { ImGui.SetTooltip(TaeAnimID_Error); } if (TaeAnimID_Value == null) { ImGui.PopStyleColor(); } if (string.IsNullOrWhiteSpace(TaeAnimID_String)) { TaeAnimID_Value = null; TaeAnimID_Error = "Animation entry ID must be specified."; } else if (long.TryParse(TaeAnimID_String.Replace("a", "").Replace("A", "").Replace("_", ""), out long animIdParsed)) { if (IsMultiTaeSubID && animIdParsed < 0) { TaeAnimID_Error = "Animation sub-ID cannot be a negative value."; TaeAnimID_Value = null; } else if (IsMultiTaeSubID && animIdParsed > (GameDataManager.GameTypeHasLongAnimIDs ? 999999 : 9999)) { TaeAnimID_Error = $"Animation sub-ID cannot be so high it overflows into the next category (over {(GameDataManager.GameTypeHasLongAnimIDs ? 999999 : 9999)} for {GameDataManager.GameTypeName})."; TaeAnimID_Value = null; } else { TaeAnimID_Value = animIdParsed; } } else { TaeAnimID_Value = null; if (IsMultiTaeSubID) { TaeAnimID_Error = "Not a valid integer."; } else { if (GameDataManager.CurrentAnimIDFormatType == GameDataManager.AnimIDFormattingType.aXXX_YYYYYY) { TaeAnimID_Error = "Invalid ID specified. Enter an ID in either 'aXXX_YYYYYY' format or 'XXXYYYYYY' format."; } else if (GameDataManager.CurrentAnimIDFormatType == GameDataManager.AnimIDFormattingType.aXX_YY_ZZZZ) { TaeAnimID_Error = "Invalid ID specified. Enter an ID in either 'aXX_YY_ZZZZ' format or 'XXYYZZZZ' format."; } else if (GameDataManager.CurrentAnimIDFormatType == GameDataManager.AnimIDFormattingType.aXX_YYYY) { TaeAnimID_Error = "Invalid ID specified. Enter an ID in either 'aXX_YYYY' format or 'XXYYYY' format."; } else { throw new NotImplementedException(); } } } ImGui.Separator(); ImGui.InputText("Animation Name", ref TaeAnimName, 256); ImGui.Separator(); ImGui.Text("Animation Type:"); ImGui.Indent(); { ImGui.MenuItem("Standard Animation", "", isCurrentlyStandard); bool clickedStandard = ImGui.IsItemClicked(); ImGui.MenuItem("Duplicate of Other Anim Entry", "", TaeAnimHeader.Type == TAE.Animation.MiniHeaderType.ImportOtherAnim); bool clickedImportOther = ImGui.IsItemClicked(); if (clickedStandard && !isCurrentlyStandard) { DialogManager.AskForMultiChoice("Change Animation Type", "Change animation type, losing the values you entered?", (cancelType, answer) => { if (cancelType != CancelTypes.None) { return; } if (answer == "YES") { TaeAnimHeader = new TAE.Animation.AnimMiniHeader.Standard(); } }, CancelTypes.Combo_ClickTitleBarX_PressEscape, "YES", "NO"); } else if (clickedImportOther && !isCurrentlyImportOther) { DialogManager.AskForMultiChoice("Change Animation Type", "Change animation type, losing the values you entered?", (cancelType, answer) => { if (cancelType != CancelTypes.None) { return; } if (answer == "YES") { TaeAnimHeader = new TAE.Animation.AnimMiniHeader.ImportOtherAnim(); } }, CancelTypes.Combo_ClickTitleBarX_PressEscape, "YES", "NO"); } } ImGui.Unindent(); if (TaeAnimHeader is TAE.Animation.AnimMiniHeader.ImportOtherAnim asImportOtherAnim) { ImGui.Text("Properties - Duplicate of Other Anim Entry:"); ImGui.Indent(); { if (ImportFromAnimID_Value == null) { ImGui.PushStyleColor(ImGuiCol.Text, new System.Numerics.Vector4(1, 0, 0, 1)); } ImGui.InputText("Duplicate of Animation ID", ref ImportFromAnimID_String, 256); if (ImGui.IsItemHovered() && ImportFromAnimID_Error != null) { ImGui.SetTooltip(ImportFromAnimID_Error); } if (ImportFromAnimID_Value == null) { ImGui.PopStyleColor(); } if (string.IsNullOrWhiteSpace(ImportFromAnimID_String)) { ImportFromAnimID_Value = asImportOtherAnim.ImportFromAnimID = -1; } else if (int.TryParse(ImportFromAnimID_String.Replace("a", "").Replace("A", "").Replace("_", ""), out int importFromIdParsed)) { ImportFromAnimID_Value = asImportOtherAnim.ImportFromAnimID = importFromIdParsed; } else { ImportFromAnimID_Value = null; if (GameDataManager.CurrentAnimIDFormatType == GameDataManager.AnimIDFormattingType.aXXX_YYYYYY) { ImportFromAnimID_Error = "Invalid ID specified. Leave the box blank to specify no animation or enter an ID in either 'aXXX_YYYYYY' format or 'XXXYYYYYY' format."; } else if (GameDataManager.CurrentAnimIDFormatType == GameDataManager.AnimIDFormattingType.aXX_YY_ZZZZ) { ImportFromAnimID_Error = "Invalid ID specified. Leave the box blank to specify no animation or enter an ID in either 'aXX_YY_ZZZZ' format or 'XXYYZZZZ' format."; } else if (GameDataManager.CurrentAnimIDFormatType == GameDataManager.AnimIDFormattingType.aXX_YYYY) { ImportFromAnimID_Error = "Invalid ID specified. Leave the box blank to specify no animation or enter an ID in either 'aXX_YYYY' format or 'XXYYYY' format."; } else { throw new NotImplementedException(); } } asImportOtherAnim.Unknown = MenuBar.IntItem("Unknown Value", asImportOtherAnim.Unknown); } ImGui.Unindent(); } else if (TaeAnimHeader is TAE.Animation.AnimMiniHeader.Standard asStandard) { ImGui.Text("Properties - Standard Animation:"); ImGui.Indent(); { asStandard.ImportsHKX = MenuBar.CheckboxBig("Import Other HKX", asStandard.ImportsHKX); if (ImportFromAnimID_Value == null) { ImGui.PushStyleColor(ImGuiCol.Text, new System.Numerics.Vector4(1, 0, 0, 1)); } ImGui.InputText("Import HKX ID", ref ImportFromAnimID_String, 256); if (ImGui.IsItemHovered() && ImportFromAnimID_Error != null) { ImGui.SetTooltip(ImportFromAnimID_Error); } if (ImportFromAnimID_Value == null) { ImGui.PopStyleColor(); } if (string.IsNullOrWhiteSpace(ImportFromAnimID_String)) { ImportFromAnimID_Value = asStandard.ImportHKXSourceAnimID = -1; } else if (int.TryParse(ImportFromAnimID_String.Replace("a", "").Replace("A", "").Replace("_", ""), out int importFromIdParsed)) { ImportFromAnimID_Value = asStandard.ImportHKXSourceAnimID = importFromIdParsed; } else { ImportFromAnimID_Value = null; if (GameDataManager.CurrentAnimIDFormatType == GameDataManager.AnimIDFormattingType.aXXX_YYYYYY) { ImportFromAnimID_Error = "Invalid ID specified. Leave the box blank to specify no animation or enter an ID in either 'aXXX_YYYYYY' format or 'XXXYYYYYY' format."; } else if (GameDataManager.CurrentAnimIDFormatType == GameDataManager.AnimIDFormattingType.aXX_YY_ZZZZ) { ImportFromAnimID_Error = "Invalid ID specified. Leave the box blank to specify no animation or enter an ID in either 'aXX_YY_ZZZZ' format or 'XXYYZZZZ' format."; } else if (GameDataManager.CurrentAnimIDFormatType == GameDataManager.AnimIDFormattingType.aXX_YYYY) { ImportFromAnimID_Error = "Invalid ID specified. Leave the box blank to specify no animation or enter an ID in either 'aXX_YYYY' format or 'XXYYYY' format."; } else { throw new NotImplementedException(); } } asStandard.AllowDelayLoad = MenuBar.CheckboxBig("Allow loading from DelayLoad ANIBNDs", asStandard.AllowDelayLoad); asStandard.IsLoopByDefault = MenuBar.CheckboxBig("Enable Looping", asStandard.IsLoopByDefault); } ImGui.Unindent(); } ImGui.Separator(); ImGui.Button("Delete This Animation..."); if (ImGui.IsItemClicked()) { DialogManager.AskForMultiChoice("Permanently Delete Animation Entry?", $"Are you sure you want to delete the current animation?\nThis can NOT be undone!", (cancelType, answer) => { if (answer == "YES") { WasAnimDeleted = true; CancelType = CancelTypes.ClickedAcceptButton; Dismiss(); DialogManager.DialogOK("Success", "Animation deleted successfully."); } }, CancelTypes.Combo_ClickTitleBarX_PressEscape, "YES", "NO"); } ImGui.Separator(); ImGui.Button("Cancel & Discard Changes"); if (ImGui.IsItemClicked()) { CancelType = CancelTypes.ClickTitleBarX; Dismiss(); } bool invalidState = (ImportFromAnimID_Value == null || TaeAnimID_Value == null); if (invalidState) { Tools.PushGrayedOut(); } ImGui.Button("Apply & Save Changes"); if (invalidState) { Tools.PopGrayedOut(); if (ImGui.IsItemHovered()) { ImGui.SetTooltip("Cannot accept changes until the animation ID formatting errors (shown in red) are fixed."); } } if (ImGui.IsItemClicked()) { if (!invalidState) { CancelType = CancelTypes.ClickedAcceptButton; Dismiss(); } } //throw new NotImplementedException(); }
protected override void BuildContents() { lock (Scene._lock_ModelLoad_Draw) { void DoMesh(Model mdl, NewMesh mesh, string meshName) { if (mesh == null) { return; } if (meshName != null) { if (!ImGui.TreeNode(meshName)) { return; } } foreach (var sm in mesh.Submeshes) { bool isMeshGrayedOut = sm.ModelMaskIndex >= 0 && sm.ModelMaskIndex < mesh.DrawMask.Length && !mesh.DrawMask[sm.ModelMaskIndex]; ImGui.PushStyleColor(ImGuiCol.Text, !isMeshGrayedOut ? new System.Numerics.Vector4(1, 1, 1, 1) : new System.Numerics.Vector4(0.75f, 0.25f, 0.25f, 1)); ImGui.PushStyleColor(ImGuiCol.TextDisabled, isMeshGrayedOut ? new System.Numerics.Vector4(1, 0, 0, 1) : new System.Numerics.Vector4(0, 1, 0, 1)); sm.IsVisible = MenuBar.Checkbox(sm.FullMaterialName, sm.IsVisible, enabled: true, shortcut: (sm.ModelMaskIndex >= 0 ? $"[Mask {(sm.ModelMaskIndex)}]" : null)); ImGui.PopStyleColor(2); } if (meshName != null) { ImGui.TreePop(); } } if (ImGui.TreeNode("Models")) { GFX.HideFLVERs = !MenuBar.Checkbox("Render Models", !GFX.HideFLVERs); ImGui.Separator(); foreach (var mdl in Scene.Models) { if (ImGui.TreeNode(mdl.Name)) { var maskDict = mdl.GetMaterialNamesPerMask(); foreach (var kvp in maskDict) { if (kvp.Key >= 0) { mdl.DefaultDrawMask[kvp.Key] = MenuBar.Checkbox($"Mask {kvp.Key}", mdl.DefaultDrawMask[kvp.Key]); } } ImGui.Separator(); DoMesh(mdl, mdl.MainMesh, null); if (mdl.ChrAsm != null) { ImGui.Separator(); DoMesh(mdl, mdl.ChrAsm.HeadMesh, "Head"); DoMesh(mdl, mdl.ChrAsm.BodyMesh, "Body"); DoMesh(mdl, mdl.ChrAsm.ArmsMesh, "Arms"); DoMesh(mdl, mdl.ChrAsm.LegsMesh, "Legs"); DoMesh(mdl, mdl.ChrAsm.FaceMesh, "Naked Body"); DoMesh(mdl, mdl.ChrAsm.FacegenMesh, "Face"); } ImGui.TreePop(); } } ImGui.TreePop(); } if (ImGui.TreeNode("Helpers")) { lock (DBG._lock_DebugDrawEnablers) { DBG.CategoryEnableDraw[DebugPrimitives.DbgPrimCategory.FlverBone] = MenuBar.Checkbox("Bone Lines", DBG.CategoryEnableDraw[DebugPrimitives.DbgPrimCategory.FlverBone], enabled: true, shortcut: "(This Color)", shortcutColor: Main.Colors.ColorHelperFlverBone); DBG.CategoryEnableNameDraw[DebugPrimitives.DbgPrimCategory.FlverBone] = MenuBar.Checkbox("Bone Names", DBG.CategoryEnableNameDraw[DebugPrimitives.DbgPrimCategory.FlverBone], enabled: true, shortcut: "(This Color)", shortcutColor: Main.Colors.ColorHelperFlverBone); DBG.CategoryEnableDraw[DebugPrimitives.DbgPrimCategory.FlverBoneBoundingBox] = MenuBar.Checkbox("Bone Boxes", DBG.CategoryEnableDraw[DebugPrimitives.DbgPrimCategory.FlverBoneBoundingBox], enabled: true, shortcut: "(This Color)", shortcutColor: Main.Colors.ColorHelperFlverBoneBoundingBox); DBG.CategoryEnableDraw[DebugPrimitives.DbgPrimCategory.DummyPoly] = MenuBar.Checkbox("DummyPoly", DBG.CategoryEnableDraw[DebugPrimitives.DbgPrimCategory.DummyPoly], enabled: true, shortcut: "(This Color)", shortcutColor: Main.Colors.ColorHelperDummyPoly); DBG.CategoryEnableNameDraw[DebugPrimitives.DbgPrimCategory.DummyPoly] = MenuBar.Checkbox("DummyPoly IDs", DBG.CategoryEnableNameDraw[DebugPrimitives.DbgPrimCategory.DummyPoly], enabled: true, shortcut: "(This Color)", shortcutColor: Main.Colors.ColorHelperDummyPoly); NewDummyPolyManager.ShowGlobalIDOffset = MenuBar.Checkbox("Show c0000 Weapon Global \nDummyPoly ID Values (10000+)", NewDummyPolyManager.ShowGlobalIDOffset); DBG.CategoryEnableDraw[DebugPrimitives.DbgPrimCategory.SoundEvent] = MenuBar.Checkbox("FMOD Sound Events", DBG.CategoryEnableDraw[DebugPrimitives.DbgPrimCategory.SoundEvent], enabled: true, shortcut: "(This Color)", shortcutColor: Main.Colors.ColorHelperSoundEvent); RemoManager.EnableDummyPrims = MenuBar.Checkbox("Cutscene Dummies", RemoManager.EnableDummyPrims, enabled: true, shortcut: "(This Color)", shortcutColor: Microsoft.Xna.Framework.Color.Lime); } ImGui.Separator(); Tae.Config.DbgPrimXRay = MenuBar.Checkbox("Helper X-Ray Mode", Tae.Config.DbgPrimXRay); ImGui.TreePop(); } } }