Basic ImGuizmo support.

master
Martin Felis 2021-10-09 11:21:53 +02:00
parent 41b7c14910
commit ea92663609
6 changed files with 283 additions and 23 deletions

View File

@ -67,6 +67,7 @@ target_include_directories(
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/3rdparty/rbdl/include>
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/glfw/deps>
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/imgui>
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/ImGuizmo>
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/vectorial/include>
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/tracy>
)
@ -82,6 +83,7 @@ target_sources(vissim PRIVATE
3rdparty/imgui/imgui_demo.cpp
3rdparty/imgui/backends/imgui_impl_glfw.cpp
3rdparty/imgui/backends/imgui_impl_opengl3.cpp
3rdparty/ImGuizmo/ImGuizmo.cpp
src/vissim.cc
src/sthstry.c
src/simulator.cc

View File

@ -10,6 +10,7 @@ typedef struct srcmdbuf srcmdbuf;
void simulator_init();
void simulator_reset();
void simulator_gui();
void simulator_update(double dt);
void simulator_step(double dt);
void simulator_draw(srcmdbuf* cmdbuf);

View File

@ -524,6 +524,7 @@ float sch_query_edge_directions (const sch_hull* hull_A, const sch_hull* hull_B,
axis = simd4f_sub(simd4f_zero(), axis);
}
// TODO: properly handle touching parallel edges.
if (simd4f_get_x(simd4f_length3_squared(axis)) < SCH_EPS) {
continue;
}

View File

@ -115,7 +115,7 @@ void simulator_reset() {
sSimTimeAccumulator = 0.;
}
void simulator_update(double dt) {
void simulator_gui() {
ZoneScoped;
ImGui::Begin("Simulator");
@ -186,6 +186,10 @@ void simulator_update(double dt) {
}
ImGui::End();
}
void simulator_update(double dt) {
ZoneScoped;
if (!sIsPaused) {
sSimTimeAccumulator += dt;

View File

@ -736,6 +736,8 @@ void srview_cleanup_framebuffer(srview* sv) {
void srview_set_size(srview* sv, int width, int height) {
if (sv->width == width && sv->height == height) {
return;
} else {
gLog("Resizing view to %d, %d", width, height);
}
sv->width = width;

View File

@ -4,20 +4,22 @@
// clang-format on
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#include <X11/Xlib.h>
#include <signal.h>
#include <csignal>
#include <unistd.h>
#include <Tracy.hpp>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include "backends/imgui_impl_glfw.h"
#include "backends/imgui_impl_opengl3.h"
#include "imgui.h"
#include "ImGuizmo.h"
#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
#endif
#include "imgui_internal.h"
#include "simulator.h"
#include "srender.h"
#include "utils.h"
@ -30,9 +32,38 @@ srndr* gRndr = nullptr;
srview* gView = nullptr;
srcmdbuf* gRndrCmds = nullptr;
simd4x4f gViewMatrix = {
simd4f_create(1.f, 0.f, 0.0, 0.f),
simd4f_create(0.f, 1.f, 0.f, 0.f),
simd4f_create(0.f, 0.f, 1.f, 0.f),
simd4f_create(0.f, 0.f, 0.f, 1.f)};
simd4x4f gProjMatrix{
simd4f_create(1.f, 0.f, 0.0, 0.f),
simd4f_create(0.f, 1.f, 0.f, 0.f),
simd4f_create(0.f, 0.f, 1.f, 0.f),
simd4f_create(0.f, 0.f, 0.f, 1.f)};
simd4x4f gTransformMatrix{
simd4f_create(1.0f, 0.f, 0.0, 0.f),
simd4f_create(0.f, 1.0f, 0.f, 0.f),
simd4f_create(0.f, 0.f, 1.0f, 0.f),
simd4f_create(0.f, 0.f, 0.f, 1.f)};
vectorial_inline simd4x4f simd4x4f_scale(simd4f s) {
return simd4x4f_create(
simd4f_create(simd4f_get_x(s), 0.f, 0.f, 0.f),
simd4f_create(0.f, simd4f_get_y(s), 0.f, 0.f),
simd4f_create(0.f, 0.f, simd4f_get_z(s), 0.f),
simd4f_create(0.f, 0.f, 0.f, simd4f_get_w(s)));
}
double mouse_scroll_x = 0.;
double mouse_scroll_y = 0.;
enum ViewMode { ViewModeSimulation = 0, ViewModeGuizmoTest = 1 };
ViewMode gViewMode = ViewModeSimulation;
bool gGizmoEnabled = true;
using namespace std;
static void error_callback(int error, const char* description) {
@ -146,30 +177,210 @@ void ShowDockspace(bool open) {
ImGui::End();
}
static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::TRANSLATE);
int gizmoCount = 1;
float camDistance = 8.f;
void RenderGuizmoTest(srcmdbuf* cmdbuf) {
srcmd rcmd;
srcmd_clear(&rcmd);
rcmd.type = SRndrCmdTypeGrid;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
simd4x4f_translation(&rcmd.mat, 0.0f, 0.0f, 0.0f);
srcmdbuf_add(cmdbuf, &rcmd);
}
}
rcmd.type = SRndrCmdTypeCube;
rcmd.mat = gTransformMatrix;
srcmdbuf_add(cmdbuf, &rcmd);
}
void ShowViewManip() {
const ImGuiStyle& imgui_style = ImGui::GetStyle();
ImGuizmo::SetDrawlist();
float windowWidth = (float)ImGui::GetWindowWidth();
float windowHeight = (float)ImGui::GetWindowHeight();
ImGuizmo::SetRect(
ImGui::GetWindowPos().x,
ImGui::GetWindowPos().y,
windowWidth,
windowHeight);
float viewManipulateRight = ImGui::GetWindowPos().x + windowWidth;
int title_height = ImGui::GetFontSize() + imgui_style.FramePadding.y * 2;
ImVec2 window_pos = ImGui::GetWindowPos();
ImVec2 view_manip_widget_size(128, 128);
ImVec2 view_manip_widget_pos(
viewManipulateRight - 128 - imgui_style.WindowPadding.x,
window_pos.y + title_height + imgui_style.WindowPadding.y);
ImGui::SetCursorPos(view_manip_widget_pos - ImGui::GetWindowPos());
ImGui::InvisibleButton("ViewManipulator", view_manip_widget_size);
ImGuizmo::ViewManipulate(
(float*)&(gViewMatrix.x),
10.0f,
view_manip_widget_pos,
view_manip_widget_size,
0x40404040);
}
void ShowTransformManip(
float* cameraView,
float* cameraProjection,
float* matrix) {
static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::LOCAL);
static bool useSnap = false;
static float snap[3] = {1.f, 1.f, 1.f};
static float bounds[] = {-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f};
static float boundsSnap[] = {0.1f, 0.1f, 0.1f};
static bool boundSizing = false;
static bool boundSizingSnap = false;
bool useWindow = false;
bool editTransformDecomposition = true;
ImVec2 window_size = ImGui::GetWindowSize();
ImVec2 window_pos = ImGui::GetWindowPos();
ImGuiStyle imgui_style = ImGui::GetStyle();
int title_height = ImGui::GetFontSize() + imgui_style.FramePadding.y * 2;
window_pos.x += imgui_style.WindowPadding.x;
window_pos.y += imgui_style.WindowPadding.y + title_height;
window_size.x -= imgui_style.WindowPadding.x * 2;
window_size.y -= imgui_style.WindowPadding.y * 2 + title_height;
ImGui::Begin("Guizmo");
if (editTransformDecomposition) {
if (ImGui::IsKeyPressed(90)) mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
if (ImGui::IsKeyPressed(69)) mCurrentGizmoOperation = ImGuizmo::ROTATE;
if (ImGui::IsKeyPressed(82)) // r Key
mCurrentGizmoOperation = ImGuizmo::SCALE;
if (ImGui::RadioButton(
"Translate",
mCurrentGizmoOperation == ImGuizmo::TRANSLATE))
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
ImGui::SameLine();
if (ImGui::RadioButton(
"Rotate",
mCurrentGizmoOperation == ImGuizmo::ROTATE))
mCurrentGizmoOperation = ImGuizmo::ROTATE;
ImGui::SameLine();
if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE))
mCurrentGizmoOperation = ImGuizmo::SCALE;
if (ImGui::RadioButton(
"Universal",
mCurrentGizmoOperation == ImGuizmo::UNIVERSAL))
mCurrentGizmoOperation = ImGuizmo::UNIVERSAL;
float matrixTranslation[3], matrixRotation[3], matrixScale[3];
ImGuizmo::DecomposeMatrixToComponents(
matrix,
matrixTranslation,
matrixRotation,
matrixScale);
ImGui::InputFloat3("Tr", matrixTranslation);
ImGui::InputFloat3("Rt", matrixRotation);
ImGui::InputFloat3("Sc", matrixScale);
ImGuizmo::RecomposeMatrixFromComponents(
matrixTranslation,
matrixRotation,
matrixScale,
matrix);
if (mCurrentGizmoOperation != ImGuizmo::SCALE) {
if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL))
mCurrentGizmoMode = ImGuizmo::LOCAL;
ImGui::SameLine();
if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD))
mCurrentGizmoMode = ImGuizmo::WORLD;
}
if (ImGui::IsKeyPressed(83)) useSnap = !useSnap;
ImGui::Checkbox("", &useSnap);
ImGui::SameLine();
switch (mCurrentGizmoOperation) {
case ImGuizmo::TRANSLATE:
ImGui::InputFloat3("Snap", &snap[0]);
break;
case ImGuizmo::ROTATE:
ImGui::InputFloat("Angle Snap", &snap[0]);
break;
case ImGuizmo::SCALE:
ImGui::InputFloat("Scale Snap", &snap[0]);
break;
}
ImGui::Checkbox("Bound Sizing", &boundSizing);
if (boundSizing) {
ImGui::PushID(3);
ImGui::Checkbox("", &boundSizingSnap);
ImGui::SameLine();
ImGui::InputFloat3("Snap", boundsSnap);
ImGui::PopID();
}
}
ImGui::End();
ImGuiIO& io = ImGui::GetIO();
float viewManipulateRight = io.DisplaySize.x;
float viewManipulateTop = 0;
if (useWindow) {
ImGui::SetNextWindowSize(ImVec2(800, 400));
ImGui::SetNextWindowPos(ImVec2(400, 20));
ImGui::PushStyleColor(
ImGuiCol_WindowBg,
(ImVec4)ImColor(0.35f, 0.3f, 0.3f));
ImGui::Begin("Gizmo", 0);
ImGuizmo::SetDrawlist();
float windowWidth = (float)ImGui::GetWindowWidth();
ImGuizmo::SetRect(window_pos.x, window_pos.y, window_size.x, window_size.y);
} else {
ImGuizmo::SetDrawlist();
ImGuizmo::SetRect(window_pos.x, window_pos.y, window_size.x, window_size.y);
}
simd4x4f identity_mat;
simd4x4f_identity(&identity_mat);
ImGuizmo::Manipulate(
cameraView,
cameraProjection,
mCurrentGizmoOperation,
mCurrentGizmoMode,
matrix,
NULL,
useSnap ? &snap[0] : NULL,
boundSizing ? bounds : NULL,
boundSizingSnap ? boundsSnap : NULL);
if (useWindow) {
ImGui::End();
ImGui::PopStyleColor(1);
}
}
void DoRender() {
ZoneScoped;
// Render Output
ImGui::Begin("Render Output");
const ImGuiStyle& imgui_style = ImGui::GetStyle();
// Update the view
// Render Output
ImGui::Begin("Render Output", nullptr, ImGuiWindowFlags_NoScrollbar);
// Update the gViewMatrix
const ImVec2 content_avail = ImGui::GetContentRegionAvail();
srview_set_size(gView, content_avail.x, content_avail.y);
simd4x4f view;
simd4x4f proj;
simd4x4f_translation(&view, 0.1f, 0.1f, -0.5f);
simd4f eye = simd4f_create(0.f, 3.f, 10.f, 1.f);
simd4x4f_lookat(
&view,
eye,
simd4f_create(0.f, 1.f, 0.f, 1.f),
simd4f_create(0.f, 1.f, 0.f, 1.f));
float view_width = content_avail.x / 50.f;
float view_height = content_avail.y / 50.f;
simd4x4f_ortho(
&proj,
&gProjMatrix,
-0.5f * view_width,
0.5f * view_width,
-0.5f * view_height,
@ -177,13 +388,13 @@ void DoRender() {
-50.0f,
50.0f);
simd4x4f_perspective(
&proj,
&gProjMatrix,
70.f * (M_PI / 180.f),
view_width / view_height,
0.1f,
50.f);
srview_set_view(gView, view);
srview_set_proj(gView, proj);
srview_set_view(gView, gViewMatrix);
srview_set_proj(gView, gProjMatrix);
// Populate render commands
srcmdbuf_clear(gRndrCmds);
@ -194,7 +405,12 @@ void DoRender() {
rcmd.type = SRndrCmdTypeFrame;
srcmdbuf_add(gRndrCmds, &rcmd);
simulator_draw(gRndrCmds);
if (gViewMode == ViewModeSimulation) {
simulator_draw(gRndrCmds);
simulator_gui();
} else {
RenderGuizmoTest(gRndrCmds);
}
// Perform the actual render
srndr_render(gRndr, gView, gRndrCmds);
@ -207,6 +423,22 @@ void DoRender() {
ImVec2(0.0f, 1.0f),
ImVec2(1.0f, 0.0f));
ImGuiIO& io = ImGui::GetIO();
ShowViewManip();
ShowTransformManip((float*)&(gViewMatrix),
(float*)&(gProjMatrix),
(float*)(&gTransformMatrix));
/*
EditTransform(
(float*)&(gViewMatrix),
(float*)&(gProjMatrix),
(float*)(&gTransformMatrix),
true,
window_pos,
window_size);
*/
ImGui::End();
}
@ -249,6 +481,10 @@ int main(void) {
std::cout << "GLSL Version : " << glGetString(GL_SHADING_LANGUAGE_VERSION)
<< endl;
glEnable(GL_DEBUG_OUTPUT);
// glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(opengl_error_callback, nullptr);
// During init, enable debug output
// glEnable ( GL_DEBUG_OUTPUT );
// glDebugMessageCallback( (GLDEBUGPROC) opengl_error_callback, 0 );
@ -290,6 +526,18 @@ int main(void) {
gRndrCmds = srcmdbuf_create(1024);
simulator_init();
simd4x4f_translation(&gViewMatrix, 0.1f, 0.1f, -0.5f);
simd4f eye = simd4f_create(0.f, 3.f, 10.f, 1.f);
simd4x4f_lookat(
&gViewMatrix,
eye,
simd4f_create(0.f, 0.f, 0.f, 1.f),
simd4f_create(0.f, 1.f, 0.f, 1.f));
simd4x4f scale_mat = simd4x4f_scale(simd4f_create(1.f, 1.f, 1.f, 1.f));
simd4x4f_mul(&gTransformMatrix, &scale_mat, &gTransformMatrix);
while (!glfwWindowShouldClose(gWindow)) {
FrameMark;
frame_counter++;
@ -307,6 +555,8 @@ int main(void) {
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGuizmo::BeginFrame();
ImGuizmo::Enable(gGizmoEnabled);
}
frame_time_last = frame_time_current;