Split up MeshHierarchy into Skeleton and SkeletonMeshes, minor code style cleanup
parent
d1ada7f3a4
commit
6573a36c90
|
@ -64,31 +64,54 @@ CharacterEntity::CharacterEntity() {
|
||||||
// base_mesh->Update();
|
// base_mesh->Update();
|
||||||
// delete quad;
|
// delete quad;
|
||||||
|
|
||||||
|
int bone_index;
|
||||||
|
|
||||||
// Build the snowman
|
// Build the snowman
|
||||||
entity->mesh.addMesh(
|
|
||||||
|
// bottom sphere
|
||||||
|
bone_index = entity->mSkeleton.AddBone(
|
||||||
-1,
|
-1,
|
||||||
Transform::fromTrans(
|
Transform::fromTrans(
|
||||||
Vector3f (0.0f, 0.9 * 0.5f, 0.0f)
|
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(
|
// middle sphere
|
||||||
0,
|
bone_index = entity->mSkeleton.AddBone(
|
||||||
|
bone_index,
|
||||||
Transform::fromTrans(
|
Transform::fromTrans(
|
||||||
Vector3f (0.0f, 0.55f, 0.0f)
|
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(
|
// top sphere
|
||||||
1,
|
bone_index = entity->mSkeleton.AddBone(
|
||||||
|
bone_index,
|
||||||
Transform::fromTrans(
|
Transform::fromTrans(
|
||||||
Vector3f (0.0f, 0.4f, 0.0f)
|
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::createCuboid (1.f, 1.f, 1.f);
|
||||||
// mState->character->entity->mesh = bgfxutils::createCylinder (20);
|
// mState->character->entity->mesh = bgfxutils::createCylinder (20);
|
||||||
|
@ -208,7 +231,7 @@ void CharacterEntity::Update(float dt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply transformation
|
// apply transformation
|
||||||
entity->transform.translation.set(
|
entity->mTransform.translation.set(
|
||||||
mPosition[0],
|
mPosition[0],
|
||||||
mPosition[1],
|
mPosition[1],
|
||||||
mPosition[2]);
|
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);
|
Quaternion quat (-cos(cur_time), 0.0f, 0.0f * sin(cur_time), 1.0f);
|
||||||
quat.normalize();
|
quat.normalize();
|
||||||
|
|
||||||
entity->mesh.localTransforms[0].rotation = quat;
|
entity->mTransform.rotation = quat;
|
||||||
|
|
||||||
// update matrices
|
// update matrices
|
||||||
entity->mesh.updateMatrices(entity->transform.toMatrix());
|
entity->mSkeleton.UpdateMatrices(entity->mTransform.toMatrix());
|
||||||
|
|
||||||
cur_time += dt;
|
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 ("Position", character->mPosition.data(), 0.01, -10.0f, 10.0f);
|
||||||
ImGui::DragFloat3 ("Velocity", character->mVelocity.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->mSkeleton.Length(); ++i) {
|
||||||
for (int i = 0; i < character->entity->mesh.meshes.size(); ++i) {
|
|
||||||
char buf[32];
|
char buf[32];
|
||||||
snprintf (buf, 32, "Mesh %d", i);
|
snprintf (buf, 32, "Mesh %d", i);
|
||||||
|
|
||||||
|
@ -252,7 +274,7 @@ void ShowCharacterPropertiesWindow (CharacterEntity* character) {
|
||||||
node_flags);
|
node_flags);
|
||||||
|
|
||||||
if (node_open) {
|
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);
|
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)) {
|
if (ImGui::Protot::DragFloat4Normalized ("Rotation", transform.rotation.data(), 0.001, -1.0f, 1.0f)) {
|
||||||
|
|
|
@ -145,23 +145,17 @@ const struct module_api MODULE_API = {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshHierarchy::updateMatrices(const Matrix44f &world_transform) {
|
void Skeleton::UpdateMatrices(const Matrix44f &world_transform) {
|
||||||
for (uint32_t i = 0; i < meshes.size(); ++i) {
|
for (uint32_t i = 0; i < mBoneMatrices.size(); ++i) {
|
||||||
Matrix44f parent_matrix (world_transform);
|
Matrix44f parent_matrix (world_transform);
|
||||||
if (parent[i] != -1) {
|
if (mParent[i] != -1) {
|
||||||
parent_matrix = meshMatrices[parent[i]];
|
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 globals
|
||||||
bgfx::VertexBufferHandle cube_vbh;
|
bgfx::VertexBufferHandle cube_vbh;
|
||||||
bgfx::IndexBufferHandle cube_ibh;
|
bgfx::IndexBufferHandle cube_ibh;
|
||||||
|
@ -1515,45 +1509,66 @@ void Renderer::paintGL() {
|
||||||
float light_pos_world[3];
|
float light_pos_world[3];
|
||||||
|
|
||||||
// shadow map pass
|
// 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(
|
bx::mtxMul(
|
||||||
lightMtx,
|
lightMtx,
|
||||||
entities[i]->mesh.meshMatrices[j].data(),
|
entities[i]->mSkeletonMeshes.GetBoneMatrix(j).data(),
|
||||||
lights[0].mtxShadow
|
lights[0].mtxShadow
|
||||||
);
|
);
|
||||||
bgfx::setUniform(lights[0].u_lightMtx, lightMtx);
|
bgfx::setUniform(lights[0].u_lightMtx, lightMtx);
|
||||||
bgfxutils::meshSubmit (
|
entities[i]->mSkeletonMeshes.GetMesh(j)->Submit(
|
||||||
entities[i]->mesh.meshes[j]->mBgfxMesh,
|
|
||||||
&s_renderStates[RenderState::ShadowMap],
|
&s_renderStates[RenderState::ShadowMap],
|
||||||
1,
|
entities[i]->mSkeletonMeshes.GetBoneMatrix(j).data()
|
||||||
entities[i]->mesh.meshMatrices[j].data()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// scene pass
|
// 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(
|
bx::mtxMul(
|
||||||
lightMtx,
|
lightMtx,
|
||||||
entities[i]->mesh.meshMatrices[j].data(),
|
entities[i]->mSkeletonMeshes.GetBoneMatrix(j).data(),
|
||||||
lights[0].mtxShadow
|
lights[0].mtxShadow
|
||||||
);
|
);
|
||||||
|
|
||||||
// compute world position of the light
|
// compute world position of the light
|
||||||
Vector4f light_pos =
|
Vector4f light_pos =
|
||||||
entities[i]->mesh.meshMatrices[j]
|
entities[i]->mSkeletonMeshes.GetBoneMatrix(j)
|
||||||
* SimpleMath::Map<Vector4f>(lights[0].pos, 4, 1);
|
* SimpleMath::Map<Vector4f>(lights[0].pos, 4, 1);
|
||||||
|
|
||||||
bgfx::setUniform(lights[0].u_lightPos, light_pos.data());
|
bgfx::setUniform(lights[0].u_lightPos, light_pos.data());
|
||||||
bgfx::setUniform(lights[0].u_lightMtx, lightMtx);
|
|
||||||
bgfx::setUniform(u_color, entities[i]->color);
|
bgfx::setUniform(u_color, entities[i]->color);
|
||||||
bgfxutils::meshSubmit (
|
bgfx::setUniform(lights[0].u_lightMtx, lightMtx);
|
||||||
entities[i]->mesh.meshes[j]->mBgfxMesh,
|
entities[i]->mSkeletonMeshes.GetMesh(j)->Submit(
|
||||||
&s_renderStates[RenderState::Scene],
|
&s_renderStates[RenderState::Scene],
|
||||||
1,
|
entities[i]->mSkeletonMeshes.GetBoneMatrix(j).data()
|
||||||
entities[i]->mesh.meshMatrices[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
|
// render debug information
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <bgfx/bgfx.h>
|
#include <bgfx/bgfx.h>
|
||||||
|
|
||||||
|
#include "Globals.h"
|
||||||
#include "RenderUtils.h"
|
#include "RenderUtils.h"
|
||||||
|
|
||||||
struct Entity;
|
struct Entity;
|
||||||
|
@ -230,49 +231,82 @@ struct Transform {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MeshHierarchy {
|
struct Skeleton {
|
||||||
~MeshHierarchy()
|
/// index of the mParent. Children must have higher indices than heir
|
||||||
{
|
// mParents
|
||||||
for (Mesh* mesh : meshes) {
|
std::vector<int> mParent;
|
||||||
delete mesh;
|
/// Transforms relative to their mParents.
|
||||||
}
|
std::vector<Transform> mLocalTransforms;
|
||||||
}
|
|
||||||
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;
|
|
||||||
/// Absolute transforms.
|
/// Absolute transforms.
|
||||||
std::vector<Matrix44f> meshMatrices;
|
std::vector<Matrix44f> mBoneMatrices;
|
||||||
|
|
||||||
void addMesh(
|
int AddBone(
|
||||||
const int parent_idx,
|
const int parent_index,
|
||||||
const Transform& transform,
|
const Transform& transform
|
||||||
Mesh* mesh) {
|
) {
|
||||||
assert (parent_idx == -1 || parent_idx < parent.size());
|
assert (parent_index == -1 || parent_index < mParent.size());
|
||||||
parent.push_back(parent_idx);
|
mParent.push_back(parent_index);
|
||||||
localTransforms.push_back(transform);
|
mLocalTransforms.push_back(transform);
|
||||||
meshes.push_back(mesh);
|
|
||||||
|
|
||||||
if (parent_idx != -1) {
|
if (parent_index != -1) {
|
||||||
meshMatrices.push_back(transform.toMatrix() * meshMatrices[parent_idx]);
|
mBoneMatrices.push_back(transform.toMatrix() * mBoneMatrices[parent_index]);
|
||||||
} else {
|
} 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 {
|
struct Entity {
|
||||||
Transform transform;
|
Transform mTransform;
|
||||||
float color[4];
|
Vector4f mColor;
|
||||||
MeshHierarchy mesh;
|
Skeleton mSkeleton;
|
||||||
|
SkeletonMeshes mSkeletonMeshes;
|
||||||
|
|
||||||
Entity() :
|
Entity() :
|
||||||
color { 1.f, 1.f, 1.f, 1.f }
|
mColor (1.f, 1.f, 1.f, 1.f ),
|
||||||
|
mSkeletonMeshes(mSkeleton)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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* Mesh::sCreateCuboid (float width, float height, float depth) {
|
||||||
Mesh* result = new Mesh();
|
Mesh* result = new Mesh();
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ struct Mesh {
|
||||||
~Mesh();
|
~Mesh();
|
||||||
void Update();
|
void Update();
|
||||||
void Merge (const Mesh& other, const Matrix44f &mat = Matrix44f::Identity());
|
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 *sCreateCuboid (float width, float height, float depth);
|
||||||
static Mesh *sCreateUVSphere (int rows, int segments, float radius = 1.0f);
|
static Mesh *sCreateUVSphere (int rows, int segments, float radius = 1.0f);
|
||||||
|
|
Loading…
Reference in New Issue