//------------------------------------------- update.
void ofxAssimpModelLoader::update() {
    updateAnimations();
    updateMeshes(scene->mRootNode, ofMatrix4x4());
    if(hasAnimations() == false) {
        return;
    }
    updateBones();
    updateGLResources();
}
Example #2
0
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();
    }
}