diff --git a/mesh.cpp b/mesh.cpp index 0e8577f..1d332dd 100755 --- a/mesh.cpp +++ b/mesh.cpp @@ -26,6 +26,9 @@ namespace vb01{ this->numShapeKeys = numShapeKeys; this->name = name; + shapeKeyFactors = new float[numShapeKeys]; + for(int i = 0; i < numShapeKeys; i++) + shapeKeyFactors[i] = 1; } Mesh::~Mesh(){ @@ -98,6 +101,10 @@ namespace vb01{ glEnableVertexAttribArray(5); glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(Vertex, boneIndices))); glEnableVertexAttribArray(6); + for(int i = 0; i < numShapeKeys; i++){ + } + glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(Vertex, shapeKeyOffsets))); + glEnableVertexAttribArray(7); } void Mesh::update(){ @@ -134,6 +141,9 @@ namespace vb01{ if(skeleton) updateSkeleton(shader); + if(numShapeKeys > 0) + updateShapeKeys(shader); + shader->setBool(castShadow, "castShadow"); shader->setBool(skeleton, "animated"); shader->setBool(false, "environment"); @@ -151,6 +161,13 @@ namespace vb01{ render(); } + void Mesh::updateShapeKeys(Shader *shader){ + shader->editShader(Shader::VERTEX_SHADER, 5, "const int numShapeKeys=" + to_string(numShapeKeys) + ";"); + for(int i = 0; i < numShapeKeys; i++){ + shader->setFloat(shapeKeyFactors[i], "shapeKeyFactors[" + to_string(i) + "]"); + } + } + void Mesh::updateSkeleton(Shader *shader){ skeleton->update(); diff --git a/mesh.h b/mesh.h index 6c633c1..e2c9ed0 100755 --- a/mesh.h +++ b/mesh.h @@ -23,7 +23,7 @@ namespace vb01{ //float *weights=nullptr; float weights[4]{0, 0, 0, 0}; int boneIndices[4]{-1, -1, -1, -1}; - Vector3 *shapeKeyOffsets = nullptr; + Vector3 shapeKeyOffsets[100]; }; Mesh(Vertex*, unsigned int*, int, std::string *vg = nullptr, int = 0, std::string *sk = nullptr, int = 0, std::string = ""); @@ -53,6 +53,7 @@ namespace vb01{ void initFramebuffer(); void updateSkeleton(Shader*); void updateReflection(Shader*, Vector3, int, int); + void updateShapeKeys(Shader*); Shader *environmentShader = nullptr; u32 environmentBuffer; @@ -68,7 +69,8 @@ namespace vb01{ bool staticVerts = true, castShadow = false, reflect = false, wireframe = false; Vertex *vertices; std::string *vertexGroups = nullptr, *shapeKeys = nullptr; - unsigned int *indices, VAO, VBO, EBO; + u32 *indices, VAO, VBO, EBO; + float *shapeKeyFactors = nullptr; int numTris, numVertexGroups = 0, numShapeKeys = 0; }; } diff --git a/texture.vert b/texture.vert index 2a453f5..b6cb69e 100755 --- a/texture.vert +++ b/texture.vert @@ -1,8 +1,9 @@ #version 330 core -const int numBones=1; -const int numVertGroups=1; +const int numBones = 1; +const int numVertGroups = 1; const int numMaxInfluences = 4; +const int numShapeKeys = 1; mat4 transform[numBones]; mat4 poseTransform[numBones]; @@ -14,6 +15,7 @@ layout (location=3) in vec3 aTan; layout (location=4) in vec3 aBiTan; layout (location=5) in vec4 aWeight; layout (location=6) in ivec4 aBoneIndices; +layout (location=7) in vec3[numShapeKeys] aShapeKeyOffsets; out vec3 fragPos; out vec3 norm; @@ -32,6 +34,7 @@ uniform Bone bones[numBones]; uniform mat4 model; uniform mat4 view; uniform mat4 proj; +uniform float[numShapeKeys] shapeKeyFactors; mat4 createTranslationMatrix(vec3 trans){ mat4 transMat; @@ -98,14 +101,18 @@ void main(){ poseTransform[i] = poseTransform[bones[i].parent] * localTransform; } - vec3 v = vec3(0); + vec3 v0 = vec3(0); for(int i = 0; i < numBones; i++){ float weight = getWeight(bones[i]); vec4 boneLocalVert = inverse(transform[i]) * vertPos; - v += (weight * poseTransform[i] * boneLocalVert).xyz; + v0 += (weight * poseTransform[i] * boneLocalVert).xyz; } - vertPos.xyz = v; + vertPos.xyz = v0; + } + + for(int i = 0; i < numShapeKeys; i++){ + vertPos.xyz += aShapeKeyOffsets[i] * shapeKeyFactors[i]; } gl_Position = proj * view * model * vertPos; diff --git a/vbModelReader.cpp b/vbModelReader.cpp index 7960020..67bb9f8 100644 --- a/vbModelReader.cpp +++ b/vbModelReader.cpp @@ -306,6 +306,7 @@ namespace vb01{ void VbModelReader::readFaces( vector &vertPos, vector &vertNorm, + vector &vertIds, vector &vertWeights, vector &meshData, int numBones, @@ -337,6 +338,7 @@ namespace vb01{ } } + vertIds.push_back(index); vertices[i] = vert; indices[i] = i; } @@ -348,8 +350,30 @@ namespace vb01{ } } - void VbModelReader::readShapeKeys(int shapeKeyStartLine, int numShapes){ + void VbModelReader::readShapeKeys(Mesh::Vertex *vertices, vector &vertIds, vector &meshData, string *shapeKeys, int numShapes, int numVertPos){ + /* + for(int i = 0; i < vertIds.size(); i++) + vertices[i].shapeKeyOffsets = new Vector3[numShapes]; + */ + + int shapeKeyStartLine = 0; for(int i = 0; i < numShapes; i++){ + shapeKeys[i] = meshData[shapeKeyStartLine]; + Vector3 *shapeKeyVertPos = new Vector3[numVertPos]; + + for(int j = 0; j < numVertPos; j++){ + string line = meshData[shapeKeyStartLine + 1 + j]; + string dataLine[3]; + getLineData(line, dataLine, 3); + shapeKeyVertPos[j] = Vector3(atof(dataLine[0].c_str()), atof(dataLine[2].c_str()), -atof(dataLine[1].c_str())); + } + for(int j = 0; j < vertIds.size(); j++){ + Vector3 offset = shapeKeyVertPos[vertIds[j]] - vertices[j].pos; + vertices[j].shapeKeyOffsets[i] = (offset); + } + + delete[] shapeKeyVertPos; + shapeKeyStartLine += numVertPos + 1; } } @@ -381,35 +405,40 @@ namespace vb01{ int vertexGroupStartLine = 8; int vertexStartLine = vertexGroupStartLine + numBones + 1; int faceStartLine = vertexStartLine + numVertices + 1; - int shapeKeyStartLine = faceStartLine + numFaces + 1; + int shapeKeyStartLine = faceStartLine + numFaces * numVertsPerFace + 1; vector vertPos, vertNorm; vector vertWeights; + vector vertIds; Mesh::Vertex *vertices = new Mesh::Vertex[numFaces * numVertsPerFace]; u32 *indices = new u32[numFaces * numVertsPerFace]; string *groups = new string[numBones]; + string *shapeKeys = new string[numShapes]; vector meshSubData = vector(meshData.begin() + vertexStartLine, meshData.begin() + vertexStartLine + numVertices); readVertices(vertPos, vertNorm, vertWeights, meshSubData, numBones); meshSubData.clear(); meshSubData = vector(meshData.begin() + faceStartLine, meshData.begin() + faceStartLine + numFaces * numVertsPerFace); - readFaces(vertPos, vertNorm, vertWeights, meshSubData, numBones, vertices, indices); + readFaces(vertPos, vertNorm, vertIds, vertWeights, meshSubData, numBones, vertices, indices); meshSubData.clear(); + vertPos.clear(); + vertNorm.clear(); + vertWeights.clear(); meshSubData = vector(meshData.begin() + vertexGroupStartLine, meshData.begin() + vertexGroupStartLine + numBones); readVertexGroups(groups, meshSubData, numBones); meshSubData.clear(); - meshSubData = vector(meshData.begin() + shapeKeyStartLine, meshData.begin() + shapeKeyStartLine + numShapes); - readShapeKeys(shapeKeyStartLine, numShapes); + meshSubData = vector(meshData.begin() + shapeKeyStartLine, meshData.begin() + (shapeKeyStartLine + numShapes * (1 + numVertices))); + readShapeKeys(vertices, vertIds, meshSubData, shapeKeys, numShapes, numVertices); meshSubData.clear(); AnimationController *controller = new AnimationController(); Node *node = new Node(Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK, name, controller); nodes.push_back(node); - int numAnimLineId = vertexStartLine + numVertices + numFaces * numVertsPerFace + numShapes + 1; + int numAnimLineId = shapeKeyStartLine + numShapes * (1 + numVertices); int numAnimations = atoi(meshData[numAnimLineId].substr(meshData[numAnimLineId].find_first_of(':') + 1).c_str()); meshSubData = vector(meshData.begin() + (numAnimLineId + 1), meshData.end()); readAnimations(controller, meshSubData, numAnimations); @@ -424,7 +453,7 @@ namespace vb01{ if(sk->getName() == skeletonName) skeleton = sk; - Mesh *mesh = new Mesh(vertices, indices, numFaces, groups, numBones, nullptr, numShapes, name); + Mesh *mesh = new Mesh(vertices, indices, numFaces, groups, numBones, shapeKeys, numShapes, name); mesh->setSkeleton(skeleton); node->attachMesh(mesh); diff --git a/vbModelReader.h b/vbModelReader.h index 211bf07..0c305be 100644 --- a/vbModelReader.h +++ b/vbModelReader.h @@ -28,9 +28,9 @@ namespace vb01{ void readAnimations(AnimationController*, std::vector&, int); Skeleton* readSkeleton(std::vector&); void readVertices(std::vector&, std::vector&, std::vector&, std::vector&, int); - void readFaces(std::vector&, std::vector&, std::vector&, std::vector&, int, Mesh::Vertex*, u32*); + void readFaces(std::vector&, std::vector&, std::vector&, std::vector&, std::vector&, int, Mesh::Vertex*, u32*); void readVertexGroups(std::string*, std::vector&, int); - void readShapeKeys(int, int); + void readShapeKeys(Mesh::Vertex*, std::vector&, std::vector&, std::string*, int, int); void buildMesh(std::vector&); Mesh* readMeshes(std::vector&); void readLights(std::vector&);