Beispiel #1
0
  SkeletalAnimationModelLoader::MeshFrame SkeletalAnimationModelLoader::getMeshFrame(const MeshExtended &mesh) const {
    MeshFrame meshFrame(mesh);

    //Calculate new frame vertices and normals
    for (unsigned int cb = 0; cb < mesh.boneWeights.size(); cb++) {
      const auto &boneWeights = mesh.boneWeights[cb];

      aiMatrix4x4 transformat = transformation;
      const std::function<void(unsigned int)> calculateBoneTransformation = [&](unsigned int boneId) {
        if (bones[boneId].hasParentBoneId) {
          calculateBoneTransformation(bones[boneId].parentBoneId);
        }
        transformat *= bones[boneId].transformation;
      };
      calculateBoneTransformation(boneWeights.boneId);
      transformat *= boneWeights.offsetMatrix;

      for (auto &weight : boneWeights.weights) {
        meshFrame.vertices[weight.mVertexId] += weight.mWeight * (transformat * mesh.vertices[weight.mVertexId]);
        meshFrame.normals[weight.mVertexId] +=
            weight.mWeight * (aiMatrix3x3(transformat) * mesh.normals[weight.mVertexId]);
        meshFrame.tangents[weight.mVertexId] +=
            weight.mWeight * (aiMatrix3x3(transformat) * mesh.tangents[weight.mVertexId]);
      }
    }

    return meshFrame;
  }
void ofxAssimpModelLoader::updateBones() {
    // 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
		vector<aiMatrix4x4> boneMatrices(mesh->mNumBones);
		for(unsigned int 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
			aiNode* node = scene->mRootNode->FindNode(bone->mName);
            
			// start with the mesh-to-bone matrix
			boneMatrices[a] = bone->mOffsetMatrix;
			// and now append all node transformations down the parent chain until we're back at mesh coordinates again
			const aiNode* tempNode = node;
			while(tempNode) {
				// check your matrix multiplication order here!!!
				boneMatrices[a] = tempNode->mTransformation * boneMatrices[a];
				// boneMatrices[a] = boneMatrices[a] * tempNode->mTransformation;
				tempNode = tempNode->mParent;
			}
			modelMeshes[i].hasChanged = true;
			modelMeshes[i].validCache = false;
		}
        
		modelMeshes[i].animatedPos.assign(modelMeshes[i].animatedPos.size(), aiVector3D(0.0f));
		if(mesh->HasNormals()){
			modelMeshes[i].animatedNorm.assign(modelMeshes[i].animatedNorm.size(), aiVector3D(0.0f));
		}
		// loop through all vertex weights of all bones
		for(unsigned int a=0; a<mesh->mNumBones; ++a) {
			const aiBone* bone = mesh->mBones[a];
			const aiMatrix4x4& posTrafo = boneMatrices[a];
            
			for(unsigned int 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(unsigned int 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);
				}
			}
		}
	}
}
void MeshLoader::RenderMesh(const aiNode* node) {
	aiMatrix4x4 Mx = mAnimator->GetLocalTransform(node);
	Mx.Transpose();

	glPushMatrix();
	glMultMatrixf((float*)&Mx);

	for (unsigned int i = 0; i < node->mNumMeshes; i++) {
		const aiMesh* mesh = m_Scene->mMeshes[node->mMeshes[i]];
		std::vector<aiVector3D> CachedPosition(mesh->mNumVertices);
		std::vector<aiVector3D> CachedNormal(mesh->mNumVertices);
		if (mesh->HasBones()) {
			const std::vector<aiMatrix4x4>& boneMatrices = mAnimator->GetBoneMatrices(node, i);

			for (unsigned int a = 0; a < mesh->mNumBones; a++) {
				const aiBone *bone = mesh->mBones[a];
				const aiMatrix4x4& posTrafo = boneMatrices[a];
				aiMatrix3x3 normTrafo = aiMatrix3x3(posTrafo);
				for (unsigned int b = 0; b < bone->mNumWeights; b++)
				{
					const aiVertexWeight& weight = bone->mWeights[b];
					unsigned int vertexId = weight.mVertexId;
					const aiVector3D& srcPos = mesh->mVertices[vertexId];
					const aiVector3D& srcNorm = mesh->mNormals[vertexId];
					CachedPosition[vertexId] += weight.mWeight * (posTrafo * srcPos);
					CachedNormal[vertexId] += weight.mWeight * (normTrafo * srcNorm);
				}
			}
		}

		ApplyMaterial(m_Scene->mMaterials[mesh->mMaterialIndex]);

		for (unsigned int j = 0; j < mesh->mNumFaces; ++j) {
			const aiFace* face = &mesh->mFaces[j];
			glBegin(GL_TRIANGLES);
			for (unsigned int k = 0; k < face->mNumIndices; k++) {
				int v_index = face->mIndices[k];
				if (mesh->mColors[0] != NULL)
					glColor4fv((GLfloat*)&mesh->mColors[0][v_index]);
				if (mesh->mNormals != NULL)
					glNormal3fv(&CachedNormal[v_index].x);
				glVertex3fv(&CachedPosition[v_index].x);
			}
			glEnd();
		}
	}

	for (unsigned int i = 0; i < node->mNumChildren; i++) {
		RenderMesh(node->mChildren[i]);
	}
	glPopMatrix();

}
Beispiel #4
0
Model::Model(){
	yUp = false;
	modelScale = 1.0;

	MODEL_ROT_MAT = aiMatrix3x3(
		1, 0, 0,
		0, 0, 1,
		0, -1, 0
	);

	gettingVertsAndNormals = false;
}
Beispiel #5
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::updateAnimation(unsigned int animationIndex, float currentTime){

    const aiAnimation* mAnim = scene->mAnimations[animationIndex];

    // calculate the transformations for each animation channel
	for( unsigned int a = 0; a < mAnim->mNumChannels; a++)
	{
		const aiNodeAnim* channel = mAnim->mChannels[a];

        aiNode* targetNode = scene->mRootNode->FindNode(channel->mNodeName);

        // ******** Position *****
        aiVector3D presentPosition( 0, 0, 0);
        if( channel->mNumPositionKeys > 0)
        {
            // Look for present frame number. Search from last position if time is after the last time, else from beginning
            // Should be much quicker than always looking from start for the average use case.
            unsigned int frame = 0;// (currentTime >= lastAnimationTime) ? lastFramePositionIndex : 0;
            while( frame < channel->mNumPositionKeys - 1)
            {
                if( currentTime < channel->mPositionKeys[frame+1].mTime)
                    break;
                frame++;
            }

            // interpolate between this frame's value and next frame's value
            unsigned int nextFrame = (frame + 1) % channel->mNumPositionKeys;
            const aiVectorKey& key = channel->mPositionKeys[frame];
            const aiVectorKey& nextKey = channel->mPositionKeys[nextFrame];
            double diffTime = nextKey.mTime - key.mTime;
            if( diffTime < 0.0)
                diffTime += mAnim->mDuration;
            if( diffTime > 0)
            {
                float factor = float( (currentTime - key.mTime) / diffTime);
                presentPosition = key.mValue + (nextKey.mValue - key.mValue) * factor;
            } else
            {
                presentPosition = key.mValue;
            }
        }

        // ******** Rotation *********
        aiQuaternion presentRotation( 1, 0, 0, 0);
        if( channel->mNumRotationKeys > 0)
        {
            unsigned int frame = 0;//(currentTime >= lastAnimationTime) ? lastFrameRotationIndex : 0;
            while( frame < channel->mNumRotationKeys - 1)
            {
                if( currentTime < channel->mRotationKeys[frame+1].mTime)
                    break;
                frame++;
            }

            // interpolate between this frame's value and next frame's value
            unsigned int nextFrame = (frame + 1) % channel->mNumRotationKeys;
            const aiQuatKey& key = channel->mRotationKeys[frame];
            const aiQuatKey& nextKey = channel->mRotationKeys[nextFrame];
            double diffTime = nextKey.mTime - key.mTime;
            if( diffTime < 0.0)
                diffTime += mAnim->mDuration;
            if( diffTime > 0)
            {
                float factor = float( (currentTime - key.mTime) / diffTime);
                aiQuaternion::Interpolate( presentRotation, key.mValue, nextKey.mValue, factor);
            } else
            {
                presentRotation = key.mValue;
            }
        }

        // ******** Scaling **********
        aiVector3D presentScaling( 1, 1, 1);
        if( channel->mNumScalingKeys > 0)
        {
            unsigned int frame = 0;//(currentTime >= lastAnimationTime) ? lastFrameScaleIndex : 0;
            while( frame < channel->mNumScalingKeys - 1)
            {
                if( currentTime < channel->mScalingKeys[frame+1].mTime)
                    break;
                frame++;
            }

            // TODO: (thom) interpolation maybe? This time maybe even logarithmic, not linear
            presentScaling = channel->mScalingKeys[frame].mValue;
        }

        // build a transformation matrix from it
        //aiMatrix4x4& mat;// = mTransforms[a];
        aiMatrix4x4 mat = aiMatrix4x4( presentRotation.GetMatrix());
        mat.a1 *= presentScaling.x; mat.b1 *= presentScaling.x; mat.c1 *= presentScaling.x;
        mat.a2 *= presentScaling.y; mat.b2 *= presentScaling.y; mat.c2 *= presentScaling.y;
        mat.a3 *= presentScaling.z; mat.b3 *= presentScaling.z; mat.c3 *= presentScaling.z;
        mat.a4 = presentPosition.x; mat.b4 = presentPosition.y; mat.c4 = presentPosition.z;
        //mat.Transpose();

        targetNode->mTransformation = mat;

    }

    lastAnimationTime = currentTime;

    // 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<aiMatrix4x4> 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
			aiNode* node = scene->mRootNode->FindNode(bone->mName);

			// start with the mesh-to-bone matrix
			boneMatrices[a] = bone->mOffsetMatrix;
			// and now append all node transformations down the parent chain until we're back at mesh coordinates again
			const aiNode* tempNode = node;
			while( tempNode)
			{
				// check your matrix multiplication order here!!!
				boneMatrices[a] = tempNode->mTransformation * boneMatrices[a];
				// boneMatrices[a] = boneMatrices[a] * tempNode->mTransformation;
				tempNode = tempNode->mParent;
			}
			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 = 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);

				}
			}
		}
	}
}
// http://sourceforge.net/projects/assimp/forums/forum/817654/topic/3880745
void ofxAssimpModelLoader::updateGLResources(){
        
    // 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<aiMatrix4x4> 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
            aiNode* node = scene->mRootNode->FindNode(bone->mName);
            
            // start with the mesh-to-bone matrix 
            boneMatrices[a] = bone->mOffsetMatrix;
            // and now append all node transformations down the parent chain until we're back at mesh coordinates again
            const aiNode* tempNode = node;
            while( tempNode)
            {
                // check your matrix multiplication order here!!!
                boneMatrices[a] = tempNode->mTransformation * boneMatrices[a];   
                // boneMatrices[a] = boneMatrices[a] * tempNode->mTransformation;
                tempNode = tempNode->mParent;
            }
        }
        
        // all using the results from the previous code snippet
        std::vector<aiVector3D> resultPos( mesh->mNumVertices); 
        std::vector<aiVector3D> resultNorm( mesh->mNumVertices);
        
        // 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 = boneMatrices[a];
            
            // 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& srcPos = mesh->mVertices[vertexId];
                const aiVector3D& srcNorm = mesh->mNormals[vertexId];
                
                resultPos[vertexId] += weight.mWeight * (posTrafo * srcPos);
                resultNorm[vertexId] += weight.mWeight * (normTrafo * srcNorm);
            }
        }
                
        // now upload the result position and normal along with the other vertex attributes into a dynamic vertex buffer, VBO or whatever
        
        // get mesh helper for this mesh;
        ofxAssimpMeshHelper meshHelper = modelMeshes[i];
        
        glBindBuffer(GL_ARRAY_BUFFER, meshHelper.vertexBuffer);
        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];
            verts->vPosition = resultPos[x];
            
            if (NULL == mesh->mNormals)
                verts->vNormal = aiVector3D(0.0f,0.0f,0.0f);
            else
                verts->vNormal = resultNorm[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);
    }
}
Beispiel #8
0
void Mesh::init_mesh(const aiScene* scene, const aiMesh* mesh, size_t index) {

    std::cout << "Loading mesh named '" << mesh->mName.C_Str() << "'" << std::endl;

    entries[index].material_index = mesh->mMaterialIndex;

    if (!mesh->HasNormals()) {
        std::cerr << "Mesh has no normals!" << std::endl;
    } else {
        if (mesh->mNumVertices > 0)
            std::cerr << "First normal:" << mesh->mNormals[0].x << "," << mesh->mNormals[0].y << "," << mesh->mNormals[0].z << std::endl;
    }

    // Create vectors to store the transformed position and normals; initialize them to the origin.
    std::vector<aiVector3D> final_pos(mesh->mNumVertices),
        final_normal(mesh->mNumVertices);
    for (size_t i = 0; i < mesh->mNumVertices; ++i) {
        final_pos[i] = final_normal[i] = aiVector3D(0.0, 0.0, 0.0);
    }


    std::vector<Vertex> vertices;
    std::vector<unsigned int> indices;

    const aiVector3D zero_3d(0.0, 0.0, 0.0);


    if (mesh->mNumBones) {
        std::vector<aiMatrix4x4> bone_matrices(mesh->mNumBones);

        // Calculate bone matrices.
        for (size_t i = 0; i < mesh->mNumBones; ++i) {
            const aiBone* bone = mesh->mBones[i];
            bone_matrices[i] = bone->mOffsetMatrix;

            std::cout << "Bone '" << bone->mName.C_Str() << "' includes " << bone->mNumWeights << " vertices:" << std::endl;
            for (size_t j = 0; j < bone->mNumWeights; ++j) {
                std::cout << ' ' << bone->mWeights[j].mVertexId;
            }
            std::cout << std::endl;

            const aiNode* node = scene->mRootNode->FindNode(bone->mName.C_Str());
            const aiNode* temp_node = node;
            while (temp_node != NULL) {
                bone_matrices[i] = temp_node->mTransformation * bone_matrices[i];
                temp_node = temp_node->mParent;
            }
        }

        // Update vertex positions according to calculated matrices
        for (size_t i = 0; i < mesh->mNumBones; ++i) {
            const aiBone* bone = mesh->mBones[i];
            aiMatrix3x3 normal_matrix = aiMatrix3x3(bone_matrices[i]);

            for (size_t j = 0; j < bone->mNumWeights; ++j) {
                const aiVertexWeight *vertex_weight = &(bone->mWeights[j]);
                size_t v = (size_t)(vertex_weight->mVertexId);
                float  w = vertex_weight->mWeight;

                const aiVector3D *src_pos = &(mesh->mVertices[v]);
                const aiVector3D *src_normal = &(mesh->mNormals[v]);

                final_pos[v]    += w * (bone_matrices[i] * (*src_pos));
                final_normal[v] += w * (normal_matrix * (*src_normal));
            }

            std::cout << "bone " << i << ":" << std::endl;
            std::cout << bone_matrices[i].a1 << ' ' << bone_matrices[i].a2 << ' ' << bone_matrices[i].a3 << ' ' << bone_matrices[i].a4 << std::endl;
            std::cout << bone_matrices[i].b1 << ' ' << bone_matrices[i].b2 << ' ' << bone_matrices[i].b3 << ' ' << bone_matrices[i].b4 << std::endl;
            std::cout << bone_matrices[i].c1 << ' ' << bone_matrices[i].c2 << ' ' << bone_matrices[i].c3 << ' ' << bone_matrices[i].c4 << std::endl;
            std::cout << bone_matrices[i].d1 << ' ' << bone_matrices[i].d2 << ' ' << bone_matrices[i].d3 << ' ' << bone_matrices[i].d4 << std::endl;
        }

        // initialize our dimension trackers.
        if (mesh->mNumVertices != 0) {
            min_extremities.x = final_pos[0].x;
            min_extremities.y = final_pos[0].y;
            min_extremities.z = final_pos[0].z;
            max_extremities = min_extremities;
        }

        // Add each updated vertex and calculate its extremities.
        for (size_t i = 0; i < mesh->mNumVertices; ++i) {
            const aiVector3D *diffuse_texture_coord = mesh->HasTextureCoords(0) ? &(mesh->mTextureCoords[0][i]) : &zero_3d;
            const aiVector3D *specular_texture_coord = mesh->HasTextureCoords(1) ? &(mesh->mTextureCoords[1][i]) : &zero_3d;

            // Find the extremities of this mesh so we can get a measurement for the object in object units.
            if (final_pos[i].x < min_extremities.x) min_extremities.x = final_pos[i].x;
            else if (final_pos[i].x > max_extremities.x) max_extremities.x = final_pos[i].x;

            if (final_pos[i].y < min_extremities.y) min_extremities.y = final_pos[i].y;
            else if (final_pos[i].y > max_extremities.y) max_extremities.y = final_pos[i].y;

            if (final_pos[i].z < min_extremities.z) min_extremities.z = final_pos[i].z;
            else if (final_pos[i].z > max_extremities.z) max_extremities.z = final_pos[i].z;


            Vertex vertex(glm::vec3(final_pos[i].x, final_pos[i].y, final_pos[i].z),
                          glm::vec2(diffuse_texture_coord->x, diffuse_texture_coord->y),
                          glm::vec2(specular_texture_coord->x, specular_texture_coord->y),
                          glm::vec3(final_normal[i].x, final_normal[i].y, final_normal[i].z));

            std::cout << "Adding vertex " << i << ": " << final_pos[i].x << "," << final_pos[i].y << "," << final_pos[i].z;
            std::cout << "\t" << final_normal[i].x << "," << final_normal[i].y << "," << final_normal[i].z << std::endl;
            std::cout << "  was: " << mesh->mVertices[i].x << "," << mesh->mVertices[i].y << "," << mesh->mVertices[i].z << '\t';
            std::cout << mesh->mNormals[i].x << "," << mesh->mNormals[i].y << "," << mesh->mNormals[i].z << std::endl;

            // Accumulate the centroid_ of the object.
            centroid_ += vertex.pos;

            vertices.push_back(vertex);
        }
    } else {
        for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
            const aiVector3D* pos    = &(mesh->mVertices[i]);
            const aiVector3D* normal = &(mesh->mNormals[i]);

            const aiVector3D* diffuse_texture_coord = mesh->HasTextureCoords(0) ? &(mesh->mTextureCoords[0][i]) : &zero_3d;
            const aiVector3D* specular_texture_coord = mesh->HasTextureCoords(1) ? &(mesh->mTextureCoords[1][i]) : &zero_3d;

            // Find the extremities of this mesh so we can get a measurement for the object in object units.
            if (pos->x < min_extremities.x)       min_extremities.x = pos->x;
            else if (pos->x > max_extremities.x)  max_extremities.x = pos->x;

            if (pos->y < min_extremities.y)       min_extremities.y = pos->y;
            else if (pos->y > max_extremities.y)  max_extremities.y = pos->y;

            if (pos->z < min_extremities.z)       min_extremities.z = pos->z;
            else if (pos->z > max_extremities.z)  max_extremities.z = pos->z;

            Vertex v(glm::vec3(pos->x, pos->y, pos->z),
                     glm::vec2(diffuse_texture_coord->x, diffuse_texture_coord->y),
                     glm::vec2(specular_texture_coord->x, specular_texture_coord->y),
                     glm::vec3(normal->x, normal->y, normal->z));

            // Accumulate the centroid_ of the object.
            centroid_ += v.pos;

            vertices.push_back(v);
        }
    }

    centroid_ /= mesh->mNumVertices;

    // Add vertices for each face
    for (size_t i = 0; i < mesh->mNumFaces; ++i) {
        const aiFace& face = mesh->mFaces[i];
        if (face.mNumIndices != 3) {
            std::cerr << "Face has " << face.mNumIndices << " indices; skipping" << std::endl;
            continue;
        }
        indices.push_back(face.mIndices[0]);
        indices.push_back(face.mIndices[1]);
        indices.push_back(face.mIndices[2]);
    }


    // Create index buffer.
    entries[index].init(vertices, indices);
}
Beispiel #9
0
void Model::recursiveRender(const aiNode* node){
	LOGGER_ENTER("Model", "recursiveRender");
	glPushMatrix();
	int m = node->mNumMeshes;
	aiMatrix4x4 masterTransform = node->mTransformation;

	/* Iterate through the node's meshes */
	for(int i = 0; i < m; i++){
		aiMesh* mesh = model->mMeshes[node->mMeshes[i]];

		Mesh m;
		if(gettingVertsAndNormals){
			m.mNumVertices = mesh->mNumVertices;
			m.vertices = new glm::vec3[m.mNumVertices];
			m.normals = new glm::vec3[m.mNumVertices];
			m.numFaces = mesh->mNumFaces;
			m.faceVertexIndices = new int*[m.numFaces];
			m.name = mesh->mName.C_Str();
		}

		aiVector3D* vertices = mesh->mVertices;
		aiVector3D* normals = mesh->mNormals;

		/*** Calculate Skeleton Transformations and Resulting Vertex Trasformations ***/
		if(mesh->HasBones()){
			vertices = new aiVector3D[mesh->mNumVertices];
			normals = new aiVector3D[mesh->mNumVertices];
			
			for(unsigned int b = 0; b < mesh->mNumBones; b++){
				aiMatrix4x4 boneMatrix;
				const aiBone* bone = mesh->mBones[b];

				aiNode* boneNode = findNodeRecurse(model->mRootNode, bone->mName);

				boneMatrix = bone->mOffsetMatrix;
				const aiNode* tmpNode = boneNode;
				while(tmpNode){
					boneMatrix = tmpNode->mTransformation * boneMatrix;
					tmpNode = tmpNode->mParent;
				}

				const aiMatrix4x4& posTransform = boneMatrix;
				const aiMatrix3x3 normalTransform = aiMatrix3x3(posTransform);

				for(unsigned int w = 0; w < bone->mNumWeights; w++){
					const aiVertexWeight& weight = bone->mWeights[w];
					unsigned int vertexID = weight.mVertexId;
					const aiVector3D& srcPos = mesh->mVertices[vertexID];
					const aiVector3D& srcNormal = mesh->mNormals[vertexID];

					vertices[vertexID] += weight.mWeight * (posTransform * srcPos);
					normals[vertexID] += weight.mWeight * (normalTransform * srcNormal);
				}
			}
		}

		/* Bind the texture if a diffuse texture exists */
		aiMaterial* mat = model->mMaterials[mesh->mMaterialIndex];
		int texIndex = 0;
		aiString texPath;
		if(AI_SUCCESS == mat->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath))    {
			unsigned int texId = textureIdMap[texPath.data];
			glBindTexture(GL_TEXTURE_2D, texId);
		}
		
		aiString matName;
		mat->Get(AI_MATKEY_NAME,matName);

		aiColor3D matDiffuseColour(0,0,0);
		if(mat->Get(AI_MATKEY_COLOR_DIFFUSE,matDiffuseColour) == AI_SUCCESS){
			float fMatDiffuseColour[] = {matDiffuseColour.r, matDiffuseColour.g, matDiffuseColour.b};
			glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fMatDiffuseColour);
		}

		aiColor3D matSpecularColour(0,0,0);
		if(mat->Get(AI_MATKEY_COLOR_SPECULAR,matSpecularColour) == AI_SUCCESS){
			float fMatSpecularColour[] = {matSpecularColour.r, matSpecularColour.g, matSpecularColour.b};
			glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fMatSpecularColour);
		}

		aiColor3D matAmbientColour(0,0,0);
		if(mat->Get(AI_MATKEY_COLOR_AMBIENT,matAmbientColour) == AI_SUCCESS){
			float fMatAmbientColour[] = {matAmbientColour.r, matAmbientColour.g, matAmbientColour.b};
			glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, fMatAmbientColour);
		}
		
			/* Draw Mesh Faces (Textures) */
			aiVector3D* texCoords = mesh->mTextureCoords[0];
			for(unsigned int j = 0; j < mesh->mNumFaces; j++){
				unsigned int* indices = mesh->mFaces[j].mIndices;
				aiVector3D n1, n2, n3, v1, v2, v3;
				
				if(mesh->HasBones()){
					n1 = normals[indices[0]];
					n2 = normals[indices[1]];
					n3 = normals[indices[2]];
					v1 = vertices[indices[0]];
					v2 = vertices[indices[1]];
					v3 = vertices[indices[2]];
				}else{
					n1 = MODEL_ROT_MAT * (masterTransform * normals[indices[0]]);
					n2 = MODEL_ROT_MAT * (masterTransform * normals[indices[1]]);
					n3 = MODEL_ROT_MAT * (masterTransform * normals[indices[2]]);
					v1 = MODEL_ROT_MAT * (masterTransform * vertices[indices[0]]);
					v2 = MODEL_ROT_MAT * (masterTransform * vertices[indices[1]]);
					v3 = MODEL_ROT_MAT * (masterTransform * vertices[indices[2]]);
				}

				glm::vec3 tmpV1(v1.x,v1.y,v1.z);
				glm::vec3 tmpV2(v2.x,v2.y,v2.z);
				glm::vec3 tmpV3(v3.x,v3.y,v3.z);
				glm::vec3 faceNormal = glm::normalize(glm::cross(tmpV3 - tmpV2, tmpV1 - tmpV2));

				if(gettingVertsAndNormals){
					glm::vec3 tmpN1(n1.x,n1.y,n1.z);
					glm::vec3 tmpN2(n2.x,n2.y,n2.z);
					glm::vec3 tmpN3(n3.x,n3.y,n3.z);

					m.vertices[indices[0]] = tmpV1;
					m.vertices[indices[1]] = tmpV2;
					m.vertices[indices[2]] = tmpV3;
					m.normals[indices[0]] = faceNormal;
					m.normals[indices[1]] = faceNormal;
					m.normals[indices[2]] = faceNormal;

					m.faceVertexIndices[j] = new int[3];
					m.faceVertexIndices[j][0] = indices[0];
					m.faceVertexIndices[j][1] = indices[1];
					m.faceVertexIndices[j][2] = indices[2];

					meshesMap[matName.C_Str()] = m;
				}else{
					glBegin(GL_POLYGON);
					
					if(mesh->HasTextureCoords(0)) glTexCoord2f(texCoords[indices[0]].x, 1 - texCoords[indices[0]].y);
					glNormal3f(faceNormal.x, faceNormal.y, faceNormal.z);
					glVertex3f(v1.x, v1.y, v1.z);
					if(mesh->HasTextureCoords(0)) glTexCoord2f(texCoords[indices[1]].x, 1 - texCoords[indices[1]].y);
					glVertex3f(v2.x, v2.y, v2.z);
					if(mesh->HasTextureCoords(0)) glTexCoord2f(texCoords[indices[2]].x, 1 - texCoords[indices[2]].y);
					glVertex3f(v3.x, v3.y, v3.z);
					glEnd();
				}
			}

			/* Free the memory that was used for the animated vertices and normals */
			if(mesh->HasBones()){
				free(normals);
				free(vertices);
			}

		/* Remove any texture binding */
		glBindTexture(GL_TEXTURE_2D, NULL);
	}

	/* Recurse Through Child Nodes */
	for(unsigned int i = 0; i < node->mNumChildren; i++){
		recursiveRender(node->mChildren[i]);
	}
	glPopMatrix();
	LOGGER_EXIT;
}
Beispiel #10
0
// Recursively traverses the assimp node hierarchy, accumulating
// modeling transformations, and creating and transforming any meshes
// found.  Meshes comming from assimp can have associated surface
// properties, so each mesh *copies* the current BRDF as a starting
// point and modifies it from the assimp data structure.
void recurseModelNodes(Scene* scene,
                       const aiScene* aiscene,
                       const aiNode* node,
                       const aiMatrix4x4& parentTr,
                       const int level)
{
    // Print line with indentation to show structure of the model node hierarchy.
    for (int i=0;  i<level;  i++) printf("| ");
    printf("%s ", node->mName.data);

    // Accumulating transformations while traversing down the hierarchy.
    aiMatrix4x4 childTr = parentTr*node->mTransformation;
    aiMatrix3x3 normalTr = aiMatrix3x3(childTr); // Really should be inverse-transpose for full generality
     
    // Loop through this node's meshes
    for (unsigned int i=0;  i<node->mNumMeshes; ++i) {
        aiMesh* aimesh = aiscene->mMeshes[node->mMeshes[i]];
        printf("%d:%d ", aimesh->mNumVertices, aimesh->mNumFaces);

        // Extract this node's surface material.
        aiString texPath;
        aiMaterial* mtl = aiscene->mMaterials[aimesh->mMaterialIndex];

        // Assimp can read material colors from the input files, but
        // it seems to invent colors of its own unpredictably so I
        // ignore them.  Textures and texture coordinates seem to work
        // well.
        
        //aiColor3D diff (0.f,0.f,0.f); 
        //aiColor3D spec (0.f,0.f,0.f); 
        //float s;
        // if (AI_SUCCESS == mtl->Get(AI_MATKEY_COLOR_DIFFUSE, diff))
        //     scene->setKd(Vector3f(diff.r, diff.g, diff.b));
        // if (AI_SUCCESS == mtl->Get(AI_MATKEY_COLOR_SPECULAR, spec))
        //     scene->setKs(Vector3f(spec.r, spec.g, spec.b));
        // if (AI_SUCCESS == mtl->Get(AI_MATKEY_SHININESS, &s, NULL))
        //     scene->setAlpha(s);
        
        Material *material = new Material(*scene->currentMat);
        if (AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, 0, &texPath))
            material->setTexture(texPath.C_Str());

        // Arrays to hold all vertex and triangle data.
        MeshData* meshdata = new MeshData;
        
        // Loop through all vertices and record the
        // vertex/normal/texture/tangent data with the node's model
        // transformation applied.
        for (unsigned int t=0;  t<aimesh->mNumVertices;  ++t) {
            aiVector3D aipnt = childTr*aimesh->mVertices[t];
            aiVector3D ainrm = aimesh->HasNormals() ? normalTr*aimesh->mNormals[t] : aiVector3D(0,0,1);
            aiVector3D aitex = aimesh->HasTextureCoords(0) ? aimesh->mTextureCoords[0][t] : aiVector3D(0,0,0);
            aiVector3D aitan = aimesh->HasTangentsAndBitangents() ? normalTr*aimesh->mTangents[t] :  aiVector3D(1,0,0);

          
            meshdata->vertices.push_back(VertexData(Vector3f(aipnt.x, aipnt.y, aipnt.z),
                                                    Vector3f(ainrm.x, ainrm.y, ainrm.z),
                                                    Vector2f(aitex.x, aitex.y),
                                                    Vector3f(aitan.x, aitan.y, aitan.z))); }
        
        // Loop through all faces, recording indices
        for (unsigned int t=0;  t<aimesh->mNumFaces;  ++t) {
            aiFace* aiface = &aimesh->mFaces[t];
            meshdata->triangles.push_back(TriData(aiface->mIndices[0],
                                                  aiface->mIndices[1],
                                                  aiface->mIndices[2])); }
        meshdata->mat = material;
        
        scene->triangleMesh(meshdata);

		delete meshdata;
	}

    printf("\n");

    // Recurse onto this node's children
    for (unsigned int i=0;  i<node->mNumChildren;  ++i)
      recurseModelNodes(scene, aiscene, node->mChildren[i], childTr, level+1);
}