예제 #1
0
aiMatrix4x4 GetMeshBakingTransform(aiNode* meshNode, aiNode* modelRootNode)
{
    if (meshNode == modelRootNode)
        return aiMatrix4x4();
    else
        return GetDerivedTransform(meshNode, modelRootNode);
}
예제 #2
0
// ------------------------------------------------------------------------------------------------
// Calculates the bone matrices for the given mesh. 
const std::vector<aiMatrix4x4>& SceneAnim::GetBoneMatrices( const aiNode* pNode, size_t pMeshIndex /* = 0 */)
{
	ai_assert( pMeshIndex < pNode->mNumMeshes);
	size_t meshIndex = pNode->mMeshes[pMeshIndex];
	ai_assert( meshIndex < mScene->mNumMeshes);
	const aiMesh* mesh = mScene->mMeshes[meshIndex];

	// resize array and initialise it with identity matrices
	mTransforms.resize( mesh->mNumBones, aiMatrix4x4());

	// calculate the mesh's inverse global transform
	aiMatrix4x4 globalInverseMeshTransform = GetGlobalTransform( pNode);
	globalInverseMeshTransform.Inverse();

	// Bone matrices transform from mesh coordinates in bind pose to mesh coordinates in skinned pose
	// Therefore the formula is offsetMatrix * currentGlobalTransform * inverseCurrentMeshTransform
	for( size_t a = 0; a < mesh->mNumBones; ++a)
	{
		const aiBone* bone = mesh->mBones[a];
		const aiMatrix4x4& currentGlobalTransform = GetGlobalTransform( mBoneNodesByName[ bone->mName.data ]);
		mTransforms[a] = globalInverseMeshTransform * currentGlobalTransform * bone->mOffsetMatrix;
	}

	// and return the result
	return mTransforms;
}
예제 #3
0
Bone::Bone(aiMatrix4x4 transform, aiMatrix4x4 global, Bone* parent) :
	m_transform(transform),
	m_global(global),
	m_parent(parent)
{
	m_numChildren=0;
	m_offset = aiMatrix4x4();
}
예제 #4
0
static inline aiMatrix4x4 ofMatrix4x4ToAiMatrix44(const ofMatrix4x4 &m)
{
	const float *d = m.getPtr();
	return aiMatrix4x4(d[0], d[4], d[8], d[12],
					d[1], d[5], d[9], d[13],
					d[2], d[6], d[10], d[14],
					d[3], d[7], d[11], d[15]);
}
예제 #5
0
파일: glview.cpp 프로젝트: cuigrey/assimp
void CGLView::Camera_Set(const size_t pCameraNumber)
{
SHelper_Camera& hcam = mHelper_Camera;// reference with short name for conveniance.
aiVector3D up;

	if(mCamera_DefaultAdded || (pCameraNumber >= mScene->mNumCameras))// If default camera used then 'pCameraNumber' doesn't matter.
	{
		// Transformation parameters
		hcam = mHelper_CameraDefault;
		up.Set(0, 1, 0);
	}
	else
	{
		const aiCamera& camera_cur = *mScene->mCameras[pCameraNumber];
		const aiNode* camera_node;

		aiMatrix4x4 camera_mat;
		aiQuaternion camera_quat_rot;
		aiVector3D camera_tr;

		up = camera_cur.mUp;
		//
		// Try to get real coordinates of the camera.
		//
		// Find node
		camera_node = mScene->mRootNode->FindNode(camera_cur.mName);
		if(camera_node != nullptr) Matrix_NodeToRoot(camera_node, camera_mat);

		hcam.Position = camera_cur.mLookAt;
		hcam.Target = camera_cur.mPosition;
		hcam.Rotation_AroundCamera = aiMatrix4x4(camera_quat_rot.GetMatrix());
		hcam.Rotation_AroundCamera.Transpose();
		// get components of transformation matrix.
		camera_mat.DecomposeNoScaling(camera_quat_rot, camera_tr);
		hcam.Rotation_Scene = aiMatrix4x4();
		hcam.Translation_ToScene = camera_tr;
	}

	// Load identity matrix - travel to world begin.
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	// Set camera and update picture
	gluLookAt(hcam.Position.x, hcam.Position.y, hcam.Position.z, hcam.Target.x, hcam.Target.y, hcam.Target.z, up.x, up.y, up.z);
}
aiMatrix4x4 NCAssimpModel::returnRotation(aiMatrix4x4 incmat) {
    aiVector3D pos;
    aiQuaternion quat;
    aiVector3D scale;
    incmat.DecomposeNoScaling(quat, pos);
    aiMatrix4x4 toreturn = aiMatrix4x4(quat.GetMatrix());
    
    return toreturn;
    
}
예제 #7
0
void Mesh::ReadNodeHeirarchyCont(float AnimationTime, 
				 const aiNode* pNode, 
				 const glm::mat4& ParentTf,
				 unsigned int anim_index)
{
  std::string NodeName(pNode->mName.data);
  glm::mat4 NodeTf;
  CopyaiMat(pNode->mTransformation, NodeTf);

  // NOTE: the skeleton must use the same naming convention used by the .bvh files
  if(_b2i_map.find(NodeName) == _b2i_map.end())
    {
      printf("Node: %15s\n", NodeName.c_str());
      return;  // bone does not exist
    }
  //  const aiNodeAnim* pNodeAnim=FindNodeAnim(_pSceneMesh->mAnimations[anim_index],NodeName);
  const aiNodeAnim* pNodeAnim = _channels[anim_index][NodeName];

  if(pNodeAnim)
    {
      // Interpolate scaling and generate scaling transformation matrix
      aiVector3D sc;
      CalcInterpolatedScaling(sc, AnimationTime, pNodeAnim);
      glm::mat4 ScMat=glm::scale(glm::mat4(1.0f),
				 glm::vec3(sc.x, sc.y, sc.z));

      //     printf("Node name: %s: Sc: %f %f %f\n", NodeName.c_str(), sc.x, sc.y, sc.z);

      aiQuaternion quat;
      CalcInterpolatedRotation(quat, AnimationTime, pNodeAnim);
      glm::mat4 RotMat;
      CopyaiMat(aiMatrix4x4(quat.GetMatrix()), RotMat);
      
      aiVector3D tran;
      CalcInterpolatedPosition(tran, AnimationTime, pNodeAnim);
      glm::mat4 TranMat = glm::translate(glm::mat4(1.0f),
					 glm::vec3(tran.x, tran.y, tran.z));

      NodeTf = TranMat*RotMat*ScMat;
    }
  
  glm::mat4 GlobalTf = ParentTf * NodeTf;
  unsigned int BoneIdx = _b2i_map[NodeName];
  _boneTfs[BoneIdx].FinalTf= _globalInvTf * GlobalTf * _boneTfs[BoneIdx].Offset;

  for(unsigned int i=0; i< pNode->mNumChildren; i++)
    {
      ReadNodeHeirarchyCont(AnimationTime, pNode->mChildren[i], GlobalTf, anim_index);
    }
}
aiBone* makeBone(const char* name,
                 aiVertexWeight weights[],
                 unsigned int numWeights) {
    aiVertexWeight* heapedWeights = new aiVertexWeight[numWeights];
    memcpy(heapedWeights, weights, numWeights * sizeof(aiVertexWeight));

    aiBone* bone = new aiBone();
    bone->mName = aiString(name);
    bone->mNumWeights = numWeights;
    bone->mOffsetMatrix = aiMatrix4x4();
    bone->mWeights = heapedWeights;

    return bone;
}
예제 #9
0
void Mesh::ReadNodeHeirarchyDisc(uint frame_index,
				 const aiNode* pNode,
				 const glm::mat4& ParentTf,
				 uint anim_index)
{
  std::string NodeName(pNode->mName.data);
  glm::mat4 NodeTf;
  CopyaiMat(pNode->mTransformation, NodeTf);

  if(_b2i_map.find(NodeName) == _b2i_map.end())
    {
      printf("Node: %15s\n", NodeName.c_str());
      return;  // bone does not exist
    }
  const aiNodeAnim* pNodeAnim = _channels[anim_index][NodeName];

  // assume all transform types share the same amount of keys
  frame_index = frame_index % pNodeAnim->mNumPositionKeys; 
  const aiVector3D&   sc = pNodeAnim->mScalingKeys[frame_index].mValue;
  const aiQuaternion& qt = pNodeAnim->mRotationKeys[frame_index].mValue;
  const aiVector3D&   tr = pNodeAnim->mPositionKeys[frame_index].mValue;

  glm::mat4 ScMat=glm::scale(glm::mat4(1.0f),
			     glm::vec3(sc.x, sc.y, sc.z));

  glm::mat4 RotMat;
  CopyaiMat(aiMatrix4x4(qt.GetMatrix()), RotMat);

  glm::mat4 TranMat = glm::translate(glm::mat4(1.0f),
				     glm::vec3(tr.x, tr.y, tr.z));

  NodeTf = TranMat * RotMat * ScMat;

  glm::mat4 GlobalTf = ParentTf * NodeTf;
  unsigned int BoneIdx = _b2i_map[NodeName];
  _boneTfs[BoneIdx].FinalTf= _globalInvTf * GlobalTf * _boneTfs[BoneIdx].Offset;

  // For debugging: print joint position in 3D:
  printf("%-15s %7.4f %7.4f %7.4f\n", pNode->mName.data, 
	 _boneTfs[BoneIdx].FinalTf[3][0], _boneTfs[BoneIdx].FinalTf[3][1], _boneTfs[BoneIdx].FinalTf[3][2]);

  // recursively update the children bones
  for(unsigned int i=0; i< pNode->mNumChildren; i++)
    ReadNodeHeirarchyDisc(frame_index, pNode->mChildren[i], GlobalTf, anim_index);
}
예제 #10
0
파일: glview.cpp 프로젝트: cuigrey/assimp
void CGLView::Matrix_NodeToRoot(const aiNode* pNode, aiMatrix4x4& pOutMatrix)
{
const aiNode* node_cur;
std::list<aiMatrix4x4> mat_list;

	pOutMatrix = aiMatrix4x4();
	// starting walk from current element to root
	node_cur = pNode;
	if(node_cur != nullptr)
	{
		do
		{
			// if cur_node is group then store group transformation matrix in list.
			mat_list.push_back(node_cur->mTransformation);
			node_cur = node_cur->mParent;
		} while(node_cur != nullptr);
	}

	// multiplicate all matrices in reverse order
	for(std::list<aiMatrix4x4>::reverse_iterator rit = mat_list.rbegin(); rit != mat_list.rend(); rit++) pOutMatrix = pOutMatrix * (*rit);
}
예제 #11
0
파일: ShapeMesh.cpp 프로젝트: Tarrasch/dart
    const aiScene* ShapeMesh::loadMesh(const string& fileName) {
        aiPropertyStore* propertyStore = aiCreatePropertyStore();
        aiSetImportPropertyInteger(propertyStore, AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_POINT | aiPrimitiveType_LINE ); // remove points and lines
        const aiScene* scene = aiImportFileExWithProperties(fileName.c_str(), aiProcess_GenNormals             |
                                                                              aiProcess_Triangulate            |
                                                                              aiProcess_JoinIdenticalVertices  |
                                                                              aiProcess_SortByPType            |
                                                                              aiProcess_OptimizeMeshes,
                                                            NULL, propertyStore);
        aiReleasePropertyStore(propertyStore);

        // Assimp rotates collada files such that the up-axis (specified in the collada file) aligns with assimp's y-axis.
        // Here we are reverting this rotation.
        // We are only catching files with the .dae file ending here. We might miss files with an .xml file ending,
        // which would need to be looked into to figure out whether they are collada files.
        if(fileName.length() >= 4 && fileName.substr(fileName.length() - 4, 4) == ".dae") {
            scene->mRootNode->mTransformation = aiMatrix4x4();
        }

        return scene;
    }
예제 #12
0
Mesh* createMeshFromAsset(const aiScene* scene, const Eigen::Vector3d &scale, const std::string &resource_name)
{
  if (!scene->HasMeshes())
  {
    logWarn("Assimp reports scene in %s has no meshes", resource_name.c_str());
    return NULL;
  }
  EigenSTL::vector_Vector3d vertices;
  std::vector<unsigned int> triangles;
  extractMeshData(scene, scene->mRootNode, aiMatrix4x4(), scale, vertices, triangles);
  if (vertices.empty())
  {
    logWarn("There are no vertices in the scene %s", resource_name.c_str());
    return NULL;
  }
  if (triangles.empty())
  {
    logWarn("There are no triangles in the scene %s", resource_name.c_str());
    return NULL;
  }
  
  return createMeshFromVertices(vertices, triangles);
}
void copyAiAnimations(const aiScene *scene, const aiMesh *sourceMesh, Skeleton &skeleton)
{
    //Create map from bone names to their indices.
    std::map<std::string, unsigned int> boneNameToIndex;
    
    for (unsigned int i = 0; i < skeleton.bones.size(); ++i)
    {
        if (!boneNameToIndex.insert(std::make_pair(skeleton.bones[i].name, i)).second)
        {
            std::cerr << "Bone name '" << skeleton.bones[i].name << "' is not unique!" << std::endl;
            throw std::exception();
        }
    }
    
    assert(boneNameToIndex.size() == skeleton.bones.size());
    
    //Create map from node names to their pointers.
    std::map<std::string, const aiNode *> nodeNameToPointer;
    
    detail::setAiNodePointers(scene->mRootNode, nodeNameToPointer);
    
    //We need to keep track of all transformation matrices.
    std::map<std::string, aiMatrix4x4> nodeNameToMatrix;
    
    for (std::map<std::string, const aiNode *>::const_iterator i = nodeNameToPointer.begin(); i != nodeNameToPointer.end(); ++i)
    {
        nodeNameToMatrix.insert(std::make_pair(i->first, aiMatrix4x4()));
    }
    
    //Process all animations.
    skeleton.animations.clear();
    
    for (unsigned int i = 0; i < scene->mNumAnimations; ++i)
    {
        copyAiAnimation(scene, sourceMesh, i, boneNameToIndex, nodeNameToPointer, nodeNameToMatrix, skeleton);
    }
}
aiMatrix4x4 NCAssimpModel::toAi(ofMatrix4x4 & m){
    return aiMatrix4x4(m(0,0),m(1,0),m(2,0),m(3,0),
                       m(0,1),m(1,1),m(2,1),m(3,1),
                       m(0,2),m(1,2),m(2,2),m(3,2),
                       m(0,3),m(1,3),m(2,3),m(3,3));
}
// ------------------------------------------------------------------------------------------------
// Evaluates the animation tracks for a given time stamp. 
void cAnimEvaluator::Evaluate( float pTime, std::map<std::string, cBone*>& bones) {

	pTime *= TicksPerSecond;
	
	float time = 0.0f;
	if( Duration > 0.0)
		time = fmod( pTime, Duration);

	// calculate the transformations for each animation channel
	for( unsigned int a = 0; a < Channels.size(); a++){
		const cAnimationChannel* channel = &Channels[a];
		std::map<std::string, cBone*>::iterator bonenode = bones.find(channel->Name);

		if(bonenode == bones.end()) { 
			OUTPUT_DEBUG_MSG("did not find the bone node "<<channel->Name);
			continue;
		}

		// ******** Position *****
		aiVector3D presentPosition( 0, 0, 0);
		if( channel->mPositionKeys.size() > 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 = (time >= mLastTime) ? std::get<0>(mLastPositions[a]): 0;
			while( frame < channel->mPositionKeys.size() - 1){
				if( time < channel->mPositionKeys[frame+1].mTime){
					break;
				}
				frame++;
			}

			// interpolate between this frame's value and next frame's value
			unsigned int nextFrame = (frame + 1) % channel->mPositionKeys.size();
	
			const aiVectorKey& key = channel->mPositionKeys[frame];
			const aiVectorKey& nextKey = channel->mPositionKeys[nextFrame];
			double diffTime = nextKey.mTime - key.mTime;
			if( diffTime < 0.0)
				diffTime += Duration;
			if( diffTime > 0) {
				float factor = float( (time - key.mTime) / diffTime);
				presentPosition = key.mValue + (nextKey.mValue - key.mValue) * factor;
			} else {
				presentPosition = key.mValue;
			}
			std::get<0>(mLastPositions[a]) = frame;
		}
		// ******** Rotation *********
		aiQuaternion presentRotation( 1, 0, 0, 0);
		if( channel->mRotationKeys.size() > 0)
		{
			unsigned int frame = (time >= mLastTime) ? std::get<1>(mLastPositions[a]) : 0;
			while( frame < channel->mRotationKeys.size()  - 1){
				if( time < channel->mRotationKeys[frame+1].mTime)
					break;
				frame++;
			}

			// interpolate between this frame's value and next frame's value
			unsigned int nextFrame = (frame + 1) % channel->mRotationKeys.size() ;

			const aiQuatKey& key = channel->mRotationKeys[frame];
			const aiQuatKey& nextKey = channel->mRotationKeys[nextFrame];
			double diffTime = nextKey.mTime - key.mTime;
			if( diffTime < 0.0) diffTime += Duration;
			if( diffTime > 0) {
				float factor = float( (time - key.mTime) / diffTime);
				aiQuaternion::Interpolate( presentRotation, key.mValue, nextKey.mValue, factor);
			} else presentRotation = key.mValue;
			std::get<1>(mLastPositions[a]) = frame;
		}

		// ******** Scaling **********
		aiVector3D presentScaling( 1, 1, 1);
		if( channel->mScalingKeys.size() > 0) {
			unsigned int frame = (time >= mLastTime) ? std::get<2>(mLastPositions[a]) : 0;
			while( frame < channel->mScalingKeys.size() - 1){
				if( time < channel->mScalingKeys[frame+1].mTime)
					break;
				frame++;
			}

			presentScaling = channel->mScalingKeys[frame].mValue;
			std::get<2>(mLastPositions[a]) = frame;
		}

		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();
		
		TransformMatrix(bonenode->second->LocalTransform, mat);
	}
	mLastTime = time;
}
예제 #16
0
void Model::draw(unsigned int animation, double timeIn)
{
	if (scene->mNumAnimations <= animation)
		return;

	aiAnimation* currentAnimation = scene->mAnimations[animation];

	//Step 1: Interpolate position, rotation, scale in the all channels and add to transformation
	for (unsigned int i = 0; i < currentAnimation->mNumChannels; i++)
	{
		aiNodeAnim* currentChannel = currentAnimation->mChannels[i];

		aiVector3D currentPosition = interpolatePosition(currentChannel, timeIn);
		aiQuaternion currentRotation = interpolateRotation(currentChannel, timeIn);
		aiVector3D currentScale = interpolateScale(currentChannel, timeIn);

		aiMatrix4x4& transformation = aiMatrix4x4(currentScale, currentRotation, currentPosition);

		aiNode* currentNode = scene->mRootNode->FindNode(currentChannel->mNodeName);
		currentNode->mTransformation = transformation;
	}

	for (unsigned int k = 0; k < scene->mNumMeshes; k++)
	{

		//Step 2: Bone transformation, change transformation of the bone according to animation
		aiMesh* currentMesh = scene->mMeshes[k];

		std::vector<aiMatrix4x4> boneTransformations = std::vector<aiMatrix4x4>(currentMesh->mNumBones);
		for (unsigned int i = 0; i < currentMesh->mNumBones; i++)
		{
			aiBone* currentBone = currentMesh->mBones[i];
			aiNode* currentNode = scene->mRootNode->FindNode(currentBone->mName);
			boneTransformations[i] = parentMultiplication(currentNode);
			boneTransformations[i] *= currentMesh->mBones[i]->mOffsetMatrix;
		}

		//Step 3: Skinning
		std::vector<aiVector3D> resultPosition(currentMesh->mNumVertices);
		for (size_t k = 0; k < currentMesh->mNumBones; k++)
		{
			const aiBone* currentBone = currentMesh->mBones[k];

			const aiMatrix4x4& positionMatrix = boneTransformations[k];
			for (size_t j = 0; j < currentBone->mNumWeights; j++)
			{
				const aiVertexWeight& weight = currentBone->mWeights[j];
				size_t vertexId = weight.mVertexId;
				const aiVector3D& srcPosition = currentMesh->mVertices[vertexId];
				resultPosition[vertexId] += weight.mWeight * (positionMatrix * srcPosition);
			}
		}

		//Step 4: Draw the final model
		// For every face
		size_t cv = 0, ctc = 0;
		glColor3d(1.0, 1.0, 1.0); // Set the face color to white
		for (int cf = 0; cf < currentMesh->mNumFaces; cf++)
		{
			const aiFace& face = currentMesh->mFaces[cf];

			// For all vertices in face (Final drawing)
			if (wireframe)
				glBegin(GL_LINE_LOOP);
			else
				glBegin(GL_TRIANGLES);
			for (int cfi = 0; cfi < 3; cfi++)
			{
				double x = resultPosition[face.mIndices[cfi]].x;
				double y = resultPosition[face.mIndices[cfi]].y;
				double z = resultPosition[face.mIndices[cfi]].z;
				glVertex3d(x, y, z);
			}

			glEnd();
		}
	}


}
void copyAiAnimation(const aiScene *scene, const aiMesh *sourceMesh, const unsigned int &animationIndex,
    std::map<std::string, unsigned int> &boneNameToIndex,
    std::map<std::string, const aiNode *> &nodeNameToPointer,
    std::map<std::string, aiMatrix4x4> &nodeNameToMatrix,
    Skeleton &skeleton)
{
    const aiAnimation *sourceAnimation = scene->mAnimations[animationIndex];
    const std::string animationName = std::string(sourceAnimation->mName.data);
    skeleton.animations.insert(std::pair<std::string, Animation>(animationName, Animation()));
    Animation *animation = &skeleton.animations[animationName];
    const size_t nrFrames = getAiNrAnimationFrames(sourceAnimation);
    
    animation->name = animationName;
    animation->frames.assign(nrFrames*skeleton.bones.size(), KeyFrame());
    
    if (sourceAnimation->mNumChannels != skeleton.bones.size())
    {
        std::cerr << "Warning: animation '" << animation->name << "' has an invalid number of channels (" << sourceAnimation->mNumChannels << " for " << skeleton.bones.size() << " bones)!" << std::endl;
    }
    
    //Store inverse of global transformation.
    aiMatrix4x4 inverseGlobalTransformation = scene->mRootNode->mTransformation;
    
    inverseGlobalTransformation.Inverse();
    
    //Process all frames.
    KeyFrame *frames = &animation->frames[0];
    
    for (size_t frame = 0; frame < nrFrames; ++frame)
    {
        //For this frame, first reset all transformations to their originals.
        for (std::map<std::string, aiMatrix4x4>::iterator i = nodeNameToMatrix.begin(); i != nodeNameToMatrix.end(); ++i)
        {
            assert(nodeNameToPointer[i->first]);
            i->second = nodeNameToPointer[i->first]->mTransformation;
        }
        
        //Then, retrieve all transformations that are stored in the animation data for the corresponding nodes.
        for (size_t i = 0; i < sourceAnimation->mNumChannels; ++i)
        {
            const aiNodeAnim *nodeAnim = sourceAnimation->mChannels[i];
            
            //Get data for this frame.
            aiVector3D scale(1.0f, 1.0f, 1.0f);
            aiQuaternion rotate(1.0f, 0.0f, 0.0f, 0.0f);
            aiVector3D translate(0.0f, 0.0f, 0.0f);
            
            if (frame < nodeAnim->mNumScalingKeys) scale = nodeAnim->mScalingKeys[frame].mValue;
            else if (nodeAnim->mNumScalingKeys > 0) scale = nodeAnim->mScalingKeys[nodeAnim->mNumScalingKeys - 1].mValue;
            if (frame < nodeAnim->mNumRotationKeys) rotate = nodeAnim->mRotationKeys[frame].mValue;
            else if (nodeAnim->mNumRotationKeys > 0) rotate = nodeAnim->mRotationKeys[nodeAnim->mNumRotationKeys - 1].mValue;
            if (frame < nodeAnim->mNumPositionKeys) translate = nodeAnim->mPositionKeys[frame].mValue;
            else if (nodeAnim->mNumPositionKeys > 0) translate = nodeAnim->mPositionKeys[nodeAnim->mNumPositionKeys - 1].mValue;
            
            //Create transformation matrix.
            if (nodeNameToMatrix.find(nodeAnim->mNodeName.data) == nodeNameToMatrix.end())
            {
                std::cerr << "Warning: animation data for node '" << nodeAnim->mNodeName.data << "' is not available!" << std::endl;
                throw std::exception();
            }
            
            aiMatrix4x4 scaleMatrix;
            aiMatrix4x4 rotationMatrix = aiMatrix4x4(rotate.GetMatrix());
            aiMatrix4x4 translationMatrix;
            
            aiMatrix4x4::Scaling(scale, scaleMatrix);
            aiMatrix4x4::Translation(translate, translationMatrix);
            
            nodeNameToMatrix[nodeAnim->mNodeName.data] = translationMatrix*rotationMatrix*scaleMatrix;
        }
        
        //Recursively update these transformations.
        updateAiNodeMatrices(scene->mRootNode, aiMatrix4x4(), nodeNameToMatrix);

        //Assign the updated transformations to the corresponding bones.
        for (std::map<std::string, aiMatrix4x4>::const_iterator i = nodeNameToMatrix.begin(); i != nodeNameToMatrix.end(); ++i)
        {
            std::map<std::string, unsigned int>::const_iterator boneIterator = boneNameToIndex.find(i->first);
            
            if (boneIterator != boneNameToIndex.end())
            {
                const unsigned int boneIndex = boneIterator->second;
                //const aiMatrix4x4 finalTransformation = inverseGlobalTransformation*i->second*sourceMesh->mBones[boneIndex]->mOffsetMatrix;
                const aiMatrix4x4 finalTransformation = i->second*sourceMesh->mBones[boneIndex]->mOffsetMatrix;
                
                aiVector3D scale(1.0f, 1.0f, 1.0f);
                aiQuaternion rotate(1.0f, 0.0f, 0.0f, 0.0f);
                aiVector3D translate(0.0f, 0.0f, 0.0f);
                
                finalTransformation.Decompose(scale, rotate, translate);
                
                frames[boneIndex] = KeyFrame(vec3(scale.x, scale.y, scale.z),
                                             frame,
                                             quatconj(vec4(rotate.x, rotate.y, rotate.z, rotate.w)),
                                             vec4(translate.x, translate.y, translate.z, 0.0f));
            }
        }
        
        //Advance to next frame.
        frames += skeleton.bones.size();
    }
    
#ifndef NDEBUG
    std::cerr << "Added animation '" << animation->name << "' with " << nrFrames << " frames, resulting in " << animation->frames.size() << " keyframes." << std::endl;
#endif
}
예제 #18
0
// calculates the node transformations for the scene
// returns false of the animation is completed or if there is no animation
bool Animator::UpdateAnimation(float time, bool loop)
{
    if (currentAnimation && currentAnimation->mDuration > 0.0 && CurAnimation != NULL)
    {
        // map into animation's duration
        double timeInTicks = 0.0f;
        
        float dur = (CurAnimation->endFrame - CurAnimation->startFrame)/FPS;
        
        if(time == 0)
        {
            timeInTicks = 0;
        }
        else if (dur > 0.0)
        {
            timeInTicks = (CurAnimation->startFrame/FPS) + fmod(time-(1/FPS), dur);
        }
        else
        {
            timeInTicks = CurAnimation->startFrame/FPS;
        }
        
        if (boneTransforms.size() != currentAnimation->mNumChannels)
        {
            boneTransforms.resize(currentAnimation->mNumChannels);
        }
        
        //calculate the transformations for each animation channel
        for (unsigned int i = 0; i < currentAnimation->mNumChannels; i++)
        {
            const aiNodeAnim* channel = currentAnimation->mChannels[i];
            
            //******** Position *****
            aiVector3D currentPosition(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
                unsigned int frame = (timeInTicks >= lastTime) ? lastFramePosition[i].x : 0;
                
                while (frame < channel->mNumPositionKeys - 1)
                {
                    if (timeInTicks < 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 dt = nextKey.mTime - key.mTime;
                
                if (dt < 0.0)
                {
                    dt += dur;
                }
                
                if (dt > 0)
                {
                    float interpolationFactor = (float) ((timeInTicks - key.mTime) / dt);
                    currentPosition = key.mValue + (nextKey.mValue - key.mValue) * interpolationFactor;
                }
                else
                {
                    currentPosition = key.mValue;
                }
                
                lastFramePosition[i].x = frame;
            }
            
            //******** Rotation *********
            aiQuaternion currentRotation(1, 0, 0, 0);
            
            if (channel->mNumRotationKeys > 0)
            {
                unsigned int frame = (timeInTicks >= lastTime) ? lastFramePosition[i].y : 0;
                
                while (frame < channel->mNumRotationKeys - 1)
                {
                    if (timeInTicks < 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 dt = nextKey.mTime - key.mTime;
                
                if (dt < 0.0)
                {
                    dt += dur;
                }
                
                if (dt > 0)
                {
                    float interpolationFactor = (float) ((timeInTicks - key.mTime) / dt);
                    aiQuaternion::Interpolate(currentRotation, key.mValue, nextKey.mValue, interpolationFactor);
                }
                else
                {
                    currentRotation = key.mValue;
                }
                
                lastFramePosition[i].y = frame;
            }
            
            //******** Scaling **********
            aiVector3D currentScaling(1, 1, 1);
            
            if (channel->mNumScalingKeys > 0)
            {
                unsigned int frame = (timeInTicks >= lastTime) ? lastFramePosition[i].z : 0;
                
                while (frame < channel->mNumScalingKeys - 1)
                {
                    if (timeInTicks < channel->mScalingKeys[frame + 1].mTime)
                    {
                        break;
                    }
                    
                    frame++;
                }
                
                currentScaling = channel->mScalingKeys[frame].mValue;
                lastFramePosition[i].z = frame;
            }
            
            // build a transformation matrix from the current position, rotation, and scale
            aiMatrix4x4& transformation = boneTransforms[i];
            transformation = aiMatrix4x4(currentRotation.GetMatrix());
            
            transformation.a1 *= currentScaling.x;
            transformation.b1 *= currentScaling.x;
            transformation.c1 *= currentScaling.x;
            
            transformation.a2 *= currentScaling.y;
            transformation.b2 *= currentScaling.y;
            transformation.c2 *= currentScaling.y;
            
            transformation.a3 *= currentScaling.z;
            transformation.b3 *= currentScaling.z;
            transformation.c3 *= currentScaling.z;
            
            transformation.a4 = currentPosition.x;
            transformation.b4 = currentPosition.y;
            transformation.c4 = currentPosition.z;
        }
        
        lastTime = timeInTicks;
        
        // update all node transformations with the results
        UpdateTransforms(rootNode, boneTransforms);
        
        if(time <= dur || loop)
        {
            if(CurAnimation != NULL) CurAnimation->isPlaying = true;
            return true;
        }
    }
    
    if(CurAnimation != NULL) CurAnimation->isPlaying = false;
    return false;
}
예제 #19
0
파일: Info.cpp 프로젝트: lubosz/assimp
// -----------------------------------------------------------------------------------
void FindSpecialPoints(const aiScene* scene,const aiNode* root,aiVector3D special_points[3],const aiMatrix4x4& mat=aiMatrix4x4())
{
	// XXX that could be greatly simplified by using code from code/ProcessHelper.h
	// XXX I just don't want to include it here.
	const aiMatrix4x4 trafo = root->mTransformation*mat;
	for(unsigned int i = 0; i < root->mNumMeshes; ++i) {
		const aiMesh* mesh = scene->mMeshes[root->mMeshes[i]];

		for(unsigned int a = 0; a < mesh->mNumVertices; ++a) {
			aiVector3D v = trafo*mesh->mVertices[a];

			special_points[0].x = std::min(special_points[0].x,v.x);
			special_points[0].y = std::min(special_points[0].y,v.y);
			special_points[0].z = std::min(special_points[0].z,v.z);

			special_points[1].x = std::max(special_points[1].x,v.x);
			special_points[1].y = std::max(special_points[1].y,v.y);
			special_points[1].z = std::max(special_points[1].z,v.z);
		}
	}

	for(unsigned int i = 0; i < root->mNumChildren; ++i) {
		FindSpecialPoints(scene,root->mChildren[i],special_points,trafo);
	}
}
예제 #20
0
    /** Get a string configuration property
     *
     *  The return value remains valid until the property is modified.
     * @see GetPropertyInteger()
     */
    const std::string GetPropertyString(const char* szName,
        const std::string& sErrorReturn = "") const;

    // -------------------------------------------------------------------
    /** Get a matrix configuration property
     *
     *  The return value remains valid until the property is modified.
     * @see GetPropertyInteger()
     */
    const aiMatrix4x4 GetPropertyMatrix(const char* szName,
        const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const;

    // -------------------------------------------------------------------
    /** Supplies a custom IO handler to the importer to use to open and
     * access files. If you need the importer to use custom IO logic to
     * access the files, you need to provide a custom implementation of
     * IOSystem and IOFile to the importer. Then create an instance of
     * your custom IOSystem implementation and supply it by this function.
     *
     * The Importer takes ownership of the object and will destroy it
     * afterwards. The previously assigned handler will be deleted.
     * Pass NULL to take again ownership of your IOSystem and reset Assimp
     * to use its default implementation.
     *
     * @param pIOHandler The IO handler to be used in all file accesses
     *   of the Importer.
void ofxAssimpAnimation::updateAnimationNodes() {
	for(unsigned int i=0; i<animation->mNumChannels; i++) {
        const aiNodeAnim * channel = animation->mChannels[i];
        aiNode * targetNode = scene->mRootNode->FindNode(channel->mNodeName);
        
        aiVector3D presentPosition(0, 0, 0);
        if(channel->mNumPositionKeys > 0) {
            unsigned int frame = 0;
            while(frame < channel->mNumPositionKeys - 1) {
                if(progressInSeconds < channel->mPositionKeys[frame+1].mTime) {
                    break;
                }
                frame++;
            }
            
            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 += getDurationInSeconds();
            }
            if(diffTime > 0) {
                float factor = float((progressInSeconds - key.mTime) / diffTime);
                presentPosition = key.mValue + (nextKey.mValue - key.mValue) * factor;
            } else {
                presentPosition = key.mValue;
            }
        }
        
        aiQuaternion presentRotation(1, 0, 0, 0);
        if(channel->mNumRotationKeys > 0) {
            unsigned int frame = 0;
            while(frame < channel->mNumRotationKeys - 1) {
                if(progressInSeconds < channel->mRotationKeys[frame+1].mTime) {
                    break;
                }
                frame++;
            }
            
            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 += getDurationInSeconds();
            }
            if(diffTime > 0) {
                float factor = float((progressInSeconds - key.mTime) / diffTime);
                aiQuaternion::Interpolate(presentRotation, key.mValue, nextKey.mValue, factor);
            } else {
                presentRotation = key.mValue;
            }
        }
        
        aiVector3D presentScaling(1, 1, 1);
        if(channel->mNumScalingKeys > 0) {
            unsigned int frame = 0;
            while(frame < channel->mNumScalingKeys - 1){
                if(progressInSeconds < channel->mScalingKeys[frame+1].mTime) {
                    break;
                }
                frame++;
            }
            
            presentScaling = channel->mScalingKeys[frame].mValue;
        }
        
        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;
        
        targetNode->mTransformation = mat;
    }
}
예제 #22
0
aiMatrix4x4 floatsToMatrix( float* data ) {
	return aiMatrix4x4( data[0], data[1], data[2], data[3],
		data[4], data[5], data[6], data[7], 
		data[8], data[9], data[10], data[11], 
		data[12], data[13], data[14], data[15] );
}
예제 #23
0
void AnimEvaluator::Evaluate( float pTime, std::map<std::string, SkinData::Bone*>& bones )
{
	pTime *= mTicksPerSecond;

	float time = 0.0f;
	if (mDuration > 0.0)
		time = fmod(pTime, mDuration);

	// Calculate transformations for each channel
	for (UINT i = 0; i < Channels.size(); ++i)
	{
		const SkinData::AnimationChannel* channel = &Channels[i];
		std::map<std::string, SkinData::Bone*>::iterator boneNode = bones.find(channel->Name);

		// Did not find bone node
		if (boneNode == bones.end())
			continue;

		//---------------------------------------------
		// Position
		//---------------------------------------------
		aiVector3D presentPosition(0, 0, 0);
		if (channel->PositionKeys.size() > 0)
		{
			// Look for present frame number
			UINT frame = (time >= mLastTime) ? std::get<0>(mLastPositions[i]) : 0;

			while (frame < channel->PositionKeys.size() - 1)
			{
				if (time < channel->PositionKeys[frame+1].mTime)
					break;

				frame++;
			}

			// Interpolate between this frame's value and the next frame's value
			UINT nextFrame = (frame + 1) % channel->PositionKeys.size();

			const aiVectorKey& key = channel->PositionKeys[frame];
			const aiVectorKey& nextKey = channel->PositionKeys[nextFrame];

			double diffTime = nextKey.mTime - key.mTime;

			if (diffTime < 0.0)
				diffTime += mDuration;
			if (diffTime > 0)
			{
				float factor = float((time - key.mTime) / diffTime);
				presentPosition = key.mValue + (nextKey.mValue - key.mValue) * factor;
			}
			else
			{
				presentPosition = key.mValue;
			}

			std::get<0>(mLastPositions[i]) = frame;
		}

		//---------------------------------------------
		// Rotation
		//---------------------------------------------
		aiQuaternion presentRotation(1, 0, 0, 0);
		if (channel->RotationKeys.size() > 0)
		{
			UINT frame = (time >= mLastTime) ? std::get<1>(mLastPositions[i]) : 0;

			while (frame < channel->RotationKeys.size() - 1)
			{
				if (time < channel->RotationKeys[frame+1].mTime)
					break;

				frame++;
			}

			UINT nextFrame = (frame + 1) % channel->RotationKeys.size();

			const aiQuatKey& key = channel->RotationKeys[frame];
			const aiQuatKey& nextKey = channel->RotationKeys[nextFrame];
			
			double diffTime = nextKey.mTime - key.mTime;

			if (diffTime < 0.0)
				diffTime += mDuration;

			if (diffTime > 0)
			{
				float factor = float((time - key.mTime) / diffTime);
				aiQuaternion::Interpolate(presentRotation, key.mValue, nextKey.mValue, factor);
			}
			else
			{
				presentRotation = key.mValue;
			}

			std::get<1>(mLastPositions[i]) = frame;
		}

		//---------------------------------------------
		// Scaling
		//---------------------------------------------
		aiVector3D presentScaling(1, 1, 1);
		if (channel->ScalingKeys.size() > 0)
		{
			UINT frame = (time >= mLastTime) ? std::get<2>(mLastPositions[i]) : 0;

			while (frame < channel->ScalingKeys.size() - 1)
			{
				if (time < channel->ScalingKeys[frame+1].mTime)
					break;

				frame++;
			}

			presentScaling = channel->ScalingKeys[frame].mValue;
			std::get<2>(mLastPositions[i]) = frame;
		}

		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();

		SkinData::ReadAiMatrix(boneNode->second->LocalTransform, mat);

	} // Channel end

	mLastTime = time;
}
//-------------------------------------------
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);

				}
			}
		}
	}
}
예제 #25
0
파일: MeshShape.cpp 프로젝트: vanurag/dart
const aiScene* MeshShape::loadMesh(
    const std::string& _uri, const common::ResourceRetrieverPtr& _retriever)
{
    // Remove points and lines from the import.
    aiPropertyStore* propertyStore = aiCreatePropertyStore();
    aiSetImportPropertyInteger(propertyStore,
                               AI_CONFIG_PP_SBP_REMOVE,
                               aiPrimitiveType_POINT
                               | aiPrimitiveType_LINE
                              );

    // Wrap ResourceRetriever in an IOSystem from Assimp's C++ API.  Then wrap
    // the IOSystem in an aiFileIO from Assimp's C API. Yes, this API is
    // completely ridiculous...
    AssimpInputResourceRetrieverAdaptor systemIO(_retriever);
    aiFileIO fileIO = createFileIO(&systemIO);

    // Import the file.
    const aiScene* scene = aiImportFileExWithProperties(
                               _uri.c_str(),
                               aiProcess_GenNormals
                               | aiProcess_Triangulate
                               | aiProcess_JoinIdenticalVertices
                               | aiProcess_SortByPType
                               | aiProcess_OptimizeMeshes,
                               &fileIO,
                               propertyStore
                           );

    // If succeeded, store the importer in the scene to keep it alive. This is
    // necessary because the importer owns the memory that it allocates.
    if(!scene)
    {
        dtwarn << "[MeshShape::loadMesh] Failed loading mesh '" << _uri << "'.\n";
        return nullptr;
    }

    // Assimp rotates collada files such that the up-axis (specified in the
    // collada file) aligns with assimp's y-axis. Here we are reverting this
    // rotation. We are only catching files with the .dae file ending here. We
    // might miss files with an .xml file ending, which would need to be looked
    // into to figure out whether they are collada files.
    std::string extension;
    const size_t extensionIndex = _uri.find_last_of('.');
    if(extensionIndex != std::string::npos)
        extension = _uri.substr(extensionIndex);

    std::transform(std::begin(extension), std::end(extension),
                   std::begin(extension), ::tolower);

    if(extension == ".dae" || extension == ".zae")
        scene->mRootNode->mTransformation = aiMatrix4x4();

    // Finally, pre-transform the vertices. We can't do this as part of the
    // import process, because we may have changed mTransformation above.
    scene = aiApplyPostProcessing(scene, aiProcess_PreTransformVertices);
    if(!scene)
        dtwarn << "[MeshShape::loadMesh] Failed pre-transforming vertices.\n";

    return scene;
}
예제 #26
0
bool Model::loadFromFile(const std::string& filename)
{
    Assimp::Importer importer;


	std::string strModelsResourcesFolder = "Data/Resources/Models/";

	std::string strModelFinalFilename = strModelsResourcesFolder + filename;

    // Component to be removed when importing file
    importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS,
                                aiComponent_COLORS
//                                | aiComponent_TANGENTS_AND_BITANGENTS
                                | aiComponent_BONEWEIGHTS
                                | aiComponent_ANIMATIONS
                                | aiComponent_LIGHTS
                                | aiComponent_CAMERAS);
    importer.SetPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE, 1);

    // And have it read the given file with some example postprocessing
    // Usually - if speed is not the most important aspect for you - you'll
    // propably to request more postprocessing than we do in this example.
	const aiScene* scene = importer.ReadFile(strModelFinalFilename,
        aiProcess_Triangulate
        | aiProcess_JoinIdenticalVertices
        | aiProcess_RemoveComponent
        | aiProcess_GenNormals
        | aiProcess_CalcTangentSpace
        | aiProcess_PreTransformVertices
        //| aiProcess_GenUVCoords
        //| aiProcess_MakeLeftHanded
    );


//    const aiScene* scene = importer.ReadFile( filename,
//                                              aiProcessPreset_TargetRealtime_MaxQuality
//    );

    // If the import failed, report it
    if( !scene)
    {
        std::cerr << importer.GetErrorString() << '\n';
        return false;
    }    

    m_nodes.clear();

    aiNode* rootNode = scene->mRootNode;

    handleNode(rootNode, aiMatrix4x4());

    m_meshes.clear();
    m_meshes.resize(scene->mNumMeshes);

    m_materials.clear();
    //m_materials.resize(scene->mNumMaterials);

    //std::string dir = filename;

    //size_t lastSeparator = dir.find_last_of('/');

    //if (lastSeparator != std::string::npos) {
    //    dir.erase(lastSeparator, dir.size());
    //}
    //else {
    //    dir = std::string(".");
    //}

    for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
        m_meshes[i].loadFromAssimpMesh(scene->mMeshes[i]);
    }

    //for (unsigned int i = 0; i < scene->mNumMaterials; ++i) {
    //    m_materials[i].loadFromAssimpMaterial(scene->mMaterials[i], dir);
    //}

//    const aiMesh* mesh = scene->mMeshes[0];

//    std::cerr << "Mesh HasFaces ? " << mesh->HasFaces() << '\n';
//    std::cerr << "Mesh HasNormals ? " << mesh->HasNormals() << '\n';
//    std::cerr << "Mesh HasPositions ? " << mesh->HasPositions() << '\n';
//    std::cerr << "Mesh HasTangentsAndBitangents ? " << mesh->HasTangentsAndBitangents() << '\n';
//    std::cerr << "Mesh HasBones ? " << mesh->HasBones() << '\n';
//    std::cerr << "Mesh HasTextureCoords ? " << mesh->HasTextureCoords(0) << '\n';
//    std::cerr << "mesh->mTextureCoords[0] != NULL ? " << (mesh->mTextureCoords[0] != NULL) << '\n';
//    std::cerr << "Mesh GetNumUVChannels ? " << mesh->GetNumUVChannels() << '\n';
//    std::cerr << "Mesh GetNumColorChannels ? " << mesh->GetNumColorChannels() << '\n';
//    std::cerr << "Mesh mNumFaces ? " << mesh->mNumFaces << '\n';
//    std::cerr << "Mesh mNumVertices ? " << mesh->mNumVertices << '\n';
//    std::cerr << "Mesh mPrimitiveTypes ? " << mesh->mPrimitiveTypes << " and should be " << aiPrimitiveType_TRIANGLE << '\n';

    return true;
}
예제 #27
0
파일: Node.cpp 프로젝트: ekryyn/3Douay
Node::Node() :
	entity(NULL)
{
	transformation = aiMatrix4x4();
}