Split up MeshHierarchy into Skeleton and SkeletonMeshes, minor code style cleanup

master
Martin Felis 2017-02-23 15:19:26 +01:00
parent d1ada7f3a4
commit 6573a36c90
5 changed files with 158 additions and 77 deletions

View File

@ -64,31 +64,54 @@ CharacterEntity::CharacterEntity() {
// base_mesh->Update();
// delete quad;
int bone_index;
// Build the snowman
entity->mesh.addMesh(
// 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)) {

View File

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

View File

@ -9,6 +9,7 @@
#include <bgfx/bgfx.h>
#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<Mesh*> meshes;
/// index of the parent. Children must have higher indices than heir
// parents
std::vector<int> parent;
/// Transforms relative to their parents.
std::vector<Transform> localTransforms;
struct Skeleton {
/// index of the mParent. Children must have higher indices than heir
// mParents
std::vector<int> mParent;
/// Transforms relative to their mParents.
std::vector<Transform> mLocalTransforms;
/// Absolute transforms.
std::vector<Matrix44f> meshMatrices;
std::vector<Matrix44f> 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<Mesh*, int> MeshBoneIndex;
std::vector<MeshBoneIndex> 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)
{}
};

View File

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

View File

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