diff --git a/bone.cpp b/bone.cpp index 7920757..02f7eb3 100644 --- a/bone.cpp +++ b/bone.cpp @@ -3,7 +3,28 @@ using namespace std; namespace vb01{ - Bone::Bone(string name, Vector3 pos) : Node(pos){ + Bone::Bone(string name, Vector3 axis[3], Vector3 pos,Quaternion rot, Vector3 scale) : Node(pos,rot,scale){ this->name=name; + this->restPos=pos; + this->restRot=rot; + this->restScale=scale; + for(int i=0;i<3;i++) + this->initAxis[i]=axis[i]; + //lookAt(axis[1],axis[2],parent); + } + + void Bone::setPosePos(Vector3 p){ + this->posePos=p; + setPosition(restPos+posePos); + } + + void Bone::setPoseRot(Quaternion r){ + this->poseRot=r; + setOrientation(poseRot*restRot); + } + + void Bone::setPoseScale(Vector3 s){ + this->poseScale=s; + setScale(restScale+poseScale); } } diff --git a/bone.h b/bone.h index 8866cd3..215e174 100644 --- a/bone.h +++ b/bone.h @@ -7,11 +7,22 @@ namespace vb01{ class Bone : public Node{ public: - Bone(std::string,Vector3=Vector3::VEC_ZERO); - std::string getName(){return name;} + Bone(std::string,Vector3[3],Vector3=Vector3::VEC_ZERO,Quaternion=Quaternion::QUAT_W,Vector3=Vector3::VEC_ZERO); + void setPosePos(Vector3 p); + void setPoseRot(Quaternion r); + void setPoseScale(Vector3 s); + inline Vector3 getInitAxis(int i){return initAxis[i];} + inline std::string getName(){return name;} + inline Vector3 getRestPos(){return restPos;} + inline Quaternion getRestRot(){return restRot;} + inline Vector3 getRestScale(){return restScale;} + inline Vector3 getPosePos(){return posePos;} + inline Quaternion getPoseRot(){return poseRot;} + inline Vector3 getPoseScale(){return poseScale;} private: std::string name; - Vector3 yAxis,zAxis; + Vector3 initAxis[3],restPos,posePos=Vector3::VEC_ZERO,restScale,poseScale=Vector3::VEC_IJK; + Quaternion restRot,poseRot=Quaternion::QUAT_W; }; } diff --git a/mesh.cpp b/mesh.cpp index e066e62..cffca3b 100755 --- a/mesh.cpp +++ b/mesh.cpp @@ -14,15 +14,13 @@ using namespace std; using namespace glm; namespace vb01{ - Mesh::Mesh(){ - - } + Mesh::Mesh(){} - Mesh::Mesh(Vertex *vertices,unsigned int *indices,int numTris,VertexGroup *vertexGroups,int numVertexGroups,ShapeKey *shapeKeys,int numShapeKeys,string name){ + Mesh::Mesh(Vertex *vertices,unsigned int *indices,int numTris,string *vertexGroups,int numVertexGroups,string *shapeKeys,int numShapeKeys,string name){ this->vertices=vertices; this->indices=indices; this->numTris=numTris; - this->groups=vertexGroups; + this->vertexGroups=vertexGroups; this->numVertexGroups=numVertexGroups; this->shapeKeys=shapeKeys; this->numShapeKeys=numShapeKeys; @@ -47,6 +45,8 @@ namespace vb01{ } void Mesh::construct(){ + int width=Root::getSingleton()->getWidth(); + u32 RBO; string basePath="../../vb01/depthMap."; environmentShader=new Shader(basePath+"vert",basePath+"frag",basePath+"geo"); @@ -71,23 +71,35 @@ namespace vb01{ glGenVertexArrays(1,&VAO); glGenBuffers(1,&VBO); glGenBuffers(1,&EBO); - + + u32 base=sizeof(float); + u32 size=(14+3*numShapeKeys)*base; + size=sizeof(Vertex); + //size=(18)*sizeof(float)+sizeof(Vector3*); + //cout<update(); Shader *shader=material->getShader(); + shader->setBool(castShadow,"castShadow"); + shader->setBool(skeleton,"animated"); shader->setBool(false,"environment"); shader->setMat4(view,"view"); shader->setMat4(proj,"proj"); shader->setVec3(camPos,"camPos"); shader->setMat4(model,"model"); + + if(skeleton){ + shader->editShader(Shader::VERTEX_SHADER,2,"const int numBones="+to_string(skeleton->getNumBones())+";"); + shader->editShader(Shader::VERTEX_SHADER,3,"const int numVertGroups="+to_string(numVertexGroups)+";"); + + Node *modelNode = skeleton->getRootBone()->getParent(); + for(int i=0;igetNumBones();i++){ + Bone *bone = skeleton->getBone(i), *parent = (Bone*)bone->getParent(); + Vector3 boneAxis[]{ + bone->getInitAxis(0), + bone->getInitAxis(1), + bone->getInitAxis(2) + }; + Vector3 posePos = bone->getPosePos(); + Quaternion poseRot = bone->getPoseRot(); + Vector3 trans = boneAxis[0]*posePos.x+boneAxis[1]*posePos.y+boneAxis[2]*posePos.z; + Vector3 scale = bone->getPoseScale(); + Vector3 bonePos = (bone->getRestPos()); + //bonePos = modelNode->globalToLocalPosition(bonePos); + + int vertGroupId = -1,parentId = -1; + for(int j=0;jgetName() == vertexGroups[j]) + vertGroupId = j; + for(int j = 0;j < skeleton->getNumBones();j++) + if(skeleton->getBone(j) == parent){ + parentId = j; + break; + } + + shader->setVec3(bonePos,"bones["+to_string(i)+"].pos"); + shader->setVec3(trans,"bones["+to_string(i)+"].trans"); + shader->setVec3(poseRot.getAxis(),"bones["+to_string(i)+"].rotAxis"); + shader->setFloat(poseRot.getAngle(),"bones["+to_string(i)+"].angle"); + shader->setVec3(scale,"bones["+to_string(i)+"].scale"); + shader->setInt(vertGroupId,"bones["+to_string(i)+"].vertGroup"); + shader->setInt(parentId,"bones["+to_string(i)+"].parent"); + } + } + if(reflect){ shader->setBool(reflect,"environmentMapEnabled"); root->getSkybox()->getMaterial()->getDiffuseMap(0)->select(4); environmentMap->select(4); } - if(skeleton){ - } + if(material->getType()==Material::MATERIAL_GUI){ shader->setVec2(Vector2((float)width,(float)height),"screen"); if(node) @@ -191,24 +244,4 @@ namespace vb01{ glPolygonMode(GL_FRONT_AND_BACK,wireframe?GL_LINE:GL_FILL); glDrawElements(GL_TRIANGLES,3*numTris,GL_UNSIGNED_INT,0); } - - Mesh::VertexGroup& Mesh::getVertexGroup(string name){ - int id=-1; - for(int i=0;imaterial=mat;} - VertexGroup& getVertexGroup(std::string); - ShapeKey& getShapeKey(std::string); inline void setNode(Node *node){this->node=node;} inline void setCastShadow(bool castShadow){this->castShadow=castShadow;} inline void setReflect(bool r){this->reflect=r;} @@ -62,7 +52,6 @@ namespace vb01{ Node *node=nullptr; std::vector meshes; std::string name=""; - int width=800; Skeleton *skeleton=nullptr; protected: Mesh(); @@ -70,8 +59,7 @@ namespace vb01{ bool staticVerts=true,castShadow=false,reflect=false,wireframe=false; Vertex *vertices; - VertexGroup *groups; - ShapeKey *shapeKeys; + std::string *vertexGroups=nullptr,*shapeKeys=nullptr; unsigned int *indices,VAO,VBO,EBO; int numTris,numVertexGroups=0,numShapeKeys=0; }; diff --git a/model.cpp b/model.cpp index 1f122fe..6f9d9ab 100755 --- a/model.cpp +++ b/model.cpp @@ -102,13 +102,13 @@ namespace vb01{ string animName=""; Bone *animBone=nullptr; - vector vertPos,vertNorm; const int numVertsPerFace=3; - int numVertPos=0,numFaces=0,vertId=0,faceId=0,groupId=-1,groupVertId=0,numGroups=0,numShapeKeys=0; + int numFaces=0,vertId=0,faceId=0,groupId=0,groupVertId=0,numGroups=0,numShapeKeys=0; Mesh::Vertex *vertices; u32 *indices; - Mesh::VertexGroup *groups=nullptr; - Mesh::ShapeKey *shapeKeys=nullptr; + vector vertPos,vertNorm; + vector vertWeights; + string *groups=nullptr,*shapeKeys=nullptr; while(getline(in,l)){ int colonId=-1; @@ -170,18 +170,36 @@ namespace vb01{ getLineData(postColon,data,numData); float length=atof(data[0].c_str()); - Vector3 pos=Vector3(atof(data[2].c_str()),atof(data[4].c_str()),-atof(data[3].c_str())); - Vector3 xAxis=Vector3(atof(data[5].c_str()),atof(data[7].c_str()),-atof(data[6].c_str())),yAxis=Vector3(atof(data[8].c_str()),atof(data[10].c_str()),-atof(data[9].c_str())),zAxis=xAxis.cross(yAxis); + Vector3 pos=Vector3(atof(data[2].c_str()),atof(data[3].c_str()),atof(data[4].c_str())); + Vector3 xAxis=Vector3(atof(data[5].c_str()),atof(data[6].c_str()),atof(data[6].c_str())); + Vector3 yAxis=Vector3(atof(data[8].c_str()),atof(data[9].c_str()),atof(data[10].c_str())); + Vector3 zAxis=xAxis.cross(yAxis); string parName=string(data[0].c_str()); Node *parent=skeleton->getBone(parName); - if(!parent) + if(!parent){ parent=this; + swap(xAxis.y,xAxis.z); + xAxis.z=-xAxis.z; + swap(yAxis.y,yAxis.z); + yAxis.z=-yAxis.z; + swap(zAxis.y,zAxis.z); + zAxis.z=-zAxis.z; + } - Bone *bone=new Bone(preColon); + Vector3 parAxis[]={ + parent->getLocalAxis(0), + parent->getLocalAxis(1), + parent->getLocalAxis(2) + }; + Vector3 boneAxis[3]={ + (parAxis[0]*xAxis.x+parAxis[1]*xAxis.y+parAxis[2]*xAxis.z).norm(), + (parAxis[0]*yAxis.x+parAxis[1]*yAxis.y+parAxis[2]*yAxis.z).norm(), + (parAxis[0]*zAxis.x+parAxis[1]*zAxis.y+parAxis[2]*zAxis.z).norm() + }; + Bone *bone=new Bone(preColon,boneAxis,pos); skeleton->addBone(bone,parent); - bone->setPosition(parent->globalToLocalPosition(pos)); - bone->lookAt(yAxis,zAxis,parent); + bone->lookAt(boneAxis[1],boneAxis[2],parent); break; } @@ -253,22 +271,22 @@ namespace vb01{ MeshStage meshStage; if(preColon=="vertices"){ - string data[2]; - getLineData(postColon,data,2); - numVertPos=atoi(data[0].c_str()); + const int numData=4; + string data[numData]; + getLineData(postColon,data,numData); numFaces=atoi(data[1].c_str()); + numGroups=atoi(data[2].c_str()); + vertices=new Mesh::Vertex[numFaces*numVertsPerFace]; + indices=new u32[numFaces*numVertsPerFace]; meshStage=VERTICES; continue; } else if(preColon=="faces"){ meshStage=FACES; - vertices=new Mesh::Vertex[numFaces*numVertsPerFace]; - indices=new u32[numFaces*numVertsPerFace]; continue; } else if(preColon=="groups"){ - numGroups=atoi(postColon.c_str()); - groups=new Mesh::VertexGroup[numGroups]; + groups=new string[numGroups]; meshStage=GROUPS; continue; } @@ -279,13 +297,35 @@ namespace vb01{ switch(meshStage){ { case VERTICES: - int numData=6; + int numData=10; string data[numData]; getLineData(l,data,numData); - Vector3 vp=Vector3(atof(data[0].c_str()),atof(data[2].c_str()),-atof(data[1].c_str())); - Vector3 vn=Vector3(atof(data[3].c_str()),atof(data[5].c_str()),-atof(data[4].c_str())); - vertPos.push_back(vp); - vertNorm.push_back(vn); + Vector3 vPos=Vector3(atof(data[0].c_str()),atof(data[2].c_str()),-atof(data[1].c_str())); + Vector3 vNorm=Vector3(atof(data[3].c_str()),atof(data[5].c_str()),-atof(data[4].c_str())); + float vWeights[]{ + atof(data[6].c_str()), + atof(data[7].c_str()), + atof(data[8].c_str()), + atof(data[9].c_str()) + }; + vertPos.push_back(vPos); + vertNorm.push_back(vNorm); + for(int i=0;i<4;i++) + vertWeights.push_back(vWeights[i]); + /* + Vector2 vertUv=Vector2(atof(data[5].c_str()),atof(data[6].c_str())); + Vector3 vertTan=Vector3(atof(data[7].c_str()),atof(data[9].c_str()),-atof(data[10].c_str())); + Vector3 vertBitan=Vector3(atof(data[11].c_str()),atof(data[13].c_str()),-atof(data[12].c_str())); + */ + /* + Mesh::Vertex vert; + vert.pos=vertPos; + vert.norm=vertNorm; + vert.uv=vertUv; + vert.tan=vertTan; + vert.biTan=vertBitan; + */ + //vertices[vertId]=vert; break; } { @@ -293,22 +333,26 @@ namespace vb01{ int numData=9; string data[numData]; getLineData(l,data,numData); - u32 index=atoi(data[0].c_str()); + int index=atoi(data[0].c_str()); Vector2 uv=Vector2(atof(data[1].c_str()),atof(data[2].c_str())); Vector3 tan=Vector3(atof(data[3].c_str()),atof(data[5].c_str()),-atof(data[4].c_str())); - Vector3 biTan=Vector3(atof(data[6].c_str()),atof(data[8].c_str()),-atof(data[7].c_str())); - /* - */ + Vector3 biTan=Vector3(atof(data[6].c_str()),atof(data[8].c_str()),-atof(data[7].c_str())); Mesh::Vertex vert; vert.pos=vertPos[index]; vert.norm=vertNorm[index]; - vert.uv=uv; vert.tan=tan; vert.biTan=biTan; + vert.uv=uv; + vert.weights[0]=vertWeights[index*4+0]; + vert.weights[1]=vertWeights[index*4+1]; + vert.weights[2]=vertWeights[index*4+2]; + vert.weights[3]=vertWeights[index*4+3]; + for(int i=0;i0){ - groups[groupId].vertices=new u32[numVerts]; - groups[groupId].weights=new float[numVerts]; - } - } else{ - int numData=2,vertId; - float weight; - string data[numData]; - getLineData(l,data,numData); - vertId=atoi(data[0].c_str()); - weight=atof(data[1].c_str()); - groups[groupId].vertices[groupVertId]=vertId; - groups[groupId].weights[groupVertId]=weight; - groupVertId++; + groups[groupId]=l; + groupId++; } break; } diff --git a/node.cpp b/node.cpp index c20e136..b27fba7 100755 --- a/node.cpp +++ b/node.cpp @@ -100,8 +100,15 @@ namespace vb01{ } void Node::lookAt(Vector3 newDir,Vector3 newUp,Node *node){ - newDir=node->localToGlobalPosition(newDir); - newUp=node->localToGlobalPosition(newUp); + Vector3 parAxis[]{ + node->getLocalAxis(0), + node->getLocalAxis(1), + node->getLocalAxis(2) + }; + newDir=parAxis[0]*newDir.x+parAxis[1]*newDir.y+parAxis[2]*newDir.z; + newUp=parAxis[0]*newUp.x+parAxis[1]*newUp.y+parAxis[2]*newUp.z; + /* + */ float angle=axis[2].getAngleBetween(newDir); Vector3 rotAxis=axis[2].cross(newDir).norm(); if(rotAxis==Vector3::VEC_ZERO) @@ -138,10 +145,10 @@ namespace vb01{ } void Node::updateLocalAxis(){ - Node *rootNode=Root::getSingleton()->getRootNode(),*par=this; - while(par->getParent()) - par=par->getParent(); - if(par!=rootNode) + Node *rootNode=Root::getSingleton()->getRootNode(),*ancestor=this; + while(ancestor->getParent()) + ancestor=ancestor->getParent(); + if(ancestor!=rootNode) return; Vector3 parAxis[3]={ @@ -259,10 +266,11 @@ namespace vb01{ vector meshes=n->getMeshes(); for(Mesh *m : meshes){ Material *mat=m->getMaterial(); - string str=to_string(root->numLights>0?root->numLights:1); + string str="const int numLights="+to_string(root->numLights>0?root->numLights:1)+";"; + if(mat){ //mat->getShader()->editShader(true,'=',';',str); - mat->getShader()->editShader(false,'=',';',str); + mat->getShader()->editShader(Shader::FRAGMENT_SHADER,1,str); } } } diff --git a/root.cpp b/root.cpp index 809ee16..bfd5f7b 100755 --- a/root.cpp +++ b/root.cpp @@ -36,7 +36,7 @@ namespace vb01{ this->height=height; glfwInit(); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3); glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE); window=glfwCreateWindow(width,height,name.c_str(),NULL,NULL); diff --git a/script.py b/script.py index 9bef5d2..6746527 100644 --- a/script.py +++ b/script.py @@ -88,22 +88,20 @@ def exportData(ob): #if mesh.shape_keys is not NoneType: #numShapeKeys=len(mesh.shape_keys[0].key_blocks)-1 - file.write("vertices: "+str(numVerts)+" "+str(numFaces)+" \n") + file.write("vertices: "+str(numVerts)+" "+str(numFaces)+" "+str(numGroups)+" "+str(numShapeKeys)+" \n") print('Exporting vertices...\n') for vert in mesh.vertices: pos=vert.co norm=vert.normal - file.write(str(pos.x)+" "+str(pos.y)+" "+str(pos.z)+" "+str(norm.x)+" "+str(norm.y)+" "+str(norm.z)+" \n") - ''' - for face in mesh.polygons: - for vert,loop in zip(face.vertices,mesh.loops): - pos=mesh.vertices[vert].co - norm=mesh.vertices[vert].normal - uv=mesh.uv_layers[0].data[loop.index].uv - tan=loop.tangent - bitan=loop.bitangent - file.write(str(pos.x)+" "+str(pos.y)+" "+str(pos.z)+" "+str(norm.x)+" "+str(norm.y)+" "+str(norm.z)+str(uv.x)+" "+str(uv.y)+" "+str(tan.x)+" "+str(tan.y)+" "+str(tan.z)+" "+str(bitan.x)+" "+str(bitan.y)+" "+str(bitan.z)+" \n") - ''' + weights=[] + for i in range(0,numGroups): + weights.append(0.0) + for g in vert.groups: + weights[g.group]=g.weight + file.write(str(pos.x)+" "+str(pos.y)+" "+str(pos.z)+" "+str(norm.x)+" "+str(norm.y)+" "+str(norm.z)+" ") + for w in weights: + file.write(str(w)+" ") + file.write('\n') file.write("faces:\n") print('Exporting faces...\n') @@ -117,6 +115,27 @@ def exportData(ob): file.write(str(vert)+" "+str(uv.x)+" "+str(uv.y)+" "+str(tan.x)+" "+str(tan.y)+" "+str(tan.z)+" "+str(bitan.x)+" "+str(bitan.y)+" "+str(bitan.z)+" \n") mesh.free_tangents() + if numGroups>0: + file.write('groups:\n') + for group in ob.vertex_groups: + file.write(group.name+'\n') + + if numShapeKeys>0: + file.write('shapeKeys:\n') + for shape_key in mesh.shape_keys.key_blocks: + if shape_key.name=='Basis': + continue + file.write(shape_key.name+'\n') + ''' + for face in mesh.polygons: + for vert,loop in zip(face.vertices,mesh.loops): + pos=mesh.vertices[vert].co + norm=mesh.vertices[vert].normal + uv=mesh.uv_layers[0].data[loop.index].uv + tan=loop.tangent + bitan=loop.bitangent + file.write(str(pos.x)+" "+str(pos.y)+" "+str(pos.z)+" "+str(norm.x)+" "+str(norm.y)+" "+str(norm.z)+str(uv.x)+" "+str(uv.y)+" "+str(tan.x)+" "+str(tan.y)+" "+str(tan.z)+" "+str(bitan.x)+" "+str(bitan.y)+" "+str(bitan.z)+" \n") + if numGroups>0: groupVerts=[] file.write("groups: "+str(numGroups)+"\n") @@ -146,6 +165,7 @@ def exportData(ob): newPos=shape_key.data[i].co if(newPos!=mesh.vertices[i].co): file.write('\n'+str(i)+" "+str(newPos.x)+' '+str(newPos.y)+' '+str(newPos.z)) + ''' fl=bpy.data.filepath dotId=0 diff --git a/shader.cpp b/shader.cpp index 769e18f..534aacf 100755 --- a/shader.cpp +++ b/shader.cpp @@ -37,16 +37,32 @@ namespace vb01{ Shader::~Shader(){} - void Shader::editShader(bool vertexShader, char firstChar, char secondChar, string insertion){ - int firstCharId=-1,secondCharId=-1; - for(int i=0;ilength(); i++) + if(shaderString[0][i] == '\n'){ + if(numPassedLines==line-1) + lineStart=i+1; + if(numPassedLines==line){ + lineEnd=i; + break; + } + numPassedLines++; + } + *shaderString=shaderString->substr(0,lineStart)+insertion+shaderString->substr(lineEnd,string::npos); loadShaders(); @@ -61,26 +77,26 @@ namespace vb01{ vert=glCreateShader(GL_VERTEX_SHADER); glShaderSource(vert,1,&vertShaderSource,NULL); glCompileShader(vert); - checkCompileErrors(vert,VERTEX); + checkCompileErrors(vert,VERTEX_ERROR); if(geometry){ geo=glCreateShader(GL_GEOMETRY_SHADER); glShaderSource(geo,1,&geoShaderSource,NULL); glCompileShader(geo); - checkCompileErrors(geo,GEOMETRY); + checkCompileErrors(geo,GEOMETRY_ERROR); } frag=glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(frag,1,&fragShaderSource,NULL); glCompileShader(frag); - checkCompileErrors(frag,FRAGMENT); + checkCompileErrors(frag,FRAGMENT_ERROR); id=glCreateProgram(); glAttachShader(id,vert); if(geometry) glAttachShader(id,geo); glAttachShader(id,frag); glLinkProgram(id); - checkCompileErrors(id,PROGRAM); + checkCompileErrors(id,PROGRAM_ERROR); glDeleteShader(vert); if(geometry) glDeleteShader(geo); @@ -91,7 +107,7 @@ namespace vb01{ int success; char infoLog[1024]; switch(type){ - case PROGRAM: + case PROGRAM_ERROR: glGetProgramiv(shader,GL_LINK_STATUS,&success); if(!success){ glGetProgramInfoLog(shader,1024,NULL,infoLog); @@ -103,13 +119,13 @@ namespace vb01{ if(!success){ const char *sh; switch(type){ - case VERTEX: + case VERTEX_ERROR: sh="VERTEX"; break; - case GEOMETRY: + case GEOMETRY_ERROR: sh="GEOMETRY"; break; - case FRAGMENT: + case FRAGMENT_ERROR: sh="FRAGMENT"; break; } diff --git a/shader.h b/shader.h index 0dd75e0..9b1e155 100755 --- a/shader.h +++ b/shader.h @@ -8,7 +8,8 @@ namespace vb01{ class Shader{ public: - enum ErrorType{VERTEX,GEOMETRY,FRAGMENT,PROGRAM}; + enum ErrorType{VERTEX_ERROR,GEOMETRY_ERROR,FRAGMENT_ERROR,PROGRAM_ERROR}; + enum ShaderType{VERTEX_SHADER,FRAGMENT_SHADER,GEOMETRY_SHADER}; Shader(std::string,std::string,std::string=""); ~Shader(); @@ -21,7 +22,7 @@ namespace vb01{ void setFloat(float,std::string); void setBool(bool,std::string); void setInt(int,std::string); - void editShader(bool,char,char,std::string); + void editShader(ShaderType,int,std::string); private: void loadShaders(); void checkCompileErrors(unsigned int,ErrorType); diff --git a/skeleton.cpp b/skeleton.cpp index 261072a..ba2c174 100644 --- a/skeleton.cpp +++ b/skeleton.cpp @@ -1,5 +1,6 @@ #include"skeleton.h" #include"animation.h" +#include"box.h" using namespace std; @@ -11,6 +12,14 @@ namespace vb01{ void Skeleton::addBone(Bone *bone, Node *parent){ parent->attachChild(bone); bones.push_back(bone); + + Box *box=new Box(Vector3(.1,.1,.1)); + Material *mat=new Material(); + mat->setTexturingEnabled(false); + mat->setLightingEnabled(false); + mat->setDiffuseColor(Vector4(0,1,0,1)); + box->setMaterial(mat); + //bone->attachMesh(box); } Bone* Skeleton::getBone(string name){ diff --git a/skeleton.h b/skeleton.h index d993af0..bec150f 100644 --- a/skeleton.h +++ b/skeleton.h @@ -16,8 +16,10 @@ namespace vb01{ Animation* getAnimation(std::string); inline void addAnimation(Animation *anim){animations.push_back(anim);} inline Bone* getBone(int i){return bones[i];} + inline Bone* getRootBone(){return bones[0];} inline std::vector& getBones(){return bones;} inline std::string getName(){return name;} + inline int getNumBones(){return bones.size();} private: std::string name; std::vector bones; diff --git a/texture.vert b/texture.vert index 5529b18..0eb7645 100755 --- a/texture.vert +++ b/texture.vert @@ -1,10 +1,15 @@ #version 330 core +const int numBones=1; +const int numVertGroups=1; + layout (location=0) in vec3 aPos; layout (location=1) in vec3 aNorm; layout (location=2) in vec2 aTexCoords; layout (location=3) in vec3 aTan; layout (location=4) in vec3 aBiTan; +layout (location=5) in vec4 aWeight; +//layout (location=5) in float[numVertGroups] aWeight; out vec3 fragPos; out vec3 norm; @@ -12,12 +17,51 @@ out vec3 tan; out vec3 biTan; out vec2 texCoords; +struct Bone{ + float angle; + vec3 pos,trans,rotAxis,scale; + int vertGroup,parent; +}; + +uniform bool animated; +uniform Bone bones[numBones]; uniform mat4 model; uniform mat4 view; uniform mat4 proj; void main(){ - gl_Position=proj*view*model*vec4(aPos,1); + vec4 vertPos=vec4(aPos,1); + if(animated){ + for(int i = 0; i < numBones; i++){ + Bone bone = bones[i]; + while(bone.parent!=-1){ + float weight = aWeight[bones[i].vertGroup]; + float angle = weight * bone.angle; + vec3 trans = bone.trans; + vec3 axis = bone.rotAxis; + vec3 scale = bone.scale; + vec4 bonePos = vec4(bone.pos,1); + + float s = sin(angle); + float c = cos(angle); + float oc = 1.0 - c; + + mat4 rotMat; + rotMat[0] = vec4(oc * axis.x * axis.x + c,oc * axis.x * axis.y + axis.z * s,oc * axis.z * axis.x - axis.y * s,0.0); + rotMat[1] = vec4(oc * axis.x * axis.y - axis.z * s,oc * axis.y * axis.y + c,oc * axis.y * axis.z + axis.x * s,0.0); + rotMat[2] = vec4(oc * axis.z * axis.x + axis.y * s,oc * axis.y * axis.z - axis.x * s,oc * axis.z * axis.z + c,0.0); + rotMat[3] = vec4(0,0,0,1); + + vertPos += -(vertPos - bonePos) + rotMat * (vertPos - bonePos); + vec4 vertToBone = vec4(vertPos.xyz - bonePos.xyz, 1); + vertPos.xyz += -weight * vertToBone.xyz + weight * vec3(scale.x * vertToBone.x, scale.y * vertToBone.y, scale.z * vertToBone.z); + vertPos.xyz = vertPos.xyz + weight * trans; + bone = bones[bone.parent]; + } + } + } + + gl_Position=proj*view*model*vertPos; fragPos=vec3(model*vec4(aPos,1)); norm=mat3(transpose(inverse(model)))*aNorm; tan=mat3(transpose(inverse(model)))*aTan;