mirror of
https://github.com/antopilo/Nuake.git
synced 2026-09-04 11:35:06 +03:00
Properly transform bones
This commit is contained in:
@@ -359,6 +359,8 @@ namespace Nuake
|
||||
gBufferSkinnedMeshShader->SetUniformMat4f("u_Projection", mProjection);
|
||||
gBufferSkinnedMeshShader->SetUniformMat4f("u_View", mView);
|
||||
|
||||
RenderCommand::Disable(RendererEnum::FACE_CULL);
|
||||
|
||||
// Skinned Models
|
||||
const uint32_t entityIdUniformLocation = gBufferSkinnedMeshShader->FindUniformLocation("u_EntityID");
|
||||
const uint32_t modelMatrixUniformLocation = gBufferSkinnedMeshShader->FindUniformLocation("u_Model");
|
||||
@@ -367,22 +369,19 @@ namespace Nuake
|
||||
for (auto e : skinnedModelView)
|
||||
{
|
||||
auto [transform, mesh, visibility] = skinnedModelView.get<TransformComponent, SkinnedModelComponent, VisibilityComponent>(e);
|
||||
auto& meshResource = mesh.ModelResource;
|
||||
|
||||
if (mesh.ModelResource && visibility.Visible)
|
||||
if (meshResource && visibility.Visible)
|
||||
{
|
||||
auto& rootBoneNode = meshResource->GetSkeletonRootNode();
|
||||
|
||||
SetSkeletonBoneTransformRecursive(rootBoneNode, gBufferSkinnedMeshShader);
|
||||
|
||||
for (auto& m : mesh.ModelResource->GetMeshes())
|
||||
{
|
||||
m->GetMaterial()->Bind(gBufferSkinnedMeshShader);
|
||||
|
||||
uint32_t boneId = 0;
|
||||
for (auto& b : m->GetBones())
|
||||
{
|
||||
const std::string boneMatrixUniformName = "u_FinalBonesMatrice[" + std::to_string(boneId) + "]";
|
||||
gBufferSkinnedMeshShader->SetUniformMat4f(boneMatrixUniformName, b.Offset);
|
||||
boneId++;
|
||||
}
|
||||
|
||||
gBufferSkinnedMeshShader->SetUniformMat4f(modelMatrixUniformLocation, transform.GetGlobalTransform());
|
||||
gBufferSkinnedMeshShader->SetUniformMat4f(modelMatrixUniformLocation, Matrix4(1.0f));
|
||||
gBufferSkinnedMeshShader->SetUniform1i(entityIdUniformLocation, (uint32_t)e + 1);
|
||||
m->Draw(gBufferSkinnedMeshShader, true);
|
||||
}
|
||||
@@ -452,4 +451,22 @@ namespace Nuake
|
||||
void SceneRenderer::PostProcessPass(const Scene& scene)
|
||||
{
|
||||
}
|
||||
|
||||
void SceneRenderer::SetSkeletonBoneTransformRecursive(SkeletonNode& skeletonNode, Shader* shader)
|
||||
{
|
||||
auto scene = Engine::GetCurrentScene();
|
||||
for (auto& child : skeletonNode.Children)
|
||||
{
|
||||
if (auto entity = scene->GetEntity(child.Name); entity.GetHandle() != -1)
|
||||
{
|
||||
const Matrix4& globalBoneTransform = entity.GetComponent<TransformComponent>().GetGlobalTransform();
|
||||
const Matrix4 bonespaceTransform = globalBoneTransform * child.Offset;
|
||||
const std::string boneMatrixUniformName = "u_FinalBonesMatrice[" + std::to_string(child.Id) + "]";
|
||||
shader->SetUniformMat4f(boneMatrixUniformName, bonespaceTransform);
|
||||
}
|
||||
|
||||
SetSkeletonBoneTransformRecursive(child, shader);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,5 +39,7 @@ namespace Nuake
|
||||
void GBufferPass(Scene& scene);
|
||||
void ShadingPass(Scene& scene);
|
||||
void PostProcessPass(const Scene& scene);
|
||||
|
||||
void SetSkeletonBoneTransformRecursive(SkeletonNode& skeletonNode, Shader* shader);
|
||||
};
|
||||
}
|
||||
@@ -50,8 +50,13 @@ namespace Nuake
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
std::unordered_map<std::string, uint32_t> bonesNameIDMap;
|
||||
Ref<SkinnedModel> ModelLoader::LoadSkinnedModel(const std::string& path, bool absolute)
|
||||
{
|
||||
bonesNameIDMap = std::unordered_map<std::string, uint32_t>();
|
||||
m_BoneMap = std::unordered_map<std::string, Bone>();
|
||||
|
||||
m_SkinnedMeshes.clear();
|
||||
Ref<SkinnedModel> model = CreateRef<SkinnedModel>(path);
|
||||
|
||||
@@ -137,7 +142,6 @@ namespace Nuake
|
||||
auto& indices = ProcessIndices(node);
|
||||
auto& material = ProcessMaterials(scene, node);
|
||||
auto& bones = std::vector<Bone>();
|
||||
auto& bonesMap = std::unordered_map<std::string, Bone>();
|
||||
|
||||
if (node->HasBones())
|
||||
{
|
||||
@@ -148,7 +152,7 @@ namespace Nuake
|
||||
const std::string& boneName = bone->mName.C_Str();
|
||||
|
||||
int32_t boneId = -1;
|
||||
if (bonesMap.find(boneName) == bonesMap.end())
|
||||
if (m_BoneMap.find(boneName) == m_BoneMap.end())
|
||||
{
|
||||
boneId = boneCounter;
|
||||
boneCounter++;
|
||||
@@ -157,11 +161,12 @@ namespace Nuake
|
||||
newBone.Offset = ConvertMatrixToGLMFormat(bone->mOffsetMatrix);
|
||||
bones.push_back(newBone);
|
||||
|
||||
bonesMap[boneName] = newBone;
|
||||
bonesNameIDMap[boneName] = boneId;
|
||||
m_BoneMap[boneName] = newBone;
|
||||
}
|
||||
else
|
||||
{
|
||||
boneId = bonesMap[boneName].Id;
|
||||
boneId = m_BoneMap[boneName].Id;
|
||||
}
|
||||
|
||||
assert(boneId != -1);
|
||||
@@ -171,7 +176,7 @@ namespace Nuake
|
||||
{
|
||||
aiVertexWeight vertexWeight = bone->mWeights[j];
|
||||
const uint32_t vertexWeightVertexId = vertexWeight.mVertexId;
|
||||
|
||||
|
||||
SetVertexBoneData(vertices[vertexWeightVertexId], boneId, vertexWeight.mWeight);
|
||||
|
||||
//BoneVertexWeight boneVertexWeight
|
||||
@@ -215,20 +220,20 @@ namespace Nuake
|
||||
auto vertices = std::vector<Vertex>();
|
||||
for (uint32_t i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
Vertex vertex;
|
||||
Vertex vertex {};
|
||||
|
||||
Vector3 current;
|
||||
|
||||
// Position
|
||||
current.x = mesh->mVertices[i].x;
|
||||
current.y = mesh->mVertices[i].z;
|
||||
current.z = mesh->mVertices[i].y;
|
||||
current.y = mesh->mVertices[i].y;
|
||||
current.z = mesh->mVertices[i].z;
|
||||
vertex.position = current;
|
||||
|
||||
// Normals
|
||||
current.x = mesh->mNormals[i].x;
|
||||
current.y = mesh->mNormals[i].z;
|
||||
current.z = mesh->mNormals[i].y;
|
||||
current.y = mesh->mNormals[i].y;
|
||||
current.z = mesh->mNormals[i].z;
|
||||
vertex.normal = current;
|
||||
|
||||
// Tangents
|
||||
@@ -343,6 +348,8 @@ namespace Nuake
|
||||
dest.Name = src->mName.data;
|
||||
dest.Transform = ConvertMatrixToGLMFormat(src->mTransformation);
|
||||
dest.ChildrenCount = src->mNumChildren;
|
||||
dest.Id = bonesNameIDMap[dest.Name];
|
||||
dest.Offset = m_BoneMap[dest.Name].Offset;
|
||||
|
||||
for (uint32_t i = 0; i < dest.ChildrenCount; i++)
|
||||
{
|
||||
@@ -358,6 +365,7 @@ namespace Nuake
|
||||
SkeletonNode bone;
|
||||
bone.Name = src->mName.C_Str();
|
||||
bone.Transform = ConvertMatrixToGLMFormat(src->mTransformation);
|
||||
bone.Id = bonesNameIDMap[bone.Name];
|
||||
|
||||
des.ChildrenCount++;
|
||||
des.Children.push_back(bone);
|
||||
|
||||
@@ -33,6 +33,8 @@ namespace Nuake
|
||||
std::string modelDir;
|
||||
std::vector<Ref<Mesh>> m_Meshes;
|
||||
std::vector<Ref<SkinnedMesh>> m_SkinnedMeshes;
|
||||
std::unordered_map<std::string, uint32_t> m_BoneIDMap;
|
||||
std::unordered_map<std::string, Bone> m_BoneMap;
|
||||
|
||||
void ProcessNode(aiNode* node, const aiScene* scene);
|
||||
Ref<Mesh> ProcessMesh(aiMesh* node, const aiScene* scene);
|
||||
@@ -52,27 +54,14 @@ namespace Nuake
|
||||
|
||||
static inline Matrix4 ConvertMatrixToGLMFormat(const aiMatrix4x4& from)
|
||||
{
|
||||
Matrix4 result;
|
||||
for (auto i = 0; i < 3; i++)
|
||||
{
|
||||
for (auto j = 0; j < 3; j++)
|
||||
{
|
||||
result[i][j] = from[i][j];
|
||||
}
|
||||
}
|
||||
Matrix4 to;
|
||||
|
||||
// The rest would be zero, other than the 4,4.
|
||||
result[0][3] = 0.0f;
|
||||
result[1][3] = 0.0f;
|
||||
result[2][3] = 0.0f;
|
||||
to[0][0] = from.a1; to[0][1] = from.b1; to[0][2] = from.c1; to[0][3] = from.d1;
|
||||
to[1][0] = from.a2; to[1][1] = from.b2; to[1][2] = from.c2; to[1][3] = from.d2;
|
||||
to[2][0] = from.a3; to[2][1] = from.b3; to[2][2] = from.c3; to[2][3] = from.d3;
|
||||
to[3][0] = from.a4; to[3][1] = from.b4; to[3][2] = from.c4; to[3][3] = from.d4;
|
||||
|
||||
result[3][0] = 0.0f;
|
||||
result[3][1] = 0.0f;
|
||||
result[3][2] = 0.0f;
|
||||
|
||||
result[3][3] = 1.0f;
|
||||
|
||||
return result;
|
||||
return to;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -7,8 +7,10 @@ namespace Nuake
|
||||
struct SkeletonNode
|
||||
{
|
||||
Matrix4 Transform;
|
||||
Matrix4 Offset;
|
||||
std::string Name;
|
||||
int ChildrenCount;
|
||||
std::vector<SkeletonNode> Children;
|
||||
int32_t Id = -1;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user