Initial attempts for a camera state object for easier camera movement.

master
Martin Felis 2021-10-19 22:40:44 +02:00
parent ea92663609
commit eb635162c8
6 changed files with 146 additions and 22 deletions

View File

@ -87,6 +87,7 @@ target_sources(vissim PRIVATE
src/vissim.cc
src/sthstry.c
src/simulator.cc
src/render_utils.c
)
# Tests

77
src/render_utils.c Normal file
View File

@ -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);
}

36
src/render_utils.h Normal file
View File

@ -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

View File

@ -9,6 +9,7 @@ Timer* gTimer = &sTimer;
double gTimeAtStart = 0;
FILE* gLogFile = NULL;
const int cLogBufferSize = 1024;
void gTimerInit() {
sTimer.mCurrentTime = 0.;

View File

@ -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);

View File

@ -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);