From 6573a36c901f18c5a05da8a75f6471dae4020211 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Thu, 23 Feb 2017 15:19:26 +0100 Subject: [PATCH] Split up MeshHierarchy into Skeleton and SkeletonMeshes, minor code style cleanup --- src/modules/CharacterModule.cc | 60 ++++++++++++++------- src/modules/RenderModule.cc | 67 ++++++++++++++--------- src/modules/RenderModule.h | 98 +++++++++++++++++++++++----------- src/modules/RenderUtils.cc | 9 ++++ src/modules/RenderUtils.h | 1 + 5 files changed, 158 insertions(+), 77 deletions(-) diff --git a/src/modules/CharacterModule.cc b/src/modules/CharacterModule.cc index d973682..a38b8ac 100644 --- a/src/modules/CharacterModule.cc +++ b/src/modules/CharacterModule.cc @@ -64,31 +64,54 @@ CharacterEntity::CharacterEntity() { // base_mesh->Update(); // delete quad; + int bone_index; + // Build the snowman - entity->mesh.addMesh( - - 1, + + // bottom sphere + bone_index = entity->mSkeleton.AddBone( + -1, Transform::fromTrans( Vector3f (0.0f, 0.9 * 0.5f, 0.0f) - ), -// base_mesh - Mesh::sCreateUVSphere(45, 45, 0.9) + ) ); + entity->mSkeletonMeshes.AddMesh ( + Mesh::sCreateUVSphere(45, 45, 0.9), + bone_index + ); + gLog ("Now have %d bones, bone_index %d", + entity->mSkeleton.Length(), + bone_index); - entity->mesh.addMesh( - 0, + // middle sphere + bone_index = entity->mSkeleton.AddBone( + bone_index, Transform::fromTrans( Vector3f (0.0f, 0.55f, 0.0f) - ), - Mesh::sCreateUVSphere (45, 45, 0.7) + ) ); + entity->mSkeletonMeshes.AddMesh ( + Mesh::sCreateUVSphere (45, 45, 0.7), + bone_index + ); + gLog ("Now have %d bones, bone_index %d", + entity->mSkeleton.Length(), + bone_index); - entity->mesh.addMesh( - 1, + // top sphere + bone_index = entity->mSkeleton.AddBone( + bone_index, Transform::fromTrans( Vector3f (0.0f, 0.4f, 0.0f) - ), - Mesh::sCreateUVSphere (45, 45, 0.5) + ) ); + entity->mSkeletonMeshes.AddMesh ( + Mesh::sCreateUVSphere (45, 45, 0.5), + bone_index + ); + gLog ("Now have %d bones, bone_index %d", + entity->mSkeleton.Length(), + bone_index); // mState->character->entity->mesh = bgfxutils::createCuboid (1.f, 1.f, 1.f); // mState->character->entity->mesh = bgfxutils::createCylinder (20); @@ -208,7 +231,7 @@ void CharacterEntity::Update(float dt) { } // apply transformation - entity->transform.translation.set( + entity->mTransform.translation.set( mPosition[0], mPosition[1], mPosition[2]); @@ -219,10 +242,10 @@ void CharacterEntity::Update(float dt) { Quaternion quat (-cos(cur_time), 0.0f, 0.0f * sin(cur_time), 1.0f); quat.normalize(); - entity->mesh.localTransforms[0].rotation = quat; + entity->mTransform.rotation = quat; // update matrices - entity->mesh.updateMatrices(entity->transform.toMatrix()); + entity->mSkeleton.UpdateMatrices(entity->mTransform.toMatrix()); cur_time += dt; } @@ -240,8 +263,7 @@ void ShowCharacterPropertiesWindow (CharacterEntity* character) { ImGui::DragFloat3 ("Position", character->mPosition.data(), 0.01, -10.0f, 10.0f); ImGui::DragFloat3 ("Velocity", character->mVelocity.data(), 0.01, -10.0f, 10.0f); - - for (int i = 0; i < character->entity->mesh.meshes.size(); ++i) { + for (int i = 0; i < character->entity->mSkeleton.Length(); ++i) { char buf[32]; snprintf (buf, 32, "Mesh %d", i); @@ -252,7 +274,7 @@ void ShowCharacterPropertiesWindow (CharacterEntity* character) { node_flags); if (node_open) { - Transform &transform = character->entity->mesh.localTransforms[i]; + Transform &transform = character->entity->mSkeleton.mLocalTransforms[i]; ImGui::DragFloat3 ("Position", transform.translation.data(), 0.01, -10.0f, 10.0f); if (ImGui::Protot::DragFloat4Normalized ("Rotation", transform.rotation.data(), 0.001, -1.0f, 1.0f)) { diff --git a/src/modules/RenderModule.cc b/src/modules/RenderModule.cc index 62a3cf2..4318902 100644 --- a/src/modules/RenderModule.cc +++ b/src/modules/RenderModule.cc @@ -145,23 +145,17 @@ const struct module_api MODULE_API = { }; } -void MeshHierarchy::updateMatrices(const Matrix44f &world_transform) { - for (uint32_t i = 0; i < meshes.size(); ++i) { +void Skeleton::UpdateMatrices(const Matrix44f &world_transform) { + for (uint32_t i = 0; i < mBoneMatrices.size(); ++i) { Matrix44f parent_matrix (world_transform); - if (parent[i] != -1) { - parent_matrix = meshMatrices[parent[i]]; + if (mParent[i] != -1) { + parent_matrix = mBoneMatrices[mParent[i]]; } - meshMatrices[i] = localTransforms[i].toMatrix() * parent_matrix; + mBoneMatrices[i] = mLocalTransforms[i].toMatrix() * parent_matrix; } } -void MeshHierarchy::submit(const RenderState *state) { - for (uint32_t i = 0; i < meshes.size(); ++i) { - bgfxutils::meshSubmit (meshes[i]->mBgfxMesh, state, 1, meshMatrices[i].data()); - } -}; - // BGFX globals bgfx::VertexBufferHandle cube_vbh; bgfx::IndexBufferHandle cube_ibh; @@ -1515,45 +1509,66 @@ void Renderer::paintGL() { float light_pos_world[3]; // shadow map pass - for (uint32_t j = 0; j < entities[i]->mesh.meshes.size(); ++j) { + for (uint32_t j = 0; j < entities[i]->mSkeletonMeshes.Length(); ++j) { bx::mtxMul( lightMtx, - entities[i]->mesh.meshMatrices[j].data(), + entities[i]->mSkeletonMeshes.GetBoneMatrix(j).data(), lights[0].mtxShadow ); bgfx::setUniform(lights[0].u_lightMtx, lightMtx); - bgfxutils::meshSubmit ( - entities[i]->mesh.meshes[j]->mBgfxMesh, + entities[i]->mSkeletonMeshes.GetMesh(j)->Submit( &s_renderStates[RenderState::ShadowMap], - 1, - entities[i]->mesh.meshMatrices[j].data() + entities[i]->mSkeletonMeshes.GetBoneMatrix(j).data() ); } // scene pass - for (uint32_t j = 0; j < entities[i]->mesh.meshes.size(); ++j) { + for (uint32_t j = 0; j < entities[i]->mSkeletonMeshes.Length(); ++j) { bx::mtxMul( lightMtx, - entities[i]->mesh.meshMatrices[j].data(), + entities[i]->mSkeletonMeshes.GetBoneMatrix(j).data(), lights[0].mtxShadow ); // compute world position of the light Vector4f light_pos = - entities[i]->mesh.meshMatrices[j] + entities[i]->mSkeletonMeshes.GetBoneMatrix(j) * SimpleMath::Map(lights[0].pos, 4, 1); bgfx::setUniform(lights[0].u_lightPos, light_pos.data()); - bgfx::setUniform(lights[0].u_lightMtx, lightMtx); bgfx::setUniform(u_color, entities[i]->color); - bgfxutils::meshSubmit ( - entities[i]->mesh.meshes[j]->mBgfxMesh, + bgfx::setUniform(lights[0].u_lightMtx, lightMtx); + entities[i]->mSkeletonMeshes.GetMesh(j)->Submit( &s_renderStates[RenderState::Scene], - 1, - entities[i]->mesh.meshMatrices[j].data() + entities[i]->mSkeletonMeshes.GetBoneMatrix(j).data() ); - } + + // + // + // +// for (uint32_t j = 0; j < entities[i]->mesh.meshes.size(); ++j) { +// bx::mtxMul( +// lightMtx, +// entities[i]->mesh.meshMatrices[j].data(), +// lights[0].mtxShadow +// ); +// +// // compute world position of the light +// Vector4f light_pos = +// entities[i]->mesh.meshMatrices[j] +// * SimpleMath::Map(lights[0].pos, 4, 1); +// +// bgfx::setUniform(lights[0].u_lightPos, light_pos.data()); +// bgfx::setUniform(lights[0].u_lightMtx, lightMtx); +// bgfxutils::meshSubmit ( +// entities[i]->mesh.meshes[j]->mBgfxMesh, +// &s_renderStates[RenderState::Scene], +// 1, +// entities[i]->mesh.meshMatrices[j].data() +// ); +// +// } } // render debug information diff --git a/src/modules/RenderModule.h b/src/modules/RenderModule.h index 50accd7..b3b3450 100644 --- a/src/modules/RenderModule.h +++ b/src/modules/RenderModule.h @@ -9,6 +9,7 @@ #include +#include "Globals.h" #include "RenderUtils.h" struct Entity; @@ -230,49 +231,82 @@ struct Transform { } }; -struct MeshHierarchy { - ~MeshHierarchy() - { - for (Mesh* mesh : meshes) { - delete mesh; - } - } - std::vector meshes; - - /// index of the parent. Children must have higher indices than heir - // parents - std::vector parent; - /// Transforms relative to their parents. - std::vector localTransforms; +struct Skeleton { + /// index of the mParent. Children must have higher indices than heir + // mParents + std::vector mParent; + /// Transforms relative to their mParents. + std::vector mLocalTransforms; /// Absolute transforms. - std::vector meshMatrices; + std::vector mBoneMatrices; - void addMesh( - const int parent_idx, - const Transform& transform, - Mesh* mesh) { - assert (parent_idx == -1 || parent_idx < parent.size()); - parent.push_back(parent_idx); - localTransforms.push_back(transform); - meshes.push_back(mesh); + int AddBone( + const int parent_index, + const Transform& transform + ) { + assert (parent_index == -1 || parent_index < mParent.size()); + mParent.push_back(parent_index); + mLocalTransforms.push_back(transform); - if (parent_idx != -1) { - meshMatrices.push_back(transform.toMatrix() * meshMatrices[parent_idx]); + if (parent_index != -1) { + mBoneMatrices.push_back(transform.toMatrix() * mBoneMatrices[parent_index]); } else { - meshMatrices.push_back(transform.toMatrix()); + mBoneMatrices.push_back(transform.toMatrix()); + } + + return mBoneMatrices.size() - 1; + } + void UpdateMatrices(const Matrix44f &world_transform); + int Length() const { + return mBoneMatrices.size(); + } +}; + +struct SkeletonMeshes { + Skeleton& mSkeleton; + typedef std::pair MeshBoneIndex; + std::vector mMeshBoneIndices; + + SkeletonMeshes(Skeleton &skeleton) : + mSkeleton(skeleton) + {} + + ~SkeletonMeshes() { + for(MeshBoneIndex& mesh_bone : mMeshBoneIndices) { + delete mesh_bone.first; } } - void updateMatrices(const Matrix44f &world_transform); - void submit(const RenderState *state); + + void AddMesh (Mesh* mesh, int bone_index) { + mMeshBoneIndices.push_back (MeshBoneIndex (mesh, bone_index)); + } + + const Matrix44f GetBoneMatrix(int index) const { + assert (index >= 0 && index < Length()); + assert (mMeshBoneIndices[index].second < mSkeleton.mBoneMatrices.size()); + + return mSkeleton.mBoneMatrices[mMeshBoneIndices[index].second]; + } + + const Mesh* GetMesh(int index) const { + assert (index >= 0 && index < Length()); + return mMeshBoneIndices[index].first; + } + + int Length() const { + return mMeshBoneIndices.size(); + } }; struct Entity { - Transform transform; - float color[4]; - MeshHierarchy mesh; + Transform mTransform; + Vector4f mColor; + Skeleton mSkeleton; + SkeletonMeshes mSkeletonMeshes; Entity() : - color { 1.f, 1.f, 1.f, 1.f } + mColor (1.f, 1.f, 1.f, 1.f ), + mSkeletonMeshes(mSkeleton) {} }; diff --git a/src/modules/RenderUtils.cc b/src/modules/RenderUtils.cc index cdd48e5..79e5648 100644 --- a/src/modules/RenderUtils.cc +++ b/src/modules/RenderUtils.cc @@ -920,6 +920,15 @@ void Mesh::Merge (const Mesh& other, const Matrix44f &transform) { } } +void Mesh::Submit (const RenderState *state, const float* matrix) const { + bgfxutils::meshSubmit ( + mBgfxMesh, + state, + 1, + matrix); +} + + Mesh* Mesh::sCreateCuboid (float width, float height, float depth) { Mesh* result = new Mesh(); diff --git a/src/modules/RenderUtils.h b/src/modules/RenderUtils.h index eaadb6e..04e567e 100644 --- a/src/modules/RenderUtils.h +++ b/src/modules/RenderUtils.h @@ -22,6 +22,7 @@ struct Mesh { ~Mesh(); void Update(); void Merge (const Mesh& other, const Matrix44f &mat = Matrix44f::Identity()); + void Submit (const RenderState *state, const float* matrix) const; static Mesh *sCreateCuboid (float width, float height, float depth); static Mesh *sCreateUVSphere (int rows, int segments, float radius = 1.0f);