Commit bcc29328 by Kai Westerkamp

BONES

parent 20755150
...@@ -5,6 +5,8 @@ layout(location = 0) out vec3 color; ...@@ -5,6 +5,8 @@ layout(location = 0) out vec3 color;
in vec3 vCamPosition; in vec3 vCamPosition;
in vec3 vCamNormal; in vec3 vCamNormal;
in vec2 vUV; in vec2 vUV;
in vec4 debugout;
uniform sampler2D colorTexture; uniform sampler2D colorTexture;
uniform vec3 LightPos; uniform vec3 LightPos;
...@@ -40,6 +42,7 @@ vec3 phong(vec3 lightPos){ ...@@ -40,6 +42,7 @@ vec3 phong(vec3 lightPos){
void main(void) void main(void)
{ {
color = phong(LightPos); color = phong(LightPos);
//color = debugout.xyz;
//color = texture2D(colorTexture,vUV).xyz; //color = texture2D(colorTexture,vUV).xyz;
} }
...@@ -2,27 +2,44 @@ ...@@ -2,27 +2,44 @@
layout(location = 0) in vec3 Position; layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal; layout(location = 1) in vec3 Normal;
layout(location = 2) in vec2 UV; layout(location = 2) in vec2 UV;
layout(location = 2) in ivec4 BoneIDs; layout(location = 3) in ivec4 BoneIDs;
layout(location = 2) in vec4 Weights; layout(location = 4) in vec4 Weights;
out vec3 vCamPosition; out vec3 vCamPosition;
out vec3 vCamNormal; out vec3 vCamNormal;
out vec2 vUV; out vec2 vUV;
out vec4 debugout;
uniform mat4x4 MV; uniform mat4x4 MV;
uniform mat4x4 MVP; uniform mat4x4 MVP;
uniform mat3x3 N; uniform mat3x3 N;
uniform mat4x4 Bones[100];
void main(void) void main(void)
{ {
vCamPosition = vec4(MV*vec4(Position,1.0)).xyz;
debugout = vec4(BoneIDs)/60;
debugout = Weights;
//debugout = vec4(1);
mat4x4 BoneTransform = Bones[BoneIDs[0]] * Weights[0];
BoneTransform += Bones[BoneIDs[1]] * Weights[1];
BoneTransform += Bones[BoneIDs[2]] * Weights[2];
BoneTransform += Bones[BoneIDs[3]] * Weights[3];
vec4 Pos = BoneTransform*vec4(Position,1.0);
//Pos = vec4(Position,1.0);
vCamPosition = vec4(MV*Pos).xyz;
vCamNormal = N*Normal; vCamNormal = N*Normal;
vUV = UV; vUV = UV;
gl_Position = MVP * vec4(Position,1.0); gl_Position = MVP * Pos;
} }
......
#include "mesh.h" #include "mesh.h"
void Vertex::AddBoneData(uint BoneID, float Weight){ void Vertex::AddBoneData(uint BoneID, float Weight){
for (int i = 0 ; i < 4 ; i++) { for (int i = 0 ; i < 4 ; i++) {
if (weights[i] == 0.0) { if (weights[i] == 0.0) {
IDs[i] = BoneID; IDs[i] = BoneID;
weights[i] = Weight; weights[i] = Weight;
//qDebug()<<"Add"<<i<<BoneID<<Weight<<pos;
return; return;
} }
} }
qCritical()<<"More tahn 4 Bones at Vertex"; qCritical()<<"More tahn 4 Bones at Vertex"<<pos<<BoneID<<Weight<<"added:"
<<IDs[0]<<weights[0]<<IDs[1]<<weights[1]<<IDs[2]<<weights[2]<<IDs[3]<<weights[3];
} }
Mesh::MeshEntry::MeshEntry() Mesh::MeshEntry::MeshEntry()
...@@ -64,15 +67,17 @@ Mesh::Mesh(QOpenGLFunctions_4_3_Core *f,QString fileName) ...@@ -64,15 +67,17 @@ Mesh::Mesh(QOpenGLFunctions_4_3_Core *f,QString fileName)
{ {
loaded = false; loaded = false;
this->f =f; this->f =f;
Assimp::Importer importer; numberOfBones = 0;
this->scene= importer.ReadFile(fileName.toStdString(), scene = NULL;
//aiProcess_CalcTangentSpace | scene= importer.ReadFile(fileName.toStdString(),
aiProcess_GenSmoothNormals | //aiProcess_CalcTangentSpace |
//aiProcess_JoinIdenticalVertices | aiProcess_GenSmoothNormals |
//aiProcess_SortByPType | //aiProcess_JoinIdenticalVertices |
// ? aiProcess_FlipUVs | //aiProcess_SortByPType |
aiProcess_Triangulate // ? aiProcess_FlipUVs |
); aiProcess_Triangulate
);
qDebug()<<"File Read"; qDebug()<<"File Read";
if( !scene) if( !scene)
{ {
...@@ -101,6 +106,7 @@ Mesh::Mesh(QOpenGLFunctions_4_3_Core *f,QString fileName) ...@@ -101,6 +106,7 @@ Mesh::Mesh(QOpenGLFunctions_4_3_Core *f,QString fileName)
for (int i = 0 ; i < entries.size() ; i++) { for (int i = 0 ; i < entries.size() ; i++) {
aiMesh* meshEntry = scene->mMeshes[i]; aiMesh* meshEntry = scene->mMeshes[i];
initMeshEntry(i, meshEntry); initMeshEntry(i, meshEntry);
} }
} else{ } else{
qWarning()<<"No Mesh found"; qWarning()<<"No Mesh found";
...@@ -115,7 +121,7 @@ Mesh::Mesh(QOpenGLFunctions_4_3_Core *f,QString fileName) ...@@ -115,7 +121,7 @@ Mesh::Mesh(QOpenGLFunctions_4_3_Core *f,QString fileName)
//TODO init Nodes //TODO init Nodes
if(scene->mRootNode != NULL) if(scene->mRootNode != NULL)
{ {
initNode(scene, scene->mRootNode, rootNode); initNode(scene, scene->mRootNode, rootNode, QString());
} else { } else {
rootNode.transformation.setToIdentity(); rootNode.transformation.setToIdentity();
rootNode.children.resize(0); rootNode.children.resize(0);
...@@ -139,25 +145,30 @@ Mesh::Mesh(QOpenGLFunctions_4_3_Core *f,QString fileName) ...@@ -139,25 +145,30 @@ Mesh::Mesh(QOpenGLFunctions_4_3_Core *f,QString fileName)
} }
} }
void Mesh::initNode(const aiScene *scene, aiNode *node, Node &newNode){ void Mesh::initNode(const aiScene *scene, aiNode *node, Node &newNode,QString debugoffset){
newNode.name = node->mName.length != 0 ? node->mName.C_Str() : ""; newNode.name = node->mName.length != 0 ? node->mName.C_Str() : "";
newNode.transformation = QMatrix4x4(node->mTransformation[0]); newNode.transformation = QMatrix4x4(node->mTransformation[0]);
newNode.meshes.resize(node->mNumMeshes); newNode.meshes.resize(node->mNumMeshes);
bool debug = false;
if(debug) qDebug()<<debugoffset.toStdString().c_str() << "NodeName" << newNode.name;
if(boneMap.find(newNode.name) != boneMap.end()){
if(debug) qDebug()<<debugoffset.toStdString().c_str() << "hasBone";
}
qDebug() << "NodeName" << newNode.name; if(debug) qDebug()<<debugoffset.toStdString().c_str() << " NumMeshes" << newNode.meshes.size();
qDebug() << " NumMeshes" << newNode.meshes.size();
for(uint i = 0; i < node->mNumMeshes; ++i) for(uint i = 0; i < node->mNumMeshes; ++i)
{ {
newNode.meshes[i] = node->mMeshes[i]; newNode.meshes[i] = node->mMeshes[i];
qDebug() << " MeshName" << entries[newNode.meshes[i]].name; if(debug) qDebug()<<debugoffset.toStdString().c_str() << " MeshName" << entries[newNode.meshes[i]].name;
} }
qDebug() << " NumChildren" << node->mNumChildren; if(debug) qDebug()<<debugoffset.toStdString().c_str() << " NumChildren" << node->mNumChildren;
QString newDebug = QString(debugoffset).append(" ");
for(uint i = 0; i < node->mNumChildren; ++i) for(uint i = 0; i < node->mNumChildren; ++i)
{ {
newNode.children.push_back(Node()); newNode.children.push_back(Node());
initNode(scene, node->mChildren[i], newNode.children[i]); initNode(scene, node->mChildren[i], newNode.children[i],newDebug);
} }
} }
...@@ -232,11 +243,126 @@ void Mesh::initMeshEntry(int index, aiMesh * entry){ ...@@ -232,11 +243,126 @@ void Mesh::initMeshEntry(int index, aiMesh * entry){
Indices.push_back(face.mIndices[2]); Indices.push_back(face.mIndices[2]);
} }
entries[index].init(f,Vertices, Indices);
entries[index].name = entry->mName.length != 0 ? entry->mName.C_Str() : "";
entries[index].name = entry->mName.length != 0 ? entry->mName.C_Str() : "";
entries[index].materialIndex = entry->mMaterialIndex; entries[index].materialIndex = entry->mMaterialIndex;
qDebug()<<"Loaded Mesh:"<<entries[index].name; qDebug()<<"Loaded Mesh:"<<entries[index].name;
if(entry->HasBones()){
for(uint i = 0; i< entry->mNumBones; i++){
int index = 0;
QString BoneName = QString(entry->mBones[i]->mName.data);
if (boneMap.find(BoneName) == boneMap.end()) {
// Allocate an index for a new bone
index = numberOfBones;
numberOfBones++;
BoneInfo bi;
bones.push_back(bi);
bones[index].BoneOffset = QMatrix4x4(entry->mBones[i]->mOffsetMatrix[0]);
boneMap[BoneName] = index;
}
else {
index = boneMap[BoneName];
}
for (uint j = 0 ; j < entry->mBones[i]->mNumWeights ; j++) {
uint VertexID = entry->mBones[i]->mWeights[j].mVertexId;
float Weight = entry->mBones[i]->mWeights[j].mWeight;
Vertices[VertexID].AddBoneData(index, Weight);
}
}
}
entries[index].init(f,Vertices, Indices);
}
void Mesh::updateBoneTransform(float TimeInSeconds){
if(!scene)
return;
const aiAnimation* animation = scene->mAnimations[0];
//TODO calc time and get Anaimation;
updateBoneHeirachy(0.0,animation,this->rootNode,QMatrix4x4());
}
void Mesh::updateBoneHeirachy(float AnimTime,const aiAnimation* animation, Node node, QMatrix4x4 parentTransform){
QMatrix4x4 nodeTransformation = node.transformation;
//Find channel
const aiNodeAnim *nodeAnimation = findAnimOfNode(animation,node.name);
//calc Tcurrent Trasnformation;
if (nodeAnimation) {
QVector3D scale = calcInterpolatedScaling(AnimTime,nodeAnimation);
QQuaternion rot = calcInterpolatedRotation(AnimTime,nodeAnimation);
QVector3D trans = calcInterpolatedTranslation(AnimTime,nodeAnimation);
//qDebug()<<"calc"<<scale<<rot<<trans;
nodeTransformation.setToIdentity();
nodeTransformation.translate(trans);
nodeTransformation.rotate(rot);
nodeTransformation.scale(scale);
}
//Update Bone and children
QMatrix4x4 GlobalTransform = parentTransform * nodeTransformation;
if (boneMap.find(node.name) != boneMap.end()) {
int index = boneMap[node.name];
bones[index].FinalTransformation = globalInverseTransform * GlobalTransform * bones[index].BoneOffset;
}
for(int i = 0; i < node.children.size(); ++i)
{
updateBoneHeirachy(AnimTime,animation,node.children[i],GlobalTransform);
}
}
const aiNodeAnim* Mesh::findAnimOfNode(const aiAnimation* animation, QString NodeName){
for (uint i = 0 ; i < animation->mNumChannels ; i++) {
const aiNodeAnim* nodeanim = animation->mChannels[i];
if (QString(nodeanim->mNodeName.data) == NodeName) {
return nodeanim;
}
}
return NULL;
}
QVector3D Mesh::calcInterpolatedScaling(float AnimTime,const aiNodeAnim *nodeAnimation){
int index = nodeAnimation->mNumScalingKeys/2;
//index = 0;
aiVector3D scale = nodeAnimation->mScalingKeys[index].mValue;
return QVector3D(scale.x,scale.y,scale.z);
}
QQuaternion Mesh::calcInterpolatedRotation(float AnimTime,const aiNodeAnim *nodeAnimation){
int index = nodeAnimation->mNumRotationKeys/2;
// index = 0;
aiQuaternion quat = nodeAnimation->mRotationKeys[index].mValue;
return QQuaternion(quat.w,quat.x,quat.y,quat.z);
}
QVector3D Mesh::calcInterpolatedTranslation(float AnimTime, const aiNodeAnim *nodeAnimation){
int index = nodeAnimation->mNumScalingKeys/2;
// index = 0;
aiVector3D pos = nodeAnimation->mPositionKeys[index].mValue;
return QVector3D(pos.x,pos.y,pos.z);
} }
...@@ -254,10 +380,15 @@ void Mesh::render(QOpenGLShaderProgram *shader, QMatrix4x4 V,QMatrix4x4 P){ ...@@ -254,10 +380,15 @@ void Mesh::render(QOpenGLShaderProgram *shader, QMatrix4x4 V,QMatrix4x4 P){
f->glEnableVertexAttribArray(boneIndex); f->glEnableVertexAttribArray(boneIndex);
f->glEnableVertexAttribArray(boneweightIndex); f->glEnableVertexAttribArray(boneweightIndex);
QMatrix4x4 M;
M.setToIdentity();
renderNode(shader,rootNode,V,P,M); updateBoneTransform(0.0);
QVector<QMatrix4x4> boneTransforms = QVector<QMatrix4x4>(bones.size());
for(int i = 0; i < bones.size(); i++){
boneTransforms[i] = bones[i].FinalTransformation;
}
shader->setUniformValueArray("Bones",boneTransforms.constData(),bones.size());
renderNode(shader,rootNode,V,P,QMatrix4x4());
f->glDisableVertexAttribArray(positionIndex); f->glDisableVertexAttribArray(positionIndex);
...@@ -282,7 +413,7 @@ void Mesh::renderNode(QOpenGLShaderProgram *shader, Node &node, QMatrix4x4 V,QMa ...@@ -282,7 +413,7 @@ void Mesh::renderNode(QOpenGLShaderProgram *shader, Node &node, QMatrix4x4 V,QMa
shader->setUniformValue("N",normalMat); shader->setUniformValue("N",normalMat);
for (int i = 0 ; i < node.meshes.size() ; i++) { for (int i = 0 ; i < node.meshes.size() ; i++) {
int index = node.meshes[i]; int index = node.meshes[i];
//load Material //load Material
renderMesh(shader, index); renderMesh(shader, index);
} }
...@@ -309,10 +440,10 @@ void Mesh::renderMesh(QOpenGLShaderProgram *shader, int index) ...@@ -309,10 +440,10 @@ void Mesh::renderMesh(QOpenGLShaderProgram *shader, int index)
// Draw Vertex Array // Draw Vertex Array
f->glBindBuffer(GL_ARRAY_BUFFER, entries[index].VB); f->glBindBuffer(GL_ARRAY_BUFFER, entries[index].VB);
f->glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); f->glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
f->glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12); //3*4 f->glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12); //12
f->glVertexAttribPointer(uvIndex, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)24); //(3+3)*4 f->glVertexAttribPointer(uvIndex, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)24); // 12+12
f->glVertexAttribIPointer(boneIndex, 4, GL_INT, sizeof(Vertex), (const GLvoid*)32); //(3+3+2)*4 f->glVertexAttribIPointer(boneIndex, 4, GL_INT, sizeof(Vertex), (const GLvoid*)32); // 12+12+8
f->glVertexAttribPointer(boneweightIndex, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)48); //(3+3+2+4)*4 f->glVertexAttribPointer(boneweightIndex, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)48); //12+12+8+16
f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, entries[index].IB); f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, entries[index].IB);
f->glDrawElements(GL_TRIANGLES, entries[index].numIndex, GL_UNSIGNED_INT, 0); f->glDrawElements(GL_TRIANGLES, entries[index].numIndex, GL_UNSIGNED_INT, 0);
......
...@@ -23,21 +23,20 @@ struct Vertex ...@@ -23,21 +23,20 @@ struct Vertex
uint IDs[4]; uint IDs[4];
float weights[4]; float weights[4];
Vertex() { Vertex(){}
Vertex(const QVector3D& pos, const QVector3D& normal, const QVector2D& tex)
{
for(int i = 0; i < 4; i++){ for(int i = 0; i < 4; i++){
IDs[i] = 0; IDs[i] = 0;
weights[i] = 0; weights[i] = 0;
} }
}
Vertex(const QVector3D& pos, const QVector3D& normal, const QVector2D& tex)
{
this->pos = pos; this->pos = pos;
this->tex = tex; this->tex = tex;
this->normal = normal; this->normal = normal;
} }
void AddBoneData(uint BoneID, float Weight); void AddBoneData(uint BoneID, float Weight);
}; };
class Mesh class Mesh
...@@ -86,6 +85,18 @@ private: ...@@ -86,6 +85,18 @@ private:
QVector3D Intensity; QVector3D Intensity;
}; };
struct BoneInfo
{
QMatrix4x4 BoneOffset;
QMatrix4x4 FinalTransformation;
BoneInfo()
{
BoneOffset.setToIdentity();
FinalTransformation.setToIdentity();
}
};
struct Node struct Node
{ {
Node(); Node();
...@@ -96,18 +107,33 @@ private: ...@@ -96,18 +107,33 @@ private:
}; };
const aiScene *scene; const aiScene *scene;
Assimp::Importer importer;
QMatrix4x4 globalInverseTransform; QMatrix4x4 globalInverseTransform;
QVector<MeshEntry> entries; QVector<MeshEntry> entries;
QVector<MaterialInfo> materials; QVector<MaterialInfo> materials;
QVector<BoneInfo> bones;
QMap<QString,int> boneMap;
int numberOfBones;
Node rootNode; Node rootNode;
QOpenGLFunctions_4_3_Core *f; QOpenGLFunctions_4_3_Core *f;
bool loaded; bool loaded;
void initMeshEntry(int i,aiMesh * entry); void initMeshEntry(int i,aiMesh * entry);
void initMaterial(QString dir, unsigned int i, const aiMaterial* material); void initMaterial(QString dir, unsigned int i, const aiMaterial* material);
void initNode(const aiScene *scene, aiNode *node, Node &newNode); void initNode(const aiScene *scene, aiNode *node, Node &newNode, QString debugoffset);
void updateBoneTransform(float TimeInSeconds);
void updateBoneHeirachy(float AnimTime,const aiAnimation* animation, Node node, QMatrix4x4 parentTransform);
const aiNodeAnim *findAnimOfNode(const aiAnimation* animation, QString NodeName);
QVector3D calcInterpolatedScaling(float AnimTime,const aiNodeAnim *nodeAnimation);
QQuaternion calcInterpolatedRotation(float AnimTime,const aiNodeAnim *nodeAnimation);
QVector3D calcInterpolatedTranslation(float AnimTime, const aiNodeAnim *nodeAnimation);
void renderNode(QOpenGLShaderProgram *shader, Node &node, QMatrix4x4 V,QMatrix4x4 P,QMatrix4x4 M); void renderNode(QOpenGLShaderProgram *shader, Node &node, QMatrix4x4 V,QMatrix4x4 P,QMatrix4x4 M);
void renderMesh(QOpenGLShaderProgram *shader, int index); void renderMesh(QOpenGLShaderProgram *shader, int index);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment