diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fd318f..9e8b079 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,6 +87,7 @@ target_sources(vissim PRIVATE src/vissim.cc src/sthstry.c src/simulator.cc + src/render_utils.c ) # Tests diff --git a/src/render_utils.c b/src/render_utils.c new file mode 100644 index 0000000..55dcf97 --- /dev/null +++ b/src/render_utils.c @@ -0,0 +1,77 @@ +#include "render_utils.h" +#include "utils.h" + +inline void CameraState_Init(CameraState* camera_state) { + // clang-format off + static float mtx_identity[16] = { + 1.f, 0.f, 0.f, 0.f, + 0.f, 1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 1.f + }; + // clang-format on + + memcpy(&camera_state->mtxView, &mtx_identity, sizeof(camera_state->mtxView)); +} + +void CameraState_CalcFromMatrix(CameraState* camera_state, simd4x4f* mtx) { + camera_state->pos[0] = mtx->w[0]; + camera_state->pos[1] = mtx->w[1]; + camera_state->pos[2] = mtx->w[2]; + + float right[3] = {mtx->x[0], mtx->y[0], mtx->z[0]}; + float up[3] = {mtx->x[1], mtx->y[1], mtx->z[1]}; + float forward[3] = {-mtx->x[2], -mtx->y[2], -mtx->z[2]}; + + camera_state->heading = atan2(forward[2], -forward[0]); + camera_state->pitch = asin(-forward[1]); + + gLog("eye: %f %f %f", camera_state->pos[0], camera_state->pos[1], camera_state->pos[2]); +} + +void CameraState_CalcToMatrix(CameraState* camera_state, simd4x4f* mtx) { + float sp = sin(camera_state->pitch); + float cp = cos(camera_state->pitch); + float ch = cos(camera_state->heading); + float sh = sin(camera_state->heading); + + const float d = 10.0f; + + simd4f eye = simd4f_create (camera_state->pos[0], camera_state->pos[1], camera_state->pos[2], 1.f); + simd4f forward = simd4f_create (-cp * ch * d, -sp * d, cp * sh * d, 1.f); + simd4f right = simd4f_cross3 (forward, simd4f_create (0.f, 1.f, 0.f, 1.f)); + simd4f up = simd4f_cross3(right, forward); + simd4f center = simd4f_add(eye, forward); + + simd4x4f_lookat(mtx, eye, center, up); +} + +inline void CameraState_Update( + CameraState* camera_state, + float dt, + float mouse_dx, + float mouse_dy, + float accel[3]) { + CameraState_CalcFromMatrix(camera_state, &camera_state->mtxView); + + camera_state->heading += dt * mouse_dx * M_PI / 180.f; + if (camera_state->heading < -M_PI) { + camera_state->heading += M_PI; + } else if (camera_state->heading > M_PI) { + camera_state->heading -= M_PI; + } + camera_state->heading = dt * mouse_dy * M_PI / 180.f; + if (camera_state->heading < -M_PI * 0.49) { + camera_state->heading = -M_PI * 0.49; + } else if (camera_state->heading > M_PI * 0.49) { + camera_state->heading = M_PI * 0.49; + } + + for (int i = 0; i < 3; i++) { + camera_state->vel[i] += dt * accel[i]; + camera_state->pos[i] += dt * camera_state->vel[i]; + camera_state->vel[i] = camera_state->vel[i] * 0.5; + } + + CameraState_CalcToMatrix(camera_state, &camera_state->mtxView); +} \ No newline at end of file diff --git a/src/render_utils.h b/src/render_utils.h new file mode 100644 index 0000000..4286212 --- /dev/null +++ b/src/render_utils.h @@ -0,0 +1,36 @@ +// +// Created by martin on 19.10.21. +// + +#ifndef RBDLSIM_RENDER_UTILS_H +#define RBDLSIM_RENDER_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vectorial/simd4x4f.h" + +typedef struct { + simd4x4f mtxView; + float heading; + float pitch; + float vel[3]; + float pos[3]; +} CameraState; + +void CameraState_Init(CameraState* camera_state); +void CameraState_CalcFromMatrix(CameraState* camera_state, simd4x4f* mtx); +void CameraState_CalcToMatrix(CameraState* camera_state, simd4x4f* mtx); +void CameraState_Update( + CameraState* camera_state, + float dt, + float mouse_dx, + float mouse_dy, + float accel[3]); + +#ifdef __cplusplus +} +#endif + +#endif //RBDLSIM_RENDER_UTILS_H diff --git a/src/utils.cc b/src/utils.cc index 7c0dc7b..1f2371f 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -9,6 +9,7 @@ Timer* gTimer = &sTimer; double gTimeAtStart = 0; FILE* gLogFile = NULL; +const int cLogBufferSize = 1024; void gTimerInit() { sTimer.mCurrentTime = 0.; diff --git a/src/utils.h b/src/utils.h index af01bc9..21dec5e 100644 --- a/src/utils.h +++ b/src/utils.h @@ -65,7 +65,7 @@ extern FILE* gLogFile; void LoggingInit(); -const int cLogBufferSize = 1024; +extern const int cLogBufferSize; inline void gLog(const char* format, ...) { assert(gLogFile != NULL); diff --git a/src/vissim.cc b/src/vissim.cc index e3cc4a4..e428a07 100644 --- a/src/vissim.cc +++ b/src/vissim.cc @@ -23,20 +23,17 @@ #include "simulator.h" #include "srender.h" #include "utils.h" +#include "render_utils.h" GLFWwindow* gWindow = nullptr; GuiInputState* gGuiInputState = nullptr; +CameraState* gCameraState = nullptr; // Rendering 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), @@ -221,7 +218,7 @@ void ShowViewManip() { ImGui::SetCursorPos(view_manip_widget_pos - ImGui::GetWindowPos()); ImGui::InvisibleButton("ViewManipulator", view_manip_widget_size); ImGuizmo::ViewManipulate( - (float*)&(gViewMatrix.x), + (float*)&(gCameraState->mtxView.x), 10.0f, view_manip_widget_pos, view_manip_widget_size, @@ -347,7 +344,7 @@ void ShowTransformManip( simd4x4f identity_mat; simd4x4f_identity(&identity_mat); - ImGuizmo::Manipulate( + bool modified = ImGuizmo::Manipulate( cameraView, cameraProjection, mCurrentGizmoOperation, @@ -372,7 +369,7 @@ void DoRender() { // Render Output ImGui::Begin("Render Output", nullptr, ImGuiWindowFlags_NoScrollbar); - // Update the gViewMatrix + // Update the gCameraState->mtxView const ImVec2 content_avail = ImGui::GetContentRegionAvail(); srview_set_size(gView, content_avail.x, content_avail.y); @@ -393,7 +390,7 @@ void DoRender() { view_width / view_height, 0.1f, 50.f); - srview_set_view(gView, gViewMatrix); + srview_set_view(gView, gCameraState->mtxView); srview_set_proj(gView, gProjMatrix); // Populate render commands @@ -426,19 +423,10 @@ void DoRender() { ImGuiIO& io = ImGui::GetIO(); ShowViewManip(); - ShowTransformManip((float*)&(gViewMatrix), + ShowTransformManip((float*)&(gCameraState->mtxView), (float*)&(gProjMatrix), (float*)(&gTransformMatrix)); - /* - EditTransform( - (float*)&(gViewMatrix), - (float*)&(gProjMatrix), - (float*)(&gTransformMatrix), - true, - window_pos, - window_size); -*/ ImGui::End(); } @@ -521,16 +509,20 @@ int main(void) { bool show_demo_window = true; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + CameraState camera_state; + CameraState_Init(&camera_state); + gCameraState = &camera_state; + gRndr = srndr_create(); gView = srview_create(); gRndrCmds = srcmdbuf_create(1024); simulator_init(); - simd4x4f_translation(&gViewMatrix, 0.1f, 0.1f, -0.5f); + simd4x4f_translation(&gCameraState->mtxView, 0.1f, 0.1f, -0.5f); simd4f eye = simd4f_create(0.f, 3.f, 10.f, 1.f); simd4x4f_lookat( - &gViewMatrix, + &gCameraState->mtxView, eye, simd4f_create(0.f, 0.f, 0.f, 1.f), simd4f_create(0.f, 1.f, 0.f, 1.f)); @@ -538,6 +530,8 @@ int main(void) { simd4x4f scale_mat = simd4x4f_scale(simd4f_create(1.f, 1.f, 1.f, 1.f)); simd4x4f_mul(&gTransformMatrix, &scale_mat, &gTransformMatrix); + CameraState_CalcFromMatrix(gCameraState, &gCameraState->mtxView); + while (!glfwWindowShouldClose(gWindow)) { FrameMark; frame_counter++; @@ -582,9 +576,24 @@ int main(void) { ImGui::EndMenu(); } + float menu_bar_height = ImGui::GetWindowHeight(); ImGui::EndMainMenuBar(); + CameraState_CalcFromMatrix(gCameraState, &gCameraState->mtxView); + + ImGui::Begin("HeadingPitch"); + + bool changed = false; + changed = ImGui::SliderFloat("Heading", &gCameraState->heading, -M_PI * 0.98, M_PI * 0.98); + changed = changed || ImGui::SliderFloat("Pitch", &gCameraState->pitch, -M_PI * 0.98, M_PI * 0.98); + + if (changed) { + //CameraState_CalcToMatrix(gCameraState, &gCameraState->mtxView); + } + + ImGui::End(); + if (show_demo_window) ImGui::ShowDemoWindow(); ShowDockspace(true);