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
build/*
cmake-build-debug/**
cmake-build-release/**
cmake-build-*/**
tags
3rdparty/glfw/docs/**

View File

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

View File

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

View File

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

View File

@ -11,6 +11,7 @@
#include <unistd.h>
#include <iostream>
#include <sstream>
#include <signal.h>
#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;

View File

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

View File

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

View File

@ -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<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 {
std::string mFilename;
tinygltf::Model mGLTFModel;

View File

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