mirror of
https://github.com/4sval/FModel.git
synced 2026-09-13 12:06:39 -05:00
preparation
This commit is contained in:
Submodule CUE4Parse updated: 46d45fbfbf...de9589bc3f
@@ -34,7 +34,7 @@ public class Camera
|
||||
public void ModifyZoom(float zoomAmount)
|
||||
{
|
||||
//We don't want to be able to zoom in too close or too far away so clamp to these values
|
||||
Zoom = Math.Clamp(Zoom - zoomAmount, 1.0f, 60f);
|
||||
Zoom = Math.Clamp(Zoom - zoomAmount, 1.0f, 89f);
|
||||
}
|
||||
|
||||
public void ModifyDirection(float xOffset, float yOffset)
|
||||
|
||||
@@ -46,7 +46,6 @@ public class Model : IDisposable
|
||||
public bool IsSavable;
|
||||
public bool DisplayVertexColors;
|
||||
public bool DisplayBones;
|
||||
public int SelectedMorph;
|
||||
public float MorphTime;
|
||||
|
||||
protected Model(UObject owner, string name, string type)
|
||||
@@ -149,10 +148,10 @@ public class Model : IDisposable
|
||||
_matrixVbo.Unbind();
|
||||
}
|
||||
|
||||
public void UpdateMorph()
|
||||
public void UpdateMorph(int index)
|
||||
{
|
||||
_morphVbo.Bind();
|
||||
_morphVbo.Update(Morphs[SelectedMorph].Vertices);
|
||||
_morphVbo.Update(Morphs[index].Vertices);
|
||||
_morphVbo.Unbind();
|
||||
}
|
||||
|
||||
@@ -188,7 +187,7 @@ public class Model : IDisposable
|
||||
for (uint morph = 0; morph < Morphs.Length; morph++)
|
||||
{
|
||||
Morphs[morph].Setup(gl);
|
||||
if (morph == SelectedMorph)
|
||||
if (morph == 0)
|
||||
_morphVbo = new BufferObject<float>(_gl, Morphs[morph].Vertices, BufferTargetARB.ArrayBuffer);
|
||||
}
|
||||
_vao.Bind();
|
||||
|
||||
52
FModel/Views/Snooper/Options.cs
Normal file
52
FModel/Views/Snooper/Options.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using CUE4Parse.UE4.Objects.Core.Misc;
|
||||
|
||||
namespace FModel.Views.Snooper;
|
||||
|
||||
public class Options
|
||||
{
|
||||
public FGuid SelectedModel { get; private set; }
|
||||
public int SelectedModelInstance;
|
||||
|
||||
public int SelectedSection { get; private set; }
|
||||
public int SelectedMorph { get; private set; }
|
||||
|
||||
public Options()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
SelectedModel = Guid.Empty;
|
||||
SelectedModelInstance = 0;
|
||||
SelectedSection = 0;
|
||||
SelectedMorph = 0;
|
||||
}
|
||||
|
||||
public void SelectModel(FGuid guid)
|
||||
{
|
||||
SelectedModel = guid;
|
||||
SelectedModelInstance = 0;
|
||||
SelectedSection = 0;
|
||||
SelectedMorph = 0;
|
||||
}
|
||||
|
||||
public void SelectSection(int index)
|
||||
{
|
||||
SelectedSection = index;
|
||||
}
|
||||
|
||||
public void SelectMorph(int index, Model model)
|
||||
{
|
||||
SelectedMorph = index;
|
||||
model.UpdateMorph(SelectedMorph);
|
||||
}
|
||||
|
||||
public bool TryGetSection(Model model, out Section section)
|
||||
{
|
||||
if (SelectedSection >= 0 && SelectedSection < model.Sections.Length)
|
||||
section = model.Sections[SelectedSection]; else section = null;
|
||||
return section != null;
|
||||
}
|
||||
}
|
||||
@@ -32,9 +32,6 @@ public class SnimGui : IDisposable
|
||||
private readonly Vector2 _textureSize;
|
||||
private readonly Vector2 _texturePosition;
|
||||
private bool _viewportFocus;
|
||||
private FGuid _selectedModel;
|
||||
private int _selectedInstance;
|
||||
private int _selectedSection;
|
||||
|
||||
private const ImGuiWindowFlags _noResize = ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove; // delete once we have a proper docking branch
|
||||
private const ImGuiCond _firstUse = ImGuiCond.Appearing; // switch to FirstUseEver once the docking branch will not be useful anymore...
|
||||
@@ -59,23 +56,18 @@ public class SnimGui : IDisposable
|
||||
_viewportPosition = new Vector2(0, titleBarHeight);
|
||||
_textureSize = _viewportSize with { Y = viewport.WorkSize.Y - _viewportSize.Y - titleBarHeight };
|
||||
_texturePosition = new Vector2(0, _viewportPosition.Y + _viewportSize.Y);
|
||||
_selectedModel = new FGuid();
|
||||
_selectedInstance = 0;
|
||||
_selectedSection = 0;
|
||||
|
||||
Theme(style);
|
||||
}
|
||||
|
||||
public void Increment(FGuid guid) => _selectedModel = guid;
|
||||
|
||||
public void Construct(Vector2D<int> size, FramebufferObject framebuffer, Camera camera, IMouse mouse, IDictionary<FGuid, Model> models)
|
||||
public void Construct(ref Options options, Vector2D<int> size, FramebufferObject framebuffer, Camera camera, IMouse mouse, IDictionary<FGuid, Model> models)
|
||||
{
|
||||
DrawDockSpace(size);
|
||||
DrawNavbar();
|
||||
|
||||
DrawOuliner(camera, models);
|
||||
DrawProperties(camera, models);
|
||||
DrawTextures(models);
|
||||
DrawOuliner(ref options, camera, models);
|
||||
DrawProperties(ref options, camera, models);
|
||||
DrawTextures(ref options, models);
|
||||
Draw3DViewport(framebuffer, camera, mouse);
|
||||
}
|
||||
|
||||
@@ -126,7 +118,7 @@ public class SnimGui : IDisposable
|
||||
ImGui.EndMainMenuBar();
|
||||
}
|
||||
|
||||
private void DrawOuliner(Camera camera, IDictionary<FGuid, Model> models)
|
||||
private void DrawOuliner(ref Options options, Camera camera, IDictionary<FGuid, Model> models)
|
||||
{
|
||||
ImGui.SetNextWindowSize(_outlinerSize, _firstUse);
|
||||
ImGui.SetNextWindowPos(_outlinerPosition, _firstUse);
|
||||
@@ -144,20 +136,19 @@ public class SnimGui : IDisposable
|
||||
foreach (var (guid, model) in models)
|
||||
{
|
||||
ImGui.PushID(i);
|
||||
model.IsSelected = _selectedModel == guid;
|
||||
model.IsSelected = options.SelectedModel == guid;
|
||||
if (ImGui.Selectable(model.Name, model.IsSelected))
|
||||
{
|
||||
_selectedModel = guid;
|
||||
_selectedInstance = 0;
|
||||
_selectedSection = 0;
|
||||
options.SelectModel(guid);
|
||||
}
|
||||
if (ImGui.BeginPopupContextItem())
|
||||
{
|
||||
options.SelectModel(guid);
|
||||
if (ImGui.Selectable("Deselect"))
|
||||
_selectedModel = Guid.Empty;
|
||||
options.SelectModel(Guid.Empty);
|
||||
if (ImGui.Selectable("Delete"))
|
||||
models.Remove(guid);
|
||||
if (ImGui.Selectable("Copy to Clipboard"))
|
||||
if (ImGui.Selectable("Copy Name to Clipboard"))
|
||||
Application.Current.Dispatcher.Invoke(delegate
|
||||
{
|
||||
Clipboard.SetText(model.Name);
|
||||
@@ -187,19 +178,19 @@ public class SnimGui : IDisposable
|
||||
ImGui.End();
|
||||
}
|
||||
|
||||
private void DrawProperties(Camera camera, IDictionary<FGuid, Model> models)
|
||||
private void DrawProperties(ref Options options, Camera camera, IDictionary<FGuid, Model> models)
|
||||
{
|
||||
ImGui.SetNextWindowSize(_propertiesSize, _firstUse);
|
||||
ImGui.SetNextWindowPos(_propertiesPosition, _firstUse);
|
||||
ImGui.Begin("Properties", _noResize | ImGuiWindowFlags.NoCollapse);
|
||||
if (!models.TryGetValue(_selectedModel, out var model))
|
||||
if (!models.TryGetValue(options.SelectedModel, out var model))
|
||||
return;
|
||||
|
||||
ImGui.Text($"Entity: ({model.Type}) {model.Name}");
|
||||
ImGui.Text($"Guid: {_selectedModel.ToString(EGuidFormats.UniqueObjectGuid)}");
|
||||
ImGui.Text($"Guid: {options.SelectedModel.ToString(EGuidFormats.UniqueObjectGuid)}");
|
||||
PushStyleCompact();
|
||||
ImGui.Columns(4, "Actions", false);
|
||||
if (ImGui.Button("Go To")) camera.Position = model.Transforms[_selectedInstance].Position;
|
||||
if (ImGui.Button("Go To")) camera.Position = model.Transforms[options.SelectedModelInstance].Position;
|
||||
ImGui.NextColumn(); ImGui.Checkbox("Show", ref model.Show);
|
||||
ImGui.NextColumn(); ImGui.BeginDisabled(!model.HasVertexColors); ImGui.Checkbox("Colors", ref model.DisplayVertexColors); ImGui.EndDisabled();
|
||||
ImGui.NextColumn(); ImGui.BeginDisabled(!model.HasBones); ImGui.Checkbox("Bones", ref model.DisplayBones); ImGui.EndDisabled();
|
||||
@@ -219,7 +210,7 @@ public class SnimGui : IDisposable
|
||||
PushStyleCompact();
|
||||
ImGui.PushID(0); ImGui.BeginDisabled(model.TransformsCount < 2);
|
||||
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X);
|
||||
ImGui.SliderInt("", ref _selectedInstance, 0, model.TransformsCount - 1, "Instance %i", ImGuiSliderFlags.AlwaysClamp);
|
||||
ImGui.SliderInt("", ref options.SelectedModelInstance, 0, model.TransformsCount - 1, "Instance %i", ImGuiSliderFlags.AlwaysClamp);
|
||||
ImGui.EndDisabled(); ImGui.PopID();
|
||||
|
||||
ImGui.SetNextItemOpen(true, ImGuiCond.Appearing);
|
||||
@@ -227,13 +218,13 @@ public class SnimGui : IDisposable
|
||||
{
|
||||
ImGui.PushID(1);
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("X", ref model.Transforms[_selectedInstance].Position.X, speed, 0f, 0f, "%.2f m");
|
||||
ImGui.DragFloat("X", ref model.Transforms[options.SelectedModelInstance].Position.X, speed, 0f, 0f, "%.2f m");
|
||||
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("Y", ref model.Transforms[_selectedInstance].Position.Y, speed, 0f, 0f, "%.2f m");
|
||||
ImGui.DragFloat("Y", ref model.Transforms[options.SelectedModelInstance].Position.Y, speed, 0f, 0f, "%.2f m");
|
||||
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("Z", ref model.Transforms[_selectedInstance].Position.Z, speed, 0f, 0f, "%.2f m");
|
||||
ImGui.DragFloat("Z", ref model.Transforms[options.SelectedModelInstance].Position.Z, speed, 0f, 0f, "%.2f m");
|
||||
|
||||
ImGui.PopID();
|
||||
ImGui.TreePop();
|
||||
@@ -244,13 +235,13 @@ public class SnimGui : IDisposable
|
||||
{
|
||||
ImGui.PushID(2);
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("X", ref model.Transforms[_selectedInstance].Rotation.Pitch, .5f, 0f, 0f, "%.1f°");
|
||||
ImGui.DragFloat("X", ref model.Transforms[options.SelectedModelInstance].Rotation.Pitch, .5f, 0f, 0f, "%.1f°");
|
||||
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("Y", ref model.Transforms[_selectedInstance].Rotation.Roll, .5f, 0f, 0f, "%.1f°");
|
||||
ImGui.DragFloat("Y", ref model.Transforms[options.SelectedModelInstance].Rotation.Roll, .5f, 0f, 0f, "%.1f°");
|
||||
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("Z", ref model.Transforms[_selectedInstance].Rotation.Yaw, .5f, 0f, 0f, "%.1f°");
|
||||
ImGui.DragFloat("Z", ref model.Transforms[options.SelectedModelInstance].Rotation.Yaw, .5f, 0f, 0f, "%.1f°");
|
||||
|
||||
ImGui.PopID();
|
||||
ImGui.TreePop();
|
||||
@@ -261,19 +252,19 @@ public class SnimGui : IDisposable
|
||||
{
|
||||
ImGui.PushID(3);
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("X", ref model.Transforms[_selectedInstance].Scale.X, speed, 0f, 0f, "%.3f");
|
||||
ImGui.DragFloat("X", ref model.Transforms[options.SelectedModelInstance].Scale.X, speed, 0f, 0f, "%.3f");
|
||||
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("Y", ref model.Transforms[_selectedInstance].Scale.Y, speed, 0f, 0f, "%.3f");
|
||||
ImGui.DragFloat("Y", ref model.Transforms[options.SelectedModelInstance].Scale.Y, speed, 0f, 0f, "%.3f");
|
||||
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("Z", ref model.Transforms[_selectedInstance].Scale.Z, speed, 0f, 0f, "%.3f");
|
||||
ImGui.DragFloat("Z", ref model.Transforms[options.SelectedModelInstance].Scale.Z, speed, 0f, 0f, "%.3f");
|
||||
|
||||
ImGui.PopID();
|
||||
ImGui.TreePop();
|
||||
}
|
||||
|
||||
model.UpdateMatrix(_selectedInstance);
|
||||
model.UpdateMatrix(options.SelectedModelInstance);
|
||||
PopStyleCompact();
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
@@ -296,14 +287,20 @@ public class SnimGui : IDisposable
|
||||
ImGui.TableSetBgColor(ImGuiTableBgTarget.RowBg0, ImGui.GetColorU32(new Vector4(1, 0, 0, .5f)));
|
||||
ImGui.Text(section.Index.ToString("D"));
|
||||
ImGui.TableNextColumn();
|
||||
if (ImGui.Selectable(section.Name, _selectedSection == i, ImGuiSelectableFlags.SpanAllColumns))
|
||||
_selectedSection = i;
|
||||
if (ImGui.Selectable(section.Name, options.SelectedSection == i, ImGuiSelectableFlags.SpanAllColumns))
|
||||
options.SelectSection(i);
|
||||
if (ImGui.BeginPopupContextItem())
|
||||
{
|
||||
options.SelectSection(i);
|
||||
if (ImGui.Selectable("Swap"))
|
||||
{
|
||||
|
||||
}
|
||||
if (ImGui.Selectable("Copy Name to Clipboard"))
|
||||
Application.Current.Dispatcher.Invoke(delegate
|
||||
{
|
||||
Clipboard.SetText(section.Name);
|
||||
});
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
ImGui.PopID();
|
||||
@@ -321,11 +318,8 @@ public class SnimGui : IDisposable
|
||||
for (int i = 0; i < model.Morphs.Length; i++)
|
||||
{
|
||||
ImGui.PushID(i);
|
||||
if (ImGui.Selectable(model.Morphs[i].Name, model.SelectedMorph == i))
|
||||
{
|
||||
model.SelectedMorph = i;
|
||||
model.UpdateMorph();
|
||||
}
|
||||
if (ImGui.Selectable(model.Morphs[i].Name, options.SelectedMorph == i))
|
||||
options.SelectMorph(i, model);
|
||||
ImGui.PopID();
|
||||
}
|
||||
ImGui.EndListBox();
|
||||
@@ -340,15 +334,15 @@ public class SnimGui : IDisposable
|
||||
ImGui.End();
|
||||
}
|
||||
|
||||
private void DrawTextures(IDictionary<FGuid, Model> models)
|
||||
private void DrawTextures(ref Options options, IDictionary<FGuid, Model> models)
|
||||
{
|
||||
ImGui.SetNextWindowSize(_textureSize, _firstUse);
|
||||
ImGui.SetNextWindowPos(_texturePosition, _firstUse);
|
||||
ImGui.Begin("Textures", _noResize | ImGuiWindowFlags.NoCollapse);
|
||||
if (!models.TryGetValue(_selectedModel, out var model))
|
||||
if (!models.TryGetValue(options.SelectedModel, out var model) ||
|
||||
!options.TryGetSection(model, out var section))
|
||||
return;
|
||||
|
||||
var section = model.Sections[_selectedSection];
|
||||
PushStyleCompact(); ImGui.BeginGroup();
|
||||
ImGui.Checkbox("Show", ref section.Show);
|
||||
ImGui.Checkbox("Wireframe", ref section.Wireframe);
|
||||
@@ -405,7 +399,7 @@ public class SnimGui : IDisposable
|
||||
Application.Current.Dispatcher.Invoke(delegate
|
||||
{
|
||||
Clipboard.SetText(Utils.FixPath(texture.Path));
|
||||
texture.Label = "(?) Copied to Clipboard";
|
||||
texture.Label = "(?) Path Copied to Clipboard";
|
||||
});
|
||||
}
|
||||
|
||||
@@ -451,18 +445,16 @@ public class SnimGui : IDisposable
|
||||
var io = ImGui.GetIO();
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
camera.ModifyZoom(io.MouseWheel);
|
||||
|
||||
// if left button down while mouse is hover viewport
|
||||
if (ImGui.IsMouseDown(ImGuiMouseButton.Left) && !_viewportFocus)
|
||||
// if right button down while mouse is hover viewport
|
||||
if (ImGui.IsMouseDown(ImGuiMouseButton.Right) && !_viewportFocus)
|
||||
_viewportFocus = true;
|
||||
}
|
||||
|
||||
// this can't be inside IsItemHovered! read it as
|
||||
// if left mouse button was pressed while hovering the viewport
|
||||
// move camera until left mouse button is released
|
||||
// if right mouse button was pressed while hovering the viewport
|
||||
// move camera until right mouse button is released
|
||||
// no matter where mouse position end up
|
||||
if (ImGui.IsMouseDragging(ImGuiMouseButton.Left, lookSensitivity) && _viewportFocus)
|
||||
if (ImGui.IsMouseDragging(ImGuiMouseButton.Right, lookSensitivity) && _viewportFocus)
|
||||
{
|
||||
var delta = io.MouseDelta * lookSensitivity;
|
||||
camera.ModifyDirection(delta.X, delta.Y);
|
||||
@@ -470,7 +462,7 @@ public class SnimGui : IDisposable
|
||||
}
|
||||
|
||||
// if left button up and mouse was in viewport
|
||||
if (ImGui.IsMouseReleased(ImGuiMouseButton.Left) && _viewportFocus)
|
||||
if (ImGui.IsMouseReleased(ImGuiMouseButton.Right) && _viewportFocus)
|
||||
{
|
||||
_viewportFocus = false;
|
||||
mouse.Cursor.CursorMode = CursorMode.Normal;
|
||||
|
||||
@@ -35,6 +35,7 @@ public class Snooper
|
||||
private IKeyboard _keyboard;
|
||||
private IMouse _mouse;
|
||||
private RawImage _icon;
|
||||
private Options _options;
|
||||
|
||||
private readonly FramebufferObject _framebuffer;
|
||||
private readonly Skybox _skybox;
|
||||
@@ -87,6 +88,7 @@ public class Snooper
|
||||
_size = vector2D;
|
||||
};
|
||||
|
||||
_options = new Options();
|
||||
_framebuffer = new FramebufferObject(_size);
|
||||
_skybox = new Skybox();
|
||||
_grid = new Grid();
|
||||
@@ -104,6 +106,7 @@ public class Snooper
|
||||
{
|
||||
_models[guid] = new Model(export, st.Name, st.ExportType, mesh.LODs[0], mesh.LODs[0].Verts);
|
||||
SetupCamera(mesh.BoundingBox *= Constants.SCALE_DOWN_RATIO);
|
||||
_options.SelectModel(guid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -114,6 +117,7 @@ public class Snooper
|
||||
{
|
||||
_models[guid] = new Model(export, sk.Name, sk.ExportType, mesh.LODs[0], mesh.LODs[0].Verts, sk.MorphTargets, mesh.RefSkeleton);
|
||||
SetupCamera(mesh.BoundingBox *= Constants.SCALE_DOWN_RATIO);
|
||||
_options.SelectModel(guid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -328,7 +332,7 @@ public class Snooper
|
||||
model.Outline(_outline);
|
||||
}
|
||||
|
||||
_imGui.Construct(_size, _framebuffer, _camera, _mouse, _models);
|
||||
_imGui.Construct(ref _options, _size, _framebuffer, _camera, _mouse, _models);
|
||||
|
||||
_framebuffer.BindMsaa();
|
||||
_framebuffer.Bind(0); // switch back to main window
|
||||
@@ -361,6 +365,10 @@ public class Snooper
|
||||
_camera.Position += moveSpeed * _camera.Up;
|
||||
if (_keyboard.IsKeyPressed(Key.Q))
|
||||
_camera.Position -= moveSpeed * _camera.Up;
|
||||
if (_keyboard.IsKeyPressed(Key.X))
|
||||
_camera.ModifyZoom(-.5f);
|
||||
if (_keyboard.IsKeyPressed(Key.C))
|
||||
_camera.ModifyZoom(+.5f);
|
||||
|
||||
if (_keyboard.IsKeyPressed(Key.H))
|
||||
{
|
||||
@@ -390,6 +398,7 @@ public class Snooper
|
||||
if (!_append)
|
||||
{
|
||||
_models.Clear();
|
||||
_options.Reset();
|
||||
_previousSpeed = 0f;
|
||||
}
|
||||
_imGui.Dispose();
|
||||
|
||||
@@ -30,7 +30,7 @@ public class Texture : IDisposable
|
||||
_handle = _gl.GenTexture();
|
||||
_type = type;
|
||||
|
||||
Label = "(?) Click to Copy";
|
||||
Label = "(?) Click to Copy Path";
|
||||
}
|
||||
|
||||
public Texture(GL gl, uint width, uint height) : this(gl, TextureType.MsaaFramebuffer)
|
||||
|
||||
Reference in New Issue
Block a user