From f3715f3a87bb4e14df3c6c0c46eb312bcb09bc79 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Wed, 26 Dec 2018 23:34:13 +0100 Subject: [PATCH] Using Posix Signals to trigger module reload, exposing more gltf properties to the gui --- .gitignore | 3 +- CMakeLists.txt | 13 +++- src/RuntimeModuleManager.cc | 14 +---- src/RuntimeModuleManager.h | 1 - src/main.cc | 21 ++++--- src/modules/CMakeLists.txt | 15 +---- src/modules/RenderUtils.cc | 64 ++++++++++++++++++- src/modules/RenderUtils.h | 121 ++++++++++++++++++++++++++++++++++++ src/modules/autorebuild.sh | 1 + 9 files changed, 218 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index 590f6b3..6b3f7e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,7 @@ .*.swp build/* -cmake-build-debug/** -cmake-build-release/** +cmake-build-*/** tags 3rdparty/glfw/docs/** diff --git a/CMakeLists.txt b/CMakeLists.txt index 1089c3c..229d70f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,13 @@ SET (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # For YouCompleteMe SET (CMAKE_EXPORT_COMPILE_COMMANDS ON) +# Enable CCache +find_program(CCACHE_FOUND ccache) +if(CCACHE_FOUND) + SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) + SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) +endif(CCACHE_FOUND) + # Enable proper C++11 flags include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) @@ -37,6 +44,10 @@ add_definitions("-DIMGUI_IMPL_OPENGL_LOADER_GLAD") SET (CCD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/libccd/src) SET (CCD_LIBRARY ccd) SET (BUILD_SHARED_LIBS TRUE) +SET (FCL_BUILD_TESTS FALSE) +SET (BUILD_TESTING OFF) +SET (GLFW_BUILD_DOCS OFF) +SET (GLFW_BUILD_EXAMPLES OFF) INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_BINARY_DIR} @@ -79,7 +90,7 @@ SET ( protot_SRCS src/RuntimeModuleManager.cc src/Utils.cc - 3rdparty/glfw/deps/glad.c + 3rdparty/glfw/deps/glad.cc 3rdparty/imgui/imgui.cpp 3rdparty/imgui/imgui_draw.cpp 3rdparty/imgui/imgui_widgets.cpp diff --git a/src/RuntimeModuleManager.cc b/src/RuntimeModuleManager.cc index b4d1d80..46504d2 100644 --- a/src/RuntimeModuleManager.cc +++ b/src/RuntimeModuleManager.cc @@ -93,7 +93,6 @@ bool RuntimeModuleManager::CheckModulesChanged() { struct stat attr; double current_time = gGetTimeSinceStart(); - mNumUpdatesSinceLastModuleChange++; for (int i = 0; i < mModules.size(); i++) { RuntimeModule* module = mModules[i]; @@ -113,22 +112,15 @@ bool RuntimeModuleManager::CheckModulesChanged() { module->mtime = attr.st_mtime; module->mtimensec = attr.st_mtim.tv_nsec; module->fsize = attr.st_size; - mNumUpdatesSinceLastModuleChange = 0; gLog ("Detected file change of %s: new size %d", module->name.c_str(), attr.st_size); + gLog ("Triggering reload"); + + return true; } } - // We have to delay the actual reload trigger to make - // sure all writes to the dynamic libraries are complete. - if (mNumUpdatesSinceLastModuleChange == 5) { - gLog ("Triggering reload"); - - return true; - } - - return false; } diff --git a/src/RuntimeModuleManager.h b/src/RuntimeModuleManager.h index c0b69af..82656e9 100644 --- a/src/RuntimeModuleManager.h +++ b/src/RuntimeModuleManager.h @@ -22,7 +22,6 @@ struct RuntimeModule { struct RuntimeModuleManager { std::vector mModules; - int mNumUpdatesSinceLastModuleChange = 0; int mTargetFPS = 30; void RegisterModule(const char* name); diff --git a/src/main.cc b/src/main.cc index a171e4b..284a448 100644 --- a/src/main.cc +++ b/src/main.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include "Timer.h" #include "RuntimeModuleManager.h" @@ -66,6 +67,15 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action, glfwSetWindowShouldClose(window, GLFW_TRUE); } +void signal_handler(int signo) { + gLog ("Received signal %d", signo); + + if (gModuleManager->CheckModulesChanged()) { + gModuleManager->UnloadModules(); + gModuleManager->LoadModules(); + } +} + void mouse_scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { mouse_scroll_x += xoffset; mouse_scroll_y += yoffset; @@ -109,6 +119,10 @@ int main(void) LoggingInit(); + if (signal(SIGUSR1, signal_handler) == SIG_ERR) { + gLog ("Error registering signal handler!"); + } + WriteSerializer out_serializer; ReadSerializer in_serializer; @@ -214,13 +228,6 @@ int main(void) if (show_demo_window) ImGui::ShowDemoWindow(&show_demo_window); - if (module_manager.CheckModulesChanged()) { - gLog("Detected module update at frame %d. Unloading all modules.", frame_counter); - module_manager.UnloadModules(); - // We need to sleep to make sure we load the new files - module_manager.LoadModules(); - } - frame_time_last = frame_time_current; frame_time_current = glfwGetTime(); frame_delta_time = frame_time_current - frame_time_last; diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index 9588c74..a4c56bf 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -12,15 +12,6 @@ ADD_LIBRARY (TestModule SHARED TestModule.cc ) -# ADD_LIBRARY (CharacterModule SHARED -# CharacterModule.cc -# ) -# -# TARGET_LINK_LIBRARIES ( CharacterModule -# RenderModule -# ) -# -# TARGET_LINK_LIBRARIES ( TestModule -# CharacterModule -# RenderModule -# ) +TARGET_LINK_LIBRARIES ( TestModule + RenderModule + ) diff --git a/src/modules/RenderUtils.cc b/src/modules/RenderUtils.cc index dc1d65c..57782b3 100644 --- a/src/modules/RenderUtils.cc +++ b/src/modules/RenderUtils.cc @@ -841,6 +841,10 @@ VertexAttributeType AssetFile::GetVertexAttributeType(const std::string &attribu attribute_type = VertexAttributeNormal; } else if (attribute_string.compare("TEXCOORD_0") == 0) { attribute_type = VertexAttributeTexCoord0; + } else if (attribute_string.compare("JOINTS_0") == 0) { + attribute_type = VertexAttributeBoneIndex0; + } else if (attribute_string.compare("WEIGHTS_0") == 0) { + attribute_type = VertexAttributeBoneWeights0; } else { attribute_type = VertexAttributeTypeCount; } @@ -973,6 +977,21 @@ void AssetFile::DrawGui() { const tinygltf::Mesh& mesh = mGLTFModel.meshes[i]; ImGui::PushID("mesh"); if (ImGui::TreeNode((void*)(intptr_t)i, "[%d] %s", i, mesh.name.c_str())) { + for (int j = 0, m = mesh.primitives.size(); j < m; ++j) { + const tinygltf::Primitive& primitive + = mesh.primitives[j]; + if (ImGui::TreeNode("Attributes")) { + std::map::const_iterator iter = primitive.attributes.begin(); + while (iter != primitive.attributes.end()) { + ImGui::Text("%s", iter->first.c_str()); + iter ++; + } + ImGui::TreePop(); + } + ImGui::Text("Indices %d", primitive.indices); + ImGui::Text("Material %d", primitive.material); + ImGui::Text("Mode %d", primitive.mode); + } ImGui::TreePop(); } ImGui::PopID(); @@ -985,16 +1004,59 @@ void AssetFile::DrawGui() { const tinygltf::Node& node = mGLTFModel.nodes[i]; ImGui::PushID("node"); if (ImGui::TreeNode((void*)(intptr_t)i, "[%d] %s", i, node.name.c_str())) { + if (node.camera >= 0) { + ImGui::Text("Camera %d", node.camera); + } + + if (node.mesh >= 0) { + ImGui::Text("Mesh %d", node.mesh); + } + + if (node.skin >= 0) { + ImGui::Text("Skin %d", node.skin); + } + DrawNodeGui(node); ImGui::TreePop(); } + ImGui::PopID(); } ImGui::TreePop(); } + + if (ImGui::TreeNode("Skins")) { + for (int i = 0, n = mGLTFModel.skins.size(); i < n; ++i) { + const tinygltf::Skin& skin = mGLTFModel.skins[i]; + ImGui::PushID("skin"); + if (ImGui::TreeNode((void*)(intptr_t)i, "[%d] %s", i, skin.name.c_str())) { + ImGui::Text("Skeleton: %d", skin.skeleton); + + if (ImGui::TreeNode("Joints")) { + for (int j = 0, m = skin.joints.size(); j < m; j++) { + ImGui::Text("%d", skin.joints[j]); + } + ImGui::TreePop(); + } + ImGui::TreePop(); + } + ImGui::PopID(); + } + ImGui::TreePop(); + } } - +// +// Skeleton +// +void Skeleton::UpdateMatrices() { + int n = mParentIndex.size(); + mMatrices[0] = mLocalTransforms[0].toMatrix(); + for (int i = 1; i < n; i++) { + int parent_index = mParentIndex[i]; + mMatrices[i] = mMatrices[parent_index] * mLocalTransforms[i].toMatrix(); + } +} // // Debug Draw Stuff diff --git a/src/modules/RenderUtils.h b/src/modules/RenderUtils.h index 79435dd..9b437fc 100644 --- a/src/modules/RenderUtils.h +++ b/src/modules/RenderUtils.h @@ -337,6 +337,8 @@ enum VertexAttributeType { VertexAttributeNormal = 1, VertexAttributeTexCoord0 = 2, VertexAttributeColor = 3, + VertexAttributeBoneIndex0 = 4, + VertexAttributeBoneWeights0 = 5, VertexAttributeTypeCount }; @@ -466,6 +468,125 @@ struct VertexArrayMesh { void Draw(GLenum mode); }; +struct Skeleton { + std::vector mParentIndex; + std::vector mMatrices; + std::vector mLocalTransforms; + + void UpdateMatrices(); +}; + +struct SkinnedModel { + Skeleton mSkeleton; + std::vector mMesh; +}; + +struct SkinnedMesh { + struct VertexData { + union { + struct { + float x; + float y; + float z; + float w; + float nx; + float ny; + float nz; + float s; + float t; + GLubyte bone_idx0; + GLubyte bone_idx1; + GLubyte bone_idx2; + GLubyte bone_idx3; + float bone_w0; + float bone_w1; + float bone_w2; + float bone_w3; + }; + struct { + float mCoords[4]; + float mNormals[3]; + float mTexCoords[2]; + GLubyte mBoneIndices[4]; + float mBoneWeights[4]; + }; + }; + + VertexData() : + x(0.0f), + y(0.0f), + z(0.0f), + w(0.0f), + nx(0.0f), + ny(0.0f), + nz(0.0f), + s(0.0f), + t(0.0f), + bone_idx0(0), + bone_idx1(0), + bone_idx2(0), + bone_idx3(0), + bone_w0(0), + bone_w1(0), + bone_w2(0), + bone_w3(0) + {} + + VertexData( + float x, + float y, + float z, + float w, + float nx, + float ny, + float nz, + float s, + float t, + GLubyte b0, + GLubyte b1, + GLubyte b2, + GLubyte b3, + float w0, + float w1, + float w2, + float w3 + ) : + x(x), y(y), z(z), w(w), + nx(nx), ny(ny), nz(nz), + s(s), t(t), + bone_idx0(b0), bone_idx1(b1), bone_idx2(b2), bone_idx3(b3), + bone_w0(w0), bone_w1(w1), bone_w2(w2), bone_w3(w3) {} + + VertexData& operator= (const VertexData& data) { + x = data.x; + y = data.y; + z = data.z; + w = data.w; + nx = data.nx; + ny = data.ny; + nz = data.nz; + s = data.s; + t = data.t; + bone_idx0 = data.bone_idx0; + bone_idx1 = data.bone_idx1; + bone_idx2 = data.bone_idx2; + bone_idx3 = data.bone_idx3, + bone_w0 = data.bone_w0; + bone_w1 = data.bone_w1; + bone_w2 = data.bone_w2; + bone_w3 = data.bone_w3; + + return *this; + } + }; + + void Initialize(const int& size, GLenum usage); + void Cleanup(); + GLuint AllocateMesh(const int& size); + void Bind(); + bool IsBound(); +}; + struct AssetFile { std::string mFilename; tinygltf::Model mGLTFModel; diff --git a/src/modules/autorebuild.sh b/src/modules/autorebuild.sh index 24e22f1..2e2f061 100755 --- a/src/modules/autorebuild.sh +++ b/src/modules/autorebuild.sh @@ -1,4 +1,5 @@ inotifywait -q -m -e close_write ../../../src/modules | while read -r filename event; do /usr/bin/make # or "./$filename" + ../../../scripts/trigger_reload.sh protot done