bool ofxAssimpModelLoader::processScene() {
    
    normalizeFactor = ofGetWidth() / 2.0;
    
    if(scene){
        loadGLResources();
        update();
        calculateDimensions();
        
        if(getAnimationCount())
            ofLogVerbose("ofxAssimpModelLoader") << "loadModel(): scene has " << getAnimationCount() << "animations";
        else {
            ofLogVerbose("ofxAssimpModelLoader") << "loadMode(): no animations";
        }
        
        ofAddListener(ofEvents().exit,this,&ofxAssimpModelLoader::onAppExit);
        
        
        return true;
    }else{
        ofLogError("ofxAssimpModelLoader") << "loadModel(): " + (string) aiGetErrorString();
        clear();
        return false;
    }
    
    return false;
}
//-------------------------------------------
bool ofxAssimpModelLoader::loadModel(ofBuffer & buffer, bool optimize, const char * extension){
	normalizeFactor = ofGetWidth() / 2.0;

	// only ever give us triangles.
	aiSetImportPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT );
	aiSetImportPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE, true);

	// aiProcess_FlipUVs is for VAR code. Not needed otherwise. Not sure why.
	unsigned int flags = aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_Triangulate | aiProcess_FlipUVs;
	if(optimize) flags |=  aiProcess_ImproveCacheLocality | aiProcess_OptimizeGraph |
			aiProcess_OptimizeMeshes | aiProcess_JoinIdenticalVertices |
			aiProcess_RemoveRedundantMaterials;

	if(scene){
		clear();
	}
	scene = aiImportFileFromMemory(buffer.getBinaryBuffer(), buffer.size(), flags, extension);
	if(scene){
		calculateDimensions();
		loadGLResources();

		if(getAnimationCount())
			ofLog(OF_LOG_VERBOSE, "scene has animations");
		else {
			ofLog(OF_LOG_VERBOSE, "no animations");

		}
		return true;
	}else{
		ofLog(OF_LOG_ERROR,string("ofxAssimpModelLoader: ") + aiGetErrorString());
		return false;
	}

}
// DEPRECATED.
float ofxAssimpModelLoader::getDuration(int animationIndex) {
    if(!hasAnimations()) {
        return 0;
    }
    animationIndex = ofClamp(animationIndex, 0, getAnimationCount() - 1);
    float duration = animations[animationIndex].getDurationInSeconds();
    return duration;
}
//------------------------------------------
void ofxAssimpModelLoader::loadModel(string modelName){
	
    
    // if we have a model loaded, unload the f****r.
    if(scene != NULL)
    {
        aiReleaseImport(scene);
        scene = NULL;
        
        deleteGLResources();   
    }
    
    
    // Load our new path.
    string filepath = ofToDataPath(modelName);

    ofLog(OF_LOG_VERBOSE, "loading model %s", filepath.c_str());
    
    // only ever give us triangles.
    aiSetImportPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT );
    aiSetImportPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE, true);
    
    // aiProcess_FlipUVs is for VAR code. Not needed otherwise. Not sure why.
    scene = (aiScene*) aiImportFile(filepath.c_str(), aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_OptimizeGraph | aiProcess_Triangulate | aiProcess_FlipUVs | 0 );
    
    if(scene){        
        ofLog(OF_LOG_VERBOSE, "initted scene with %i meshes & %i animations", scene->mNumMeshes, scene->mNumAnimations);

        getBoundingBoxWithMinVector(&scene_min, &scene_max);
        scene_center.x = (scene_min.x + scene_max.x) / 2.0f;
        scene_center.y = (scene_min.y + scene_max.y) / 2.0f;
        scene_center.z = (scene_min.z + scene_max.z) / 2.0f;
        
        // optional normalized scaling
        normalizedScale = scene_max.x-scene_min.x;
        normalizedScale = aisgl_max(scene_max.y - scene_min.y,normalizedScale);
        normalizedScale = aisgl_max(scene_max.z - scene_min.z,normalizedScale);
        normalizedScale = 1.f / normalizedScale;
        normalizedScale *= ofGetWidth() / 2.0;
        
        glPushAttrib(GL_ALL_ATTRIB_BITS);
        glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
        
        loadGLResources();
        
        glPopClientAttrib();
        glPopAttrib();

        if(getAnimationCount())
            ofLog(OF_LOG_VERBOSE, "scene has animations");
        else {
            ofLog(OF_LOG_VERBOSE, "no animations");
            
        }
    }
}
void ofxAssimpModelLoader::setTime(float t){ // 0 - 1
    if(getAnimationCount()){

        // only evaluate if we have a delta t.
        if(animationTime != t){
            animationTime = t;
            updateAnimation(currentAnimation, animationTime);
        }
    }
}
//-------------------------------------------
void ofxAssimpModelLoader::setNormalizedTime(float t){ // 0 - 1

    if(getAnimationCount())
    {

        const aiAnimation* anim = scene->mAnimations[currentAnimation];
        float realT = ofMap(t, 0.0, 1.0, 0.0, (float)anim->mDuration, false);

        setTime(realT);
    }
}
//-------------------------------------------
bool ofxAssimpModelLoader::loadModel(ofBuffer & buffer, bool optimize, const char * extension){
	normalizeFactor = ofGetWidth() / 2.0;
    
    if(scene != NULL){
        clear();
    }
    
	// only ever give us triangles.
	aiSetImportPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT );
	aiSetImportPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE, true);

	// aiProcess_FlipUVs is for VAR code. Not needed otherwise. Not sure why.
	unsigned int flags = aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_Triangulate | aiProcess_FlipUVs;
	if(optimize) flags |=  aiProcess_ImproveCacheLocality | aiProcess_OptimizeGraph |
			aiProcess_OptimizeMeshes | aiProcess_JoinIdenticalVertices |
			aiProcess_RemoveRedundantMaterials;

	scene = aiImportFileFromMemory(buffer.getBinaryBuffer(), buffer.size(), flags, extension);
    
	if(scene){
		calculateDimensions();
		loadGLResources();
        update();

		if(getAnimationCount())
			ofLogVerbose("ofxAssimpModelLoader") << "loadModel(): scene has " << getAnimationCount() << "animations";
		else {
			ofLogVerbose("ofxAssimpModelLoader") << "loadMode(): no animations";
		}

		ofAddListener(ofEvents().exit,this,&ofxAssimpModelLoader::onAppExit);


		return true;
	}else{
		ofLogError("ofxAssimpModelLoader") << "loadModel(): " + (string) aiGetErrorString();
		clear();
		return false;
	}
}
示例#8
0
//------------------------------------------
bool ofxAssimpModelLoader::loadModel(string modelName, unsigned extraFlags /* = 0 */){


    // if we have a model loaded, unload the f****r.
    if(scene != NULL){
        clear();
    }

    // Load our new path.
    filepath = modelName;
    string filepath = ofToDataPath(modelName);

	//theo added - so we can have models and their textures in sub folders
	modelFolder = ofFilePath::getEnclosingDirectory(filepath);

    ofLog(OF_LOG_VERBOSE, "loading model %s", filepath.c_str());
    ofLog(OF_LOG_VERBOSE, "loading from folder %s", modelFolder.c_str());

    // only ever give us triangles.
    aiSetImportPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT );
    aiSetImportPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE, true);

    // aiProcess_FlipUVs is for VAR code. Not needed otherwise. Not sure why.
    unsigned int flags = aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_Triangulate | aiProcess_FlipUVs;
	flags |= extraFlags;
	/*
    if(optimize) flags |=  aiProcess_ImproveCacheLocality | aiProcess_OptimizeGraph |
			aiProcess_OptimizeMeshes | aiProcess_JoinIdenticalVertices |
			aiProcess_RemoveRedundantMaterials;
	*/

    scene = aiImportFile(filepath.c_str(), flags);

    if(scene){
        calculateDimensions();
        loadGLResources();

        if(getAnimationCount())
            ofLog(OF_LOG_VERBOSE, "scene has animations");
        else {
            ofLog(OF_LOG_VERBOSE, "no animations");

        }
		collectNodeTransforms(scene, scene->mRootNode);
		collectBoneTransforms();

        return true;
    }else{
    	ofLog(OF_LOG_ERROR,string("ofxAssimpModelLoader: ") + aiGetErrorString());
    	return false;
    }
}
//-------------------------------------------
void ofxAssimpModelLoader::loadGLResources(){

    ofLog(OF_LOG_VERBOSE, "loading gl resources");

    // create new mesh helpers for each mesh, will populate their data later.
    modelMeshes.reserve(scene->mNumMeshes); 
        
    // create OpenGL buffers and populate them based on each meshes pertinant info.
    for (unsigned int i = 0; i < scene->mNumMeshes; ++i){
        ofLog(OF_LOG_VERBOSE, "loading mesh %u", i);
        // current mesh we are introspecting
        aiMesh* mesh = scene->mMeshes[i];
        
        // the current meshHelper we will be populating data into.
        ofxAssimpMeshHelper meshHelper;
        
        meshHelper.mesh = mesh;
        
        // set the mesh's default values.
        aiColor4D dcolor = aiColor4D(0.8f, 0.8f, 0.8f, 1.0f);
        meshHelper.diffuseColor = dcolor;

        aiColor4D scolor = aiColor4D(0.0f, 0.0f, 0.0f, 1.0f);
        meshHelper.specularColor = scolor;

        aiColor4D acolor = aiColor4D(0.2f, 0.2f, 0.2f, 1.0f);
        meshHelper.ambientColor = acolor;

        aiColor4D ecolor = aiColor4D(0.0f, 0.0f, 0.0f, 1.0f);
        meshHelper.emissiveColor = ecolor;

        // Handle material info
        aiMaterial* mtl = scene->mMaterials[mesh->mMaterialIndex];
        
        // Load Textures
        int texIndex = 0;
        aiString texPath;
        
        //meshHelper.texture = NULL;
        
        // TODO: handle other aiTextureTypes
        if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath)){
            // This is magic. Thanks Kyle.
            
            textures.push_back(ofImage());            
            
            ofImage& image = textures.back();                

            ofLog(OF_LOG_VERBOSE, "loading image from %s", texPath.data);
            
            image.loadImage(texPath.data);
            image.update();
            
            ofLog(OF_LOG_VERBOSE, "texture width: %f height %f", image.getWidth(), image.getHeight());
            
            //meshHelper.texture = &(image.getTextureReference()); 
            meshHelper.textureIndex = textures.size()-1;
        }
        
        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &dcolor))
            meshHelper.diffuseColor = dcolor;
        
        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &scolor))
            meshHelper.specularColor = scolor;
        
        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &acolor))
            meshHelper.ambientColor = acolor;
        
        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &ecolor))
            meshHelper.emissiveColor = ecolor;
        
        // Culling
        unsigned int max = 1;
        int two_sided;
        if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)
            meshHelper.twoSided = true;
        else
            meshHelper.twoSided = false;
        
        // Create a VBO for our vertices
        GLuint vhandle;
        glGenBuffers(1, &vhandle);
        
        glBindBuffer(GL_ARRAY_BUFFER, vhandle);
        
        if(getAnimationCount())
            glBufferData(GL_ARRAY_BUFFER, sizeof(aiVertex) * mesh->mNumVertices, NULL, GL_STREAM_DRAW/*GL_STATIC_DRAW GL_STREAM_DRAW*/);
        else
            glBufferData(GL_ARRAY_BUFFER, sizeof(aiVertex) * mesh->mNumVertices, NULL, GL_STATIC_DRAW/*GL_STATIC_DRAW GL_STREAM_DRAW*/);

        // populate vertices
        aiVertex* verts = (aiVertex*)glMapBuffer(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
        
        for (unsigned int x = 0; x < mesh->mNumVertices; ++x)
        {
            verts->vPosition = mesh->mVertices[x];
            
            if (NULL == mesh->mNormals)
                verts->vNormal = aiVector3D(0.0f,0.0f,0.0f);
            else
                verts->vNormal = mesh->mNormals[x];
            
            if (mesh->HasVertexColors(0))
            {
                verts->dColorDiffuse = mesh->mColors[0][x];
            }
            else
                verts->dColorDiffuse = aiColor4D(1.0, 1.0, 1.0, 1.0);
            
            // This varies slightly form Assimp View, we support the 3rd texture component.
            if (mesh->HasTextureCoords(0))
                verts->vTextureUV = mesh->mTextureCoords[0][x];
            else
                verts->vTextureUV = aiVector3D(0.5f,0.5f, 0.0f);
           
            // No longer in aiVertex VBO structure
            /*          
            if (NULL == mesh->mTangents)
            {
                verts->vTangent = aiVector3D(0.0f,0.0f,0.0f);
                verts->vBitangent = aiVector3D(0.0f,0.0f,0.0f);
            }
            else
            {
                verts->vTangent = mesh->mTangents[x];
                verts->vBitangent = mesh->mBitangents[x];
            }
             
            if (mesh->HasTextureCoords(1))
                verts->vTextureUV2 = mesh->mTextureCoords[1][x];
            else 
                verts->vTextureUV2 = aiVector3D(0.5f,0.5f, 0.0f);

            if( mesh->HasBones()){
                unsigned char boneIndices[4] = { 0, 0, 0, 0 };
                unsigned char boneWeights[4] = { 0, 0, 0, 0 };
                ai_assert( weightsPerVertex[x].size() <= 4);

                for( unsigned int a = 0; a < weightsPerVertex[x].size(); a++){
                    boneIndices[a] = weightsPerVertex[x][a].mVertexId;
                    boneWeights[a] = (unsigned char) (weightsPerVertex[x][a].mWeight * 255.0f);
                }

                memcpy( verts->mBoneIndices, boneIndices, sizeof( boneIndices));
                memcpy( verts->mBoneWeights, boneWeights, sizeof( boneWeights));
            }
            else{
               // memset( verts->mBoneIndices, 0, sizeof( verts->mBoneIndices));
               // memset( verts->mBoneWeights, 0, sizeof( verts->mBoneWeights));
            }
 */           
            ++verts;
        }
        
        glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); //invalidates verts
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        
        // set the mesh vertex buffer handle to our new vertex buffer.
        meshHelper.vertexBuffer = vhandle;
        
        // Create Index Buffer
        unsigned int nidx;
        switch (mesh->mPrimitiveTypes){
            case aiPrimitiveType_POINT:
                nidx = 1;break;
            case aiPrimitiveType_LINE:
                nidx = 2;break;
            case aiPrimitiveType_TRIANGLE:
                nidx = 3;break;
            default: assert(false);
        }   
        
        GLuint ihandle;
        glGenBuffers(1, &ihandle);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ihandle);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * mesh->mNumFaces * nidx, NULL, GL_STATIC_DRAW/*GL_STATIC_DRAW GL_STREAM_DRAW*/);
        
        unsigned int* indices = (unsigned int*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_ARB);
        
        // now fill the index buffer
        for (unsigned int x = 0; x < mesh->mNumFaces; ++x){
            for (unsigned int a = 0; a < nidx; ++a){
                *indices++ = mesh->mFaces[x].mIndices[a];
            }
        }
        
        glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        
        // set the mesh index buffer handle to our new index buffer.
        meshHelper.indexBuffer = ihandle;
        meshHelper.numIndices = mesh->mNumFaces * nidx;
        
        // create the normal buffer. Assimp View creates a second normal buffer. Unsure why. Using only the interleaved normals for now.
        // This is here for reference.
        
        /*
        GLuint nhandle;
        glGenBuffers(1, &nhandle);
        glBindBuffer(GL_ARRAY_BUFFER, nhandle);
        glBufferData(GL_ARRAY_BUFFER, sizeof(aiVector3D)* mesh->mNumVertices, NULL, GL_STATIC_DRAW);

        // populate normals
        aiVector3D* normals = (aiVector3D*)glMapBuffer(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);

        for (unsigned int x = 0; x < mesh->mNumVertices; ++x)
        {
        aiVector3D vNormal = mesh->mNormals[x];
        *normals = vNormal;
        ++normals;
        }

        glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); //invalidates verts
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        meshHelper.normalBuffer = nhandle;
        */
        
        // Create VAO and populate it
        GLuint vaoHandle; 
        glGenVertexArraysAPPLE(1, &vaoHandle);
            
        // TODO: equivalent PC call.
        glBindVertexArrayAPPLE(vaoHandle);
        
        glBindBuffer(GL_ARRAY_BUFFER, meshHelper.vertexBuffer);
        
        glEnableClientState(GL_NORMAL_ARRAY);
        glNormalPointer(GL_FLOAT, sizeof(aiVertex), BUFFER_OFFSET(12));
        
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glTexCoordPointer(3, GL_FLOAT, sizeof(aiVertex), BUFFER_OFFSET(24));
        //TODO: handle second texture

        glEnableClientState(GL_COLOR_ARRAY);
        glColorPointer(4, GL_FLOAT, sizeof(aiVertex), BUFFER_OFFSET(36));
        
        // VertexPointer ought to come last, apparently this is some optimization, since if its set once first, it gets fiddled with every time something else is update.
        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(3, GL_FLOAT, sizeof(aiVertex), 0);
        
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshHelper.indexBuffer);
        
        glBindVertexArrayAPPLE(0);
       
        // save the VAO handle into our mesh helper
        meshHelper.vao = vaoHandle;
        
        modelMeshes.push_back(meshHelper);
    }
    ofLog(OF_LOG_VERBOSE, "finished loading gl resources");
}
//-------------------------------------------
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::loadGLResources(){

	ofLogVerbose("ofxAssimpModelLoader") << "loadGLResources(): starting";

    // create new mesh helpers for each mesh, will populate their data later.
    modelMeshes.resize(scene->mNumMeshes,ofxAssimpMeshHelper());

    // create OpenGL buffers and populate them based on each meshes pertinant info.
    for (unsigned int i = 0; i < scene->mNumMeshes; ++i){
        ofLogVerbose("ofxAssimpModelLoader") << "loadGLResources(): loading mesh " << i;
        // current mesh we are introspecting
        aiMesh* mesh = scene->mMeshes[i];

        // the current meshHelper we will be populating data into.
        ofxAssimpMeshHelper & meshHelper = modelMeshes[i];
        //ofxAssimpMeshHelper meshHelper;
		
        //meshHelper.texture = NULL;

        // Handle material info
        aiMaterial* mtl = scene->mMaterials[mesh->mMaterialIndex];
        aiColor4D dcolor, scolor, acolor, ecolor;

        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &dcolor)){
            meshHelper.material.setDiffuseColor(aiColorToOfColor(dcolor));
        }

        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &scolor)){
        	meshHelper.material.setSpecularColor(aiColorToOfColor(scolor));
        }

        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &acolor)){
        	meshHelper.material.setAmbientColor(aiColorToOfColor(acolor));
        }

        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &ecolor)){
        	meshHelper.material.setEmissiveColor(aiColorToOfColor(ecolor));
        }

        float shininess;
        if(AI_SUCCESS == aiGetMaterialFloat(mtl, AI_MATKEY_SHININESS, &shininess)){
			meshHelper.material.setShininess(shininess);
		}

        int blendMode;
		if(AI_SUCCESS == aiGetMaterialInteger(mtl, AI_MATKEY_BLEND_FUNC, &blendMode)){
			if(blendMode==aiBlendMode_Default){
				meshHelper.blendMode=OF_BLENDMODE_ALPHA;
			}else{
				meshHelper.blendMode=OF_BLENDMODE_ADD;
			}
		}

        // Culling
        unsigned int max = 1;
        int two_sided;
        if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)
            meshHelper.twoSided = true;
        else
            meshHelper.twoSided = false;

        // Load Textures
        int texIndex = 0;
        aiString texPath;

        // TODO: handle other aiTextureTypes
        if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath)){
            ofLogVerbose("ofxAssimpModelLoader") << "loadGLResource(): loading image from \"" << texPath.data << "\"";
            string modelFolder = file.getEnclosingDirectory();
            string relTexPath = ofFilePath::getEnclosingDirectory(texPath.data,false);
            string texFile = ofFilePath::getFileName(texPath.data);
            string realPath = ofFilePath::join(ofFilePath::join(modelFolder, relTexPath), texFile);
            
            if(ofFile::doesFileExist(realPath) == false) {
                ofLogError("ofxAssimpModelLoader") << "loadGLResource(): texture doesn't exist: \""
					<< file.getFileName() + "\" in \"" << realPath << "\"";
            }
            
            ofxAssimpTexture assimpTexture;
            bool bTextureAlreadyExists = false;
            for(int j=0; j<textures.size(); j++) {
                assimpTexture = textures[j];
                if(assimpTexture.getTexturePath() == realPath) {
                    bTextureAlreadyExists = true;
                    break;
                }
            }
            if(bTextureAlreadyExists) {
                meshHelper.assimpTexture = assimpTexture;
                ofLogVerbose("ofxAssimpModelLoader") << "loadGLResource(): texture already loaded: \""
					<< file.getFileName() + "\" from \"" << realPath << "\"";
            } else {
                ofTexture texture;
                bool bTextureLoadedOk = ofLoadImage(texture, realPath);
                if(bTextureLoadedOk) {
                    textures.push_back(ofxAssimpTexture(texture, realPath));
                    assimpTexture = textures.back();
                    meshHelper.assimpTexture = assimpTexture;
                    ofLogVerbose("ofxAssimpModelLoader") << "loadGLResource(): texture loaded, dimensions: "
						<< texture.getWidth() << "x" << texture.getHeight();
                } else {
                    ofLogError("ofxAssimpModelLoader") << "loadGLResource(): couldn't load texture: \""
						<< file.getFileName() + "\" from \"" << realPath << "\"";
                }
            }
        }

        meshHelper.mesh = mesh;
        aiMeshToOfMesh(mesh, meshHelper.cachedMesh, &meshHelper);
        meshHelper.cachedMesh.setMode(OF_PRIMITIVE_TRIANGLES);
        meshHelper.validCache = true;
        meshHelper.hasChanged = false;

        meshHelper.animatedPos.resize(mesh->mNumVertices);
        if(mesh->HasNormals()){
        	meshHelper.animatedNorm.resize(mesh->mNumVertices);
        }


        int usage;
        if(getAnimationCount()){
#ifndef TARGET_OPENGLES
        	if(!ofIsGLProgrammableRenderer()){
        		usage = GL_STATIC_DRAW;
        	}else{
        		usage = GL_STREAM_DRAW;
        	}
#else
        	usage = GL_DYNAMIC_DRAW;
#endif
        }else{
        	usage = GL_STATIC_DRAW;

        }

        meshHelper.vbo.setVertexData(&mesh->mVertices[0].x,3,mesh->mNumVertices,usage,sizeof(aiVector3D));
        if(mesh->HasVertexColors(0)){
        	meshHelper.vbo.setColorData(&mesh->mColors[0][0].r,mesh->mNumVertices,GL_STATIC_DRAW,sizeof(aiColor4D));
        }
        if(mesh->HasNormals()){
        	meshHelper.vbo.setNormalData(&mesh->mNormals[0].x,mesh->mNumVertices,usage,sizeof(aiVector3D));
        }
        if (meshHelper.cachedMesh.hasTexCoords()){			
        	meshHelper.vbo.setTexCoordData(meshHelper.cachedMesh.getTexCoordsPointer()[0].getPtr(),mesh->mNumVertices,GL_STATIC_DRAW,sizeof(ofVec2f));
        }

        meshHelper.indices.resize(mesh->mNumFaces * 3);
        int j=0;
        for (unsigned int x = 0; x < mesh->mNumFaces; ++x){
			for (unsigned int a = 0; a < mesh->mFaces[x].mNumIndices; ++a){
				meshHelper.indices[j++]=mesh->mFaces[x].mIndices[a];
			}
		}

        meshHelper.vbo.setIndexData(&meshHelper.indices[0],meshHelper.indices.size(),GL_STATIC_DRAW);

        //modelMeshes.push_back(meshHelper);
    }
    
    int numOfAnimations = scene->mNumAnimations;
    for(int i=0; i<numOfAnimations; i++) {
        aiAnimation * animation = scene->mAnimations[i];
        animations.push_back(ofxAssimpAnimation(scene, animation));
    }

    ofLogVerbose("ofxAssimpModelLoader") << "loadGLResource(): finished";
}
// DEPRECATED.
void ofxAssimpModelLoader::setAnimation(int animationIndex) {
    if(!hasAnimations()) {
        return;
    }
    currentAnimation = ofClamp(animationIndex, 0, getAnimationCount() - 1);
}
示例#13
0
Animation * AnimationMgr::getAnimation(unsigned index) const
{
   assert(index < getAnimationCount());
   return _animations[index].get();
}
示例#14
0
CCAFCAnimation* CCSPX3Sprite::getAnimationAt(int index, CCAFCClipMapping* mapping) {
	if(index < 0 || index >= getAnimationCount())
		return NULL;
	else
		return CCSPX3Manager::getInstance()->getAnimationData(m_spx, index, mapping);
}
示例#15
0
void AnimationMgr::setAnimationId(unsigned id)
{
   assert(id < getAnimationCount());
   _index = id;
   getAnimation(id)->resetFrames();
}
示例#16
0
Animation * AnimationMgr::getCurrentAnimation() const
{
   assert(getAnimationId() < getAnimationCount());
   return _animations[getAnimationId()].get();
}
示例#17
0
wyAFCAnimation* wyAuroraSprite::getAnimationAt(int index, wyAFCClipMapping* mapping) {
	if(index < 0 || index >= getAnimationCount())
		return NULL;
	else
		return wyAuroraManager::getInstance()->getAnimationData(m_aurora, index, mapping);
}
void ofxAssimpModelLoader::setTime(float t){ // 0 - 1
    if(getAnimationCount())
        updateAnimation(currentAnimation, t);
}
示例#19
0
    bool ModelMD2::loadModel(const char *filename, GLboolean is_absPath) {
        FILE *file;
        GLubyte buffer[MD2_MAX_FRAMESIZE];
        int i;

        file = fopen(Utils::getFileName(filename, is_absPath), "rb");

        if (!file)
            return false;

        /* initialize model and read header */
        fread (&m_header, sizeof (md2_header_t), 1, file);
#if DEBUG
        printf ("magic:\t\t%d\n", m_header.magic);
        printf ("version:\t\t%d\n", m_header.version);
        printf ("skinWidth:\t\t%d\n", m_header.skinWidth);
        printf ("skinHeight:\t\t%d\n", m_header.skinHeight);
        printf ("frameSize:\t\t%d\n", m_header.frameSize);
        printf ("numSkins:\t\t%d\n", m_header.numSkins);
        printf ("numVertices:\t\t%d\n", m_header.numVertices);
        printf ("numTexCoords:\t\t%d\n", m_header.numTexCoords);
        printf ("numTriangles:\t\t%d\n", m_header.numTriangles);
        printf ("numGlCommands:\t\t%d\n", m_header.numGlCommands);
        printf ("numFrames:\t\t%d\n", m_header.numFrames);
        printf ("offsetSkins:\t\t%d\n", m_header.offsetSkins);
        printf ("offsetTexCoords:\t%d\n", m_header.offsetTexCoords);
        printf ("offsetTriangles:\t%d\n", m_header.offsetTriangles);
        printf ("offsetFrames:\t\t%d\n", m_header.offsetFrames);
        printf ("offsetGlCommands:\t%d\n", m_header.offsetGlCommands);
        printf ("offsetEnd:\t\t%d\n", m_header.offsetEnd);
#endif

        if (m_header.magic != (int) (('2' << 24) + ('P' << 16) + ('D' << 8) + 'I')) {
            fclose(file);
            return false;
        }

        /* read skins */
        fseek (file, m_header.offsetSkins, SEEK_SET);
        if (m_header.numSkins > 0) {
            m_skins = (md2_skin_t *) malloc(sizeof(md2_skin_t) * m_header.numSkins);
            if (!m_skins) {
                //md2_freeModel (model);
                return false;
            }

            for (i = 0; i < m_header.numSkins; i++)
                fread (&m_skins[i], sizeof(md2_skin_t), 1, file);
        }

        /* read texture coordinates */
        fseek (file, m_header.offsetTexCoords, SEEK_SET);
        if (m_header.numTexCoords > 0) {
            m_texCoords = (md2_textureCoordinate_t *) malloc (sizeof (md2_textureCoordinate_t) * m_header.numTexCoords);
            if (!m_texCoords) {
                //md2_freeModel (model);
                return false;
            }

            for (i = 0; i < m_header.numTexCoords; i++)
                fread (&m_texCoords[i], sizeof (md2_textureCoordinate_t), 1, file);
        }

        /* read triangles */
        fseek (file, m_header.offsetTriangles, SEEK_SET);
        if (m_header.numTriangles > 0) {
            m_triangles = (md2_triangle_t *) malloc(sizeof(md2_triangle_t) * m_header.numTriangles);
            if (!m_triangles) {
                //md2_freeModel (model);
                return false;
            }

            for (i = 0; i < m_header.numTriangles; i++)
                fread (&m_triangles[i], sizeof (md2_triangle_t), 1, file);
        }

        /* read alias frames */
        fseek (file, m_header.offsetFrames, SEEK_SET);
        if (m_header.numFrames > 0) {
            m_frames = (md2_frame_t *) malloc (sizeof (md2_frame_t) * m_header.numFrames);
            if (!m_frames) {
                //md2_freeModel (model);
                return false;
            }

            for (i = 0; i < m_header.numFrames; i++) {
                md2_alias_frame_t *frame = (md2_alias_frame_t *) buffer;
                int j;

                m_frames[i].vertices = (md2_triangleVertex_t *) malloc (sizeof (md2_triangleVertex_t) * m_header.numVertices);
                if (!m_frames[i].vertices) {
                    //md2_freeModel (model);
                    return false;
                }

                fread (frame, 1, m_header.frameSize, file);
                strcpy (m_frames[i].name, frame->name);
                for (j = 0; j < m_header.numVertices; j++) {
                    m_frames[i].vertices[j].vertex[0] = (float) ((int) frame->alias_vertices[j].vertex[0]) * frame->scale[0] + frame->translate[0];
                    m_frames[i].vertices[j].vertex[2] = -1* ((float) ((int) frame->alias_vertices[j].vertex[1]) * frame->scale[1] + frame->translate[1]);
                    m_frames[i].vertices[j].vertex[1] = (float) ((int) frame->alias_vertices[j].vertex[2]) * frame->scale[2] + frame->translate[2];

                    m_frames[i].vertices[j].normal[0] = NORMALS_TABLE[frame->alias_vertices[j].lightNormalIndex][0];
                    m_frames[i].vertices[j].normal[1] = NORMALS_TABLE[frame->alias_vertices[j].lightNormalIndex][1];
                    m_frames[i].vertices[j].normal[2] = NORMALS_TABLE[frame->alias_vertices[j].lightNormalIndex][2];
                    //model->frames[i].vertices[j].lightNormalIndex = frame->alias_vertices[j].lightNormalIndex;
                }
            }
        }
        //ignore gl commands reading

        fclose (file);

        setTriangleNums(m_header.numTriangles);

        m_actionCount = getAnimationCount();
#if DEBUG
        printf("getAnimationCount:\t%d\n", m_actionCount);
#endif
        m_actions = (md2_action_t *) malloc(m_actionCount * sizeof(md2_action_t));
        for (i = 0; i < (int) m_actionCount; i++) {
            m_actions[i].index = i;
            strcpy (m_actions[i].name, getAnimationName(i));
            getAnimationFrames(i, &(m_actions[i].min_idx), &(m_actions[i].max_idx ));
#if DEBUG
            printf("m_actions[%d]:\t\t%s [%d, %d]\n", i, m_actions[i].name, m_actions[i].min_idx, m_actions[i].max_idx);
#endif
        }

        return true;
    }
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();
    }
}
//-------------------------------------------
void ofxAssimpModelLoader::loadGLResources(){

    ofLog(OF_LOG_VERBOSE, "loading gl resources");

    // create new mesh helpers for each mesh, will populate their data later.
   // modelMeshes.resize(scene->mNumMeshes,ofxAssimpMeshHelper());

    // create OpenGL buffers and populate them based on each meshes pertinant info.
    for (unsigned int i = 0; i < scene->mNumMeshes; ++i){
        ofLog(OF_LOG_VERBOSE, "loading mesh %u", i);
        // current mesh we are introspecting
        aiMesh* mesh = scene->mMeshes[i];

        // the current meshHelper we will be populating data into.
        //ofxAssimpMeshHelper & meshHelper = modelMeshes[i];
        ofxAssimpMeshHelper meshHelper;
		
        //meshHelper.texture = NULL;

        // Handle material info
        aiMaterial* mtl = scene->mMaterials[mesh->mMaterialIndex];
        aiColor4D dcolor, scolor, acolor, ecolor;

        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &dcolor)){
            meshHelper.material.setDiffuseColor(aiColorToOfColor(dcolor));
        }

        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &scolor)){
        	meshHelper.material.setSpecularColor(aiColorToOfColor(scolor));
        }

        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &acolor)){
        	meshHelper.material.setAmbientColor(aiColorToOfColor(acolor));
        }

        if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &ecolor)){
        	meshHelper.material.setEmissiveColor(aiColorToOfColor(ecolor));
        }

        float shininess;
        if(AI_SUCCESS == aiGetMaterialFloat(mtl, AI_MATKEY_SHININESS, &shininess)){
			meshHelper.material.setShininess(shininess);
		}

        int blendMode;
		if(AI_SUCCESS == aiGetMaterialInteger(mtl, AI_MATKEY_BLEND_FUNC, &blendMode)){
			if(blendMode==aiBlendMode_Default){
				meshHelper.blendMode=OF_BLENDMODE_ALPHA;
			}else{
				meshHelper.blendMode=OF_BLENDMODE_ADD;
			}
		}

        // Culling
        unsigned int max = 1;
        int two_sided;
        if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)
            meshHelper.twoSided = true;
        else
            meshHelper.twoSided = false;

        // Load Textures
        int texIndex = 0;
        aiString texPath;

        // TODO: handle other aiTextureTypes
        if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath)){
            ofLog(OF_LOG_VERBOSE, "loading image from %s", texPath.data);
            string modelFolder = ofFilePath::getEnclosingDirectory(filepath,false);
            string relTexPath = ofFilePath::getEnclosingDirectory(texPath.data,false);
            string texFile = ofFilePath::getFileName(texPath.data);
            string realPath = modelFolder + relTexPath  + texFile;
			if(!ofFile::doesFileExist(realPath) || !ofLoadImage(meshHelper.texture,realPath)) {
                ofLog(OF_LOG_ERROR,string("error loading image ") + filepath + " " +realPath);
			}else{
                ofLog(OF_LOG_VERBOSE, "texture width: %f height %f", meshHelper.texture.getWidth(), meshHelper.texture.getHeight());
			}
        }

        meshHelper.mesh = mesh;
        aiMeshToOfMesh(mesh, meshHelper.cachedMesh, &meshHelper);
        meshHelper.cachedMesh.setMode(OF_PRIMITIVE_TRIANGLES);
        meshHelper.validCache = true;
        meshHelper.hasChanged = false;

        meshHelper.animatedPos.resize(mesh->mNumVertices);
        if(mesh->HasNormals()){
        	meshHelper.animatedNorm.resize(mesh->mNumVertices);
        }


        int usage;
        if(getAnimationCount()){
#ifndef TARGET_OPENGLES
        	usage = GL_STREAM_DRAW;
#else
        	usage = GL_DYNAMIC_DRAW;
#endif
        }else{
        	usage = GL_STATIC_DRAW;

        }

        meshHelper.vbo.setVertexData(&mesh->mVertices[0].x,3,mesh->mNumVertices,usage,sizeof(aiVector3D));
        if(mesh->HasVertexColors(0)){
        	meshHelper.vbo.setColorData(&mesh->mColors[0][0].r,mesh->mNumVertices,GL_STATIC_DRAW,sizeof(aiColor4D));
        }
        if(mesh->HasNormals()){
        	meshHelper.vbo.setNormalData(&mesh->mNormals[0].x,mesh->mNumVertices,usage,sizeof(aiVector3D));
        }
        if (meshHelper.cachedMesh.hasTexCoords()){			
        	meshHelper.vbo.setTexCoordData(meshHelper.cachedMesh.getTexCoordsPointer()[0].getPtr(),mesh->mNumVertices,GL_STATIC_DRAW,sizeof(ofVec2f));
        }

        meshHelper.indices.resize(mesh->mNumFaces * 3);
        int j=0;
        for (unsigned int x = 0; x < mesh->mNumFaces; ++x){
			for (unsigned int a = 0; a < mesh->mFaces[x].mNumIndices; ++a){
				meshHelper.indices[j++]=mesh->mFaces[x].mIndices[a];
			}
		}

        meshHelper.vbo.setIndexData(&meshHelper.indices[0],meshHelper.indices.size(),GL_STATIC_DRAW);
        modelMeshes.push_back(meshHelper);
    }

    animationTime = -1;
    setNormalizedTime(0);

    ofLog(OF_LOG_VERBOSE, "finished loading gl resources");

}