//------------------------------------------- update. void ofxAssimpModelLoader::update() { updateAnimations(); updateMeshes(scene->mRootNode, ofMatrix4x4()); if(hasAnimations() == false) { return; } updateBones(); updateGLResources(); }
void AssimpModelMover::updateSkeleton() { // update mesh position for the animation for (unsigned int i = 0; i < modelMeshes.size(); ++i) { // current mesh we are introspecting const aiMesh *mesh = modelMeshes[i].mesh; // calculate bone matrices std::vector<ofMatrix4x4> boneMatrices(mesh->mNumBones); for (size_t a = 0; a < mesh->mNumBones; ++a) { const aiBone *bone = mesh->mBones[a]; // find the corresponding node by again looking recursively through the node hierarchy for the same name map<string, BoneNode *>::iterator it = boneNodes.find(bone->mName.data); assert(it != boneNodes.end()); BoneNode *bn = it->second; // start with the mesh-to-bone matrix //boneMatrices[a] = aiMatrix4x4ToOfMatrix44(bone->mOffsetMatrix) * bn->getGlobalTransformMatrix(); boneMatrices[a] = aiMatrix4x4ToOfMatrix44(bone->mOffsetMatrix) * bn->getDerivedTransformMatrix(); modelMeshes[i].hasChanged = true; modelMeshes[i].validCache = false; } modelMeshes[i].animatedPos.assign(modelMeshes[i].animatedPos.size(),0); if(mesh->HasNormals()){ modelMeshes[i].animatedNorm.assign(modelMeshes[i].animatedNorm.size(),0); } // loop through all vertex weights of all bones for( size_t a = 0; a < mesh->mNumBones; ++a) { const aiBone* bone = mesh->mBones[a]; const aiMatrix4x4& posTrafo = ofMatrix4x4ToAiMatrix44(boneMatrices[a]); for( size_t b = 0; b < bone->mNumWeights; ++b) { const aiVertexWeight& weight = bone->mWeights[b]; size_t vertexId = weight.mVertexId; const aiVector3D& srcPos = mesh->mVertices[vertexId]; modelMeshes[i].animatedPos[vertexId] += weight.mWeight * (posTrafo * srcPos); } if(mesh->HasNormals()){ // 3x3 matrix, contains the bone matrix without the translation, only with rotation and possibly scaling aiMatrix3x3 normTrafo = aiMatrix3x3( posTrafo); for( size_t b = 0; b < bone->mNumWeights; ++b) { const aiVertexWeight& weight = bone->mWeights[b]; size_t vertexId = weight.mVertexId; const aiVector3D& srcNorm = mesh->mNormals[vertexId]; modelMeshes[i].animatedNorm[vertexId] += weight.mWeight * (normTrafo * srcNorm); } } } } updateGLResources(); }
//------------------------------------------- void ofxAssimpModelLoader::draw(ofPolyRenderMode renderType) { if(scene){ ofPushStyle(); #ifndef TARGET_OPENGLES glPushAttrib(GL_ALL_ATTRIB_BITS); glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); glPolygonMode(GL_FRONT_AND_BACK, ofGetGLPolyMode(renderType)); #endif glEnable(GL_NORMALIZE); ofPushMatrix(); ofTranslate(pos); ofRotate(180, 0, 0, 1); ofTranslate(-scene_center.x, -scene_center.y, scene_center.z); if(normalizeScale) { ofScale(normalizedScale , normalizedScale, normalizedScale); } for(int i = 0; i < (int)rotAngle.size(); i++){ ofRotate(rotAngle[i], rotAxis[i].x, rotAxis[i].y, rotAxis[i].z); } ofScale(scale.x, scale.y, scale.z); if(getAnimationCount()) { updateGLResources(); } for(int i = 0; i < (int)modelMeshes.size(); i++){ ofxAssimpMeshHelper & meshHelper = modelMeshes.at(i); // Texture Binding if(bUsingTextures && meshHelper.texture.isAllocated()){ meshHelper.texture.bind(); } if(bUsingMaterials){ meshHelper.material.begin(); } // Culling if(meshHelper.twoSided) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); ofEnableBlendMode(meshHelper.blendMode); #ifndef TARGET_OPENGLES meshHelper.vbo.drawElements(GL_TRIANGLES,meshHelper.indices.size()); #else switch(renderType){ case OF_MESH_FILL: meshHelper.vbo.drawElements(GL_TRIANGLES,meshHelper.indices.size()); break; case OF_MESH_WIREFRAME: meshHelper.vbo.drawElements(GL_LINES,meshHelper.indices.size()); break; case OF_MESH_POINTS: meshHelper.vbo.drawElements(GL_POINTS,meshHelper.indices.size()); break; } #endif // Texture Binding if(bUsingTextures && meshHelper.texture.bAllocated()){ meshHelper.texture.unbind(); } if(bUsingMaterials){ meshHelper.material.end(); } } ofPopMatrix(); #ifndef TARGET_OPENGLES glPopClientAttrib(); glPopAttrib(); #endif ofPopStyle(); } }
void ofxAssimpModelLoader::draw() { if(scene){ glPushAttrib(GL_ALL_ATTRIB_BITS); glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); glEnable(GL_NORMALIZE); glPushMatrix(); glTranslatef(pos.x, pos.y, pos.z); glRotatef(180, 0, 0, 1); glTranslated(-scene_center.x, -scene_center.y, scene_center.z); if(normalizeScale) { glScaled(normalizedScale , normalizedScale, normalizedScale); } for(int i = 0; i < numRotations; i++){ glRotatef(rotAngle[i], rotAxis[i].x, rotAxis[i].y, rotAxis[i].z); } glScalef(scale.x, scale.y, scale.z); if(getAnimationCount()) { updateGLResources(); } if(modelMeshes.size()) { for(int i = 0; i < modelMeshes.size(); i++){ ofxAssimpMeshHelper meshHelper = modelMeshes.at(i); // Texture Binding if(meshHelper.textureIndex!=-1){ textures[meshHelper.textureIndex].getTextureReference().bind(); } // Set up meterial state. float dc[4]; float sc[4]; float ac[4]; float emc[4]; // Material colors and properties color4_to_float4(&meshHelper.diffuseColor, dc); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, dc); color4_to_float4(&meshHelper.specularColor, sc); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, sc); color4_to_float4(&meshHelper.ambientColor, ac); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ac); color4_to_float4(&meshHelper.emissiveColor, emc); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emc); // Culling if(meshHelper.twoSided) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); // TODO: equivalent VAO callfor linux and windows. glBindVertexArrayAPPLE(meshHelper.vao); glDrawElements(GL_TRIANGLES, meshHelper.numIndices, GL_UNSIGNED_INT, 0); // Texture Binding if(meshHelper.textureIndex!=-1){ textures[meshHelper.textureIndex].getTextureReference().unbind(); } } } glPopMatrix(); glPopClientAttrib(); glPopAttrib(); } }