Esempio n. 1
0
void Model_Impl::Load(CL_GraphicContext &gc, GraphicStore *gs, const char *filename)
{
	generate_texture_coords = true;

	const struct aiScene* scene = aiImportFileExWithProperties(filename,aiProcessPreset_TargetRealtime_MaxQuality, NULL, gs->store);
	if (!scene)
		throw CL_Exception("Cannot load a model");

	try
	{
		vbo_size = count_vertices(scene, scene->mRootNode);
		if (!vbo_size)
			throw CL_Exception("No vertices found in the model");
	
		vbo_positions = CL_VertexArrayBuffer(gc, vbo_size * sizeof(CL_Vec3f), cl_usage_static_draw);
		vbo_normals = CL_VertexArrayBuffer(gc, vbo_size * sizeof(CL_Vec3f), cl_usage_static_draw);
		if (generate_texture_coords)
			vbo_texcoords = CL_VertexArrayBuffer(gc, vbo_size * sizeof(CL_Vec2f), cl_usage_static_draw);
		insert_vbo(0, scene, scene->mRootNode);
	}catch(...)
	{
		aiReleaseImport(scene);
		throw;
	}

	aiReleaseImport(scene);
}
Esempio n. 2
0
const aiScene* MeshShape::loadMesh(const std::string& _fileName) {
  aiPropertyStore* propertyStore = aiCreatePropertyStore();
  // remove points and lines
  aiSetImportPropertyInteger(propertyStore,
                             AI_CONFIG_PP_SBP_REMOVE,
                             aiPrimitiveType_POINT | aiPrimitiveType_LINE);
  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();
  }
  scene = aiApplyPostProcessing(scene, aiProcess_PreTransformVertices);

  return scene;
}
//------------------------------------------
bool ofxAssimpModelLoader::loadModel(string modelName, bool optimize){
    
    file.open(modelName, ofFile::ReadOnly, true); // Since it may be a binary file we should read it in binary -Ed
    if(!file.exists()) {
        ofLogVerbose("ofxAssimpModelLoader") << "loadModel(): model does not exist: \"" << modelName << "\"";
        return false;
    }

    ofLogVerbose("ofxAssimpModelLoader") << "loadModel(): loading \"" << file.getFileName()
		<< "\" from \"" << file.getEnclosingDirectory() << "\"";
    
    if(scene.get() != nullptr){
        clear();
		// we reset the shared_ptr explicitly here, to force the old 
		// aiScene to be deleted **before** a new aiScene is created.
		scene.reset();
    }
    
    // sets various properties & flags to a default preference
    unsigned int flags = initImportProperties(optimize);
    
    // loads scene from file
    scene = shared_ptr<const aiScene>(aiImportFileExWithProperties(file.getAbsolutePath().c_str(), flags, NULL, store.get()), aiReleaseImport);
    
    bool bOk = processScene();
    return bOk;
}
Esempio n. 4
0
 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_PreTransformVertices   |
                                                                           aiProcess_OptimizeMeshes,
                                                         NULL, propertyStore);
     aiReleasePropertyStore(propertyStore);
     return scene;
 }
Esempio n. 5
0
void Model_Impl::Load(GraphicContext &gc, GraphicStore *gs, const char *filename)
{
	const struct aiScene* scene = aiImportFileExWithProperties(filename,aiProcessPreset_TargetRealtime_MaxQuality, NULL, gs->store);
	if (!scene)
		throw Exception("Cannot load a model");

	try
	{
		vbo_size = count_vertices(scene, scene->mRootNode);
		if (!vbo_size)
			throw Exception("No vertices found in the model");
	
		vbo_positions = VertexArrayVector<Vec3f>(gc, vbo_size);
		vbo_normals = VertexArrayVector<Vec3f>(gc, vbo_size);
		insert_vbo(gc, 0, scene, scene->mRootNode);
	}catch(...)
	{
		aiReleaseImport(scene);
		throw;
	}

	aiReleaseImport(scene);
}
Esempio n. 6
0
//////////////////////////////////////////////////////////////////////////
// import
BcBool ScnAnimationImport::import( const Json::Value& )
{
#if PSY_IMPORT_PIPELINE
	if( Source_.empty() )
	{
		PSY_LOG( "ERROR: Missing 'source' field.\n" );
		return BcFalse;
	}

	CsResourceImporter::addDependency( Source_.c_str() );

	auto PropertyStore = aiCreatePropertyStore();

	aiLogStream AssimpLogger =
	{
		AssimpLogStream, (char*)this
	};
	aiAttachLogStream( &AssimpLogger );

	Scene_ = aiImportFileExWithProperties( 
		Source_.c_str(), 
		0,
		nullptr, 
		PropertyStore );

	aiReleasePropertyStore( PropertyStore );

	if( Scene_ != nullptr )
	{
		PSY_LOG( "Found %u animations:\n", Scene_->mNumAnimations );
		for( int Idx = 0; Idx < (int)Scene_->mNumAnimations; ++Idx )
		{
			PSY_LOG( " - %s\n", Scene_->mAnimations[ Idx ]->mName.C_Str() );
		}

		// Build animated nodes list. Need this to calculate relative transforms later.
		recursiveParseAnimatedNodes( Scene_->mRootNode, BcErrorCode );

		// Pack down animation into useful internal format.
		BcAssert( Scene_->mNumAnimations == 1 );
		for( BcU32 AnimationIdx = 0; AnimationIdx < 1; ++AnimationIdx )
		{
			auto* Animation = Scene_->mAnimations[ AnimationIdx ];

			BcF32 Rate = 1.0f;
			BcU32 Duration = static_cast< BcU32 >( Animation->mDuration / Rate );

			// Setup data streams.
			ScnAnimationHeader Header;
			Header.NoofNodes_ = Animation->mNumChannels;
			Header.NoofPoses_ = Duration;
			Header.Flags_ = scnAF_DEFAULT;
			Header.Packing_ = scnAP_R16S16T16; // TODO: Make this configurable when we factor out into another class.
			HeaderStream_ << Header;

			// Animation node file data.
			ScnAnimationNodeFileData NodeFileData;
			for( BcU32 NodeIdx = 0; NodeIdx < Animation->mNumChannels; ++NodeIdx )
			{
				auto* Channel = Animation->mChannels[ NodeIdx ];
				NodeFileData.Name_ = CsResourceImporter::addString( Channel->mNodeName.C_Str() );
				NodeStream_ << NodeFileData;
			}

			// Calculate output pose.
			for( BcF32 Time = 0.0f; Time <= Animation->mDuration; Time += Rate )
			{
				ScnAnimationPoseFileData Pose;
				Pose.Time_ = Time / FrameRate_;
				Pose.KeyDataOffset_ = static_cast< BcU32 >( KeyStream_.dataSize() );

				// Iterate over all node channels to generate keys.
				for( BcU32 ChannelIdx = 0; ChannelIdx < Animation->mNumChannels; ++ChannelIdx )
				{
					auto* Channel = Animation->mChannels[ ChannelIdx ];
					auto& AnimatedNode = findAnimatedNode( Channel->mNodeName.C_Str() );

					aiVector3D OutPositionKey;
					aiVector3D OutScaleKey;
					aiQuaternion OutRotationKey;

					// Extract position.
					GetKeyNodeAnim( 
						Channel->mPositionKeys, 
						Channel->mNumPositionKeys, 
						Time, 
						BcTrue, 
						OutPositionKey );
	
					// Extract scale.
					GetKeyNodeAnim( 
						Channel->mScalingKeys, 
						Channel->mNumScalingKeys, 
						Time, 
						BcTrue, 
						OutScaleKey );

					// Extract rotation.
					GetKeyNodeAnim( 
						Channel->mRotationKeys, 
						Channel->mNumRotationKeys, 
						Time, 
						BcTrue, 
						OutRotationKey );

					// Combine key into transform.
					ScnAnimationTransform Transform;
					Transform.R_ = MaQuat( OutRotationKey.x, OutRotationKey.y, OutRotationKey.z, OutRotationKey.w );
					Transform.S_ = MaVec3d( OutScaleKey.x, OutScaleKey.y, OutScaleKey.z );
					Transform.T_ = MaVec3d( OutPositionKey.x, OutPositionKey.y, OutPositionKey.z );
				
					// Store as local matrix.
					Transform.toMatrix( AnimatedNode.LocalTransform_ );
				}

				// Calculate local node matrices relative to their parents.
				for( auto& AnimatedNode : AnimatedNodes_ )
				{
					if( AnimatedNode.ParentIdx_ != BcErrorCode )
					{
						auto& ParentAnimatedNode( AnimatedNodes_[ AnimatedNode.ParentIdx_ ] );
						MaMat4d ParentLocal = ParentAnimatedNode.LocalTransform_;
						AnimatedNode.WorldTransform_ = ParentLocal * AnimatedNode.LocalTransform_;
					}
					else
					{
						AnimatedNode.WorldTransform_ = AnimatedNode.LocalTransform_;
					}
				}

				// Write out pose keys.
				ScnAnimationTransformKey_R16S16T16 OutKey;
				for( BcU32 ChannelIdx = 0; ChannelIdx < Animation->mNumChannels; ++ChannelIdx )
				{
					auto* Channel = Animation->mChannels[ ChannelIdx ];
					const auto& AnimatedNode = findAnimatedNode( Channel->mNodeName.C_Str() );

					// Extract individual transform elements.
					ScnAnimationTransform Transform;
					Transform.fromMatrix( AnimatedNode.LocalTransform_ );

					// Pack into output key.
					OutKey.pack( 
						Transform.R_,
						Transform.S_,
						Transform.T_ );

					KeyStream_ << OutKey;
				}
			
				// Final size + CRC.
				Pose.KeyDataSize_ = static_cast< BcU32 >( KeyStream_.dataSize() - Pose.KeyDataOffset_ );
				Pose.CRC_ = BcHash::GenerateCRC32( 0, KeyStream_.pData() + Pose.KeyDataOffset_, Pose.KeyDataSize_ );

				// Write out pose.
				PoseStream_ << Pose;
			}
		
			// Write out chunks.
			CsResourceImporter::addChunk( BcHash( "header" ), HeaderStream_.pData(), HeaderStream_.dataSize(), 16, csPCF_IN_PLACE );
			CsResourceImporter::addChunk( BcHash( "nodes" ), NodeStream_.pData(), NodeStream_.dataSize() );
			CsResourceImporter::addChunk( BcHash( "poses" ), PoseStream_.pData(), PoseStream_.dataSize() );
			CsResourceImporter::addChunk( BcHash( "keys" ), KeyStream_.pData(), KeyStream_.dataSize() );
		}

		aiReleaseImport( Scene_ );
		Scene_ = nullptr;

		//
		return BcTrue;
	}
#endif // PSY_IMPORT_PIPELINE
	return BcFalse;	
}
Esempio n. 7
0
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;
}