Using Posix Signals to trigger module reload, exposing more gltf properties to the gui
parent
c1b39036db
commit
f3715f3a87
|
@ -1,8 +1,7 @@
|
||||||
.*.swp
|
.*.swp
|
||||||
|
|
||||||
build/*
|
build/*
|
||||||
cmake-build-debug/**
|
cmake-build-*/**
|
||||||
cmake-build-release/**
|
|
||||||
tags
|
tags
|
||||||
|
|
||||||
3rdparty/glfw/docs/**
|
3rdparty/glfw/docs/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
21
src/main.cc
21
src/main.cc
|
@ -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;
|
||||||
|
|
|
@ -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
|
|
||||||
# )
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue