Using Posix Signals to trigger module reload, exposing more gltf properties to the gui

simple_math_single_header
Martin Felis 2018-12-26 23:34:13 +01:00
parent c1b39036db
commit f3715f3a87
9 changed files with 218 additions and 35 deletions

3
.gitignore vendored
View File

@ -1,8 +1,7 @@
.*.swp .*.swp
build/* build/*
cmake-build-debug/** cmake-build-*/**
cmake-build-release/**
tags tags
3rdparty/glfw/docs/** 3rdparty/glfw/docs/**

View File

@ -14,6 +14,13 @@ SET (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# For YouCompleteMe # For YouCompleteMe
SET (CMAKE_EXPORT_COMPILE_COMMANDS ON) 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 # Enable proper C++11 flags
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) 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_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/libccd/src)
SET (CCD_LIBRARY ccd) SET (CCD_LIBRARY ccd)
SET (BUILD_SHARED_LIBS TRUE) 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 ( INCLUDE_DIRECTORIES (
${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}
@ -79,7 +90,7 @@ SET ( protot_SRCS
src/RuntimeModuleManager.cc src/RuntimeModuleManager.cc
src/Utils.cc src/Utils.cc
3rdparty/glfw/deps/glad.c 3rdparty/glfw/deps/glad.cc
3rdparty/imgui/imgui.cpp 3rdparty/imgui/imgui.cpp
3rdparty/imgui/imgui_draw.cpp 3rdparty/imgui/imgui_draw.cpp
3rdparty/imgui/imgui_widgets.cpp 3rdparty/imgui/imgui_widgets.cpp

View File

@ -93,7 +93,6 @@ bool RuntimeModuleManager::CheckModulesChanged() {
struct stat attr; struct stat attr;
double current_time = gGetTimeSinceStart(); double current_time = gGetTimeSinceStart();
mNumUpdatesSinceLastModuleChange++;
for (int i = 0; i < mModules.size(); i++) { for (int i = 0; i < mModules.size(); i++) {
RuntimeModule* module = mModules[i]; RuntimeModule* module = mModules[i];
@ -113,22 +112,15 @@ bool RuntimeModuleManager::CheckModulesChanged() {
module->mtime = attr.st_mtime; module->mtime = attr.st_mtime;
module->mtimensec = attr.st_mtim.tv_nsec; module->mtimensec = attr.st_mtim.tv_nsec;
module->fsize = attr.st_size; module->fsize = attr.st_size;
mNumUpdatesSinceLastModuleChange = 0;
gLog ("Detected file change of %s: new size %d", gLog ("Detected file change of %s: new size %d",
module->name.c_str(), attr.st_size); 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; return false;
} }

View File

@ -22,7 +22,6 @@ struct RuntimeModule {
struct RuntimeModuleManager { struct RuntimeModuleManager {
std::vector<RuntimeModule*> mModules; std::vector<RuntimeModule*> mModules;
int mNumUpdatesSinceLastModuleChange = 0;
int mTargetFPS = 30; int mTargetFPS = 30;
void RegisterModule(const char* name); void RegisterModule(const char* name);

View File

@ -11,6 +11,7 @@
#include <unistd.h> #include <unistd.h>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <signal.h>
#include "Timer.h" #include "Timer.h"
#include "RuntimeModuleManager.h" #include "RuntimeModuleManager.h"
@ -66,6 +67,15 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
glfwSetWindowShouldClose(window, GLFW_TRUE); 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) { void mouse_scroll_callback(GLFWwindow* window, double xoffset, double yoffset) {
mouse_scroll_x += xoffset; mouse_scroll_x += xoffset;
mouse_scroll_y += yoffset; mouse_scroll_y += yoffset;
@ -109,6 +119,10 @@ int main(void)
LoggingInit(); LoggingInit();
if (signal(SIGUSR1, signal_handler) == SIG_ERR) {
gLog ("Error registering signal handler!");
}
WriteSerializer out_serializer; WriteSerializer out_serializer;
ReadSerializer in_serializer; ReadSerializer in_serializer;
@ -214,13 +228,6 @@ int main(void)
if (show_demo_window) if (show_demo_window)
ImGui::ShowDemoWindow(&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_last = frame_time_current;
frame_time_current = glfwGetTime(); frame_time_current = glfwGetTime();
frame_delta_time = frame_time_current - frame_time_last; frame_delta_time = frame_time_current - frame_time_last;

View File

@ -12,15 +12,6 @@ ADD_LIBRARY (TestModule SHARED
TestModule.cc TestModule.cc
) )
# ADD_LIBRARY (CharacterModule SHARED TARGET_LINK_LIBRARIES ( TestModule
# CharacterModule.cc RenderModule
# ) )
#
# TARGET_LINK_LIBRARIES ( CharacterModule
# RenderModule
# )
#
# TARGET_LINK_LIBRARIES ( TestModule
# CharacterModule
# RenderModule
# )

View File

@ -841,6 +841,10 @@ VertexAttributeType AssetFile::GetVertexAttributeType(const std::string &attribu
attribute_type = VertexAttributeNormal; attribute_type = VertexAttributeNormal;
} else if (attribute_string.compare("TEXCOORD_0") == 0) { } else if (attribute_string.compare("TEXCOORD_0") == 0) {
attribute_type = VertexAttributeTexCoord0; 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 { } else {
attribute_type = VertexAttributeTypeCount; attribute_type = VertexAttributeTypeCount;
} }
@ -973,6 +977,21 @@ void AssetFile::DrawGui() {
const tinygltf::Mesh& mesh = mGLTFModel.meshes[i]; const tinygltf::Mesh& mesh = mGLTFModel.meshes[i];
ImGui::PushID("mesh"); ImGui::PushID("mesh");
if (ImGui::TreeNode((void*)(intptr_t)i, "[%d] %s", i, mesh.name.c_str())) { 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<std::string, int>::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::TreePop();
} }
ImGui::PopID(); ImGui::PopID();
@ -985,16 +1004,59 @@ void AssetFile::DrawGui() {
const tinygltf::Node& node = mGLTFModel.nodes[i]; const tinygltf::Node& node = mGLTFModel.nodes[i];
ImGui::PushID("node"); ImGui::PushID("node");
if (ImGui::TreeNode((void*)(intptr_t)i, "[%d] %s", i, node.name.c_str())) { 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); DrawNodeGui(node);
ImGui::TreePop(); ImGui::TreePop();
} }
ImGui::PopID(); ImGui::PopID();
} }
ImGui::TreePop(); 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 // Debug Draw Stuff

View File

@ -337,6 +337,8 @@ enum VertexAttributeType {
VertexAttributeNormal = 1, VertexAttributeNormal = 1,
VertexAttributeTexCoord0 = 2, VertexAttributeTexCoord0 = 2,
VertexAttributeColor = 3, VertexAttributeColor = 3,
VertexAttributeBoneIndex0 = 4,
VertexAttributeBoneWeights0 = 5,
VertexAttributeTypeCount VertexAttributeTypeCount
}; };
@ -466,6 +468,125 @@ struct VertexArrayMesh {
void Draw(GLenum mode); void Draw(GLenum mode);
}; };
struct Skeleton {
std::vector<int> mParentIndex;
std::vector<Matrix44f> mMatrices;
std::vector<Transform> mLocalTransforms;
void UpdateMatrices();
};
struct SkinnedModel {
Skeleton mSkeleton;
std::vector<VertexArrayMesh> 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 { struct AssetFile {
std::string mFilename; std::string mFilename;
tinygltf::Model mGLTFModel; tinygltf::Model mGLTFModel;

View File

@ -1,4 +1,5 @@
inotifywait -q -m -e close_write ../../../src/modules | inotifywait -q -m -e close_write ../../../src/modules |
while read -r filename event; do while read -r filename event; do
/usr/bin/make # or "./$filename" /usr/bin/make # or "./$filename"
../../../scripts/trigger_reload.sh protot
done done