/**
         * Searches a geode for drawables containing texture coordinates.
         * Based on which texture units the coordinates are mapped to,
         * appropriate texture slots are extracted.
         * @param geode The geometry node to check.
         */
        virtual void apply(osg::Geode &geode)
        {
            FindTextures(geode.getStateSet());
            for (unsigned int i=0; i<geode.getNumDrawables(); i++)
            {
                osg::Geometry *geom = geode.getDrawable(i)->asGeometry();
                if (geom != NULL)
                {
                    FindTextures(geom->getStateSet());
                    unsigned int texCoordCount = geom->getNumTexCoordArrays();
                    if (texCoordCount > mMaxTexCoordArrayCount)
                        mMaxTexCoordArrayCount = texCoordCount;
                }
            }

            traverse(geode);
        }
Esempio n. 2
0
S3DModel* CAssParser::Load(const std::string& modelFilePath)
{
	LOG_SL(LOG_SECTION_MODEL, L_INFO, "Loading model: %s", modelFilePath.c_str());

	const std::string& modelPath = FileSystem::GetDirectory(modelFilePath);
	const std::string& modelName = FileSystem::GetBasename(modelFilePath);

	// Load the lua metafile. This contains properties unique to Spring models and must return a table
	std::string metaFileName = modelFilePath + ".lua";

	if (!CFileHandler::FileExists(metaFileName, SPRING_VFS_ZIP)) {
		// Try again without the model file extension
		metaFileName = modelPath + '/' + modelName + ".lua";
	}
	if (!CFileHandler::FileExists(metaFileName, SPRING_VFS_ZIP)) {
		LOG_SL(LOG_SECTION_MODEL, L_INFO, "No meta-file '%s'. Using defaults.", metaFileName.c_str());
	}

	LuaParser metaFileParser(metaFileName, SPRING_VFS_MOD_BASE, SPRING_VFS_ZIP);

	if (!metaFileParser.Execute()) {
		LOG_SL(LOG_SECTION_MODEL, L_ERROR, "'%s': %s. Using defaults.", metaFileName.c_str(), metaFileParser.GetErrorLog().c_str());
	}

	// Get the (root-level) model table
	const LuaTable& modelTable = metaFileParser.GetRoot();

	if (!modelTable.IsValid()) {
		LOG_SL(LOG_SECTION_MODEL, L_INFO, "No valid model metadata in '%s' or no meta-file", metaFileName.c_str());
	}


	// Create a model importer instance
	Assimp::Importer importer;

	// Create a logger for debugging model loading issues
	Assimp::DefaultLogger::create("", Assimp::Logger::VERBOSE);
	Assimp::DefaultLogger::get()->attachStream(new AssLogStream(), ASS_LOGGING_OPTIONS);

	// Give the importer an IO class that handles Spring's VFS
	importer.SetIOHandler(new AssVFSSystem());
	// Speed-up processing by skipping things we don't need
	importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, ASS_IMPORTER_OPTIONS);

#ifndef BITMAP_NO_OPENGL
	{
		// Optimize VBO-Mesh sizes/ranges
		GLint maxIndices  = 1024;
		GLint maxVertices = 1024;
		// FIXME returns non-optimal data, at best compute it ourselves (pre-TL cache size!)
		glGetIntegerv(GL_MAX_ELEMENTS_INDICES,  &maxIndices);
		glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxVertices);
		importer.SetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,   maxVertices);
		importer.SetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, maxIndices / 3);
	}
#endif

	// Read the model file to build a scene object
	LOG_SL(LOG_SECTION_MODEL, L_INFO, "Importing model file: %s", modelFilePath.c_str());

	const aiScene* scene;
	{
		// ASSIMP spams many SIGFPEs atm in normal & tangent generation
		ScopedDisableFpuExceptions fe;
		scene = importer.ReadFile(modelFilePath, ASS_POSTPROCESS_OPTIONS);
	}

	if (scene != NULL) {
		LOG_SL(LOG_SECTION_MODEL, L_INFO,
			"Processing scene for model: %s (%d meshes / %d materials / %d textures)",
			modelFilePath.c_str(), scene->mNumMeshes, scene->mNumMaterials,
			scene->mNumTextures);
	} else {
		throw content_error("[AssimpParser] Model Import: " + std::string(importer.GetErrorString()));
	}

	S3DModel* model = new S3DModel();
	model->name = modelFilePath;
	model->type = MODELTYPE_ASS;

	// Load textures
	FindTextures(model, scene, modelTable, modelPath, modelName);
	LOG_SL(LOG_SECTION_MODEL, L_INFO, "Loading textures. Tex1: '%s' Tex2: '%s'", model->tex1.c_str(), model->tex2.c_str());
	texturehandlerS3O->LoadS3OTexture(model);

	// Load all pieces in the model
	LOG_SL(LOG_SECTION_MODEL, L_INFO, "Loading pieces from root node '%s'", scene->mRootNode->mName.data);
	LoadPiece(model, scene->mRootNode, scene, modelTable);

	// Update piece hierarchy based on metadata
	BuildPieceHierarchy(model);
	CalculateModelProperties(model, modelTable);

	// Verbose logging of model properties
	LOG_SL(LOG_SECTION_MODEL, L_DEBUG, "model->name: %s", model->name.c_str());
	LOG_SL(LOG_SECTION_MODEL, L_DEBUG, "model->numobjects: %d", model->numPieces);
	LOG_SL(LOG_SECTION_MODEL, L_DEBUG, "model->radius: %f", model->radius);
	LOG_SL(LOG_SECTION_MODEL, L_DEBUG, "model->height: %f", model->height);
	LOG_SL(LOG_SECTION_MODEL, L_DEBUG, "model->drawRadius: %f", model->drawRadius);
	LOG_SL(LOG_SECTION_MODEL, L_DEBUG, "model->mins: (%f,%f,%f)", model->mins[0], model->mins[1], model->mins[2]);
	LOG_SL(LOG_SECTION_MODEL, L_DEBUG, "model->maxs: (%f,%f,%f)", model->maxs[0], model->maxs[1], model->maxs[2]);
	LOG_SL(LOG_SECTION_MODEL, L_INFO, "Model %s Imported.", model->name.c_str());
	return model;
}
Esempio n. 3
0
void LevelFactory::FindTextures(const char *aDirName)
{
	DIR *dir;
	char buffer[PATH_MAX + 2];
	char *p = buffer;
	const char *src;
	char *end = &buffer[PATH_MAX];
	int ok;

	/* Copy directory name to buffer */
	src = aDirName;
	while (p < end  &&  *src != '\0') {
		*p++ = *src++;
	}
	*p = '\0';

	/* Open directory stream */
	dir = opendir(aDirName);
	if (dir != NULL) {
		struct dirent *ent;

		/* Print all files and directories within the directory */
		while ((ent = readdir(dir)) != NULL) {
			char *q = p;
			char c;

			/* Get final character of directory name */
			if (buffer < q) {
				c = q[-1];
			}
			else {
				c = ':';
			}

			/* Append directory separator if not already there */
			if (c != ':'  &&  c != '/'  &&  c != '\\') {
				*q++ = '/';
			}

			/* Append file name */
			src = ent->d_name;
			while (q < end  &&  *src != '\0') {
				*q++ = *src++;
			}
			*q = '\0';

			/* Decide what to do with the directory entry */
			switch (ent->d_type) {
			case DT_LNK:
			case DT_REG:
				/* Output file name with directory */
				//printf("%s\n", buffer);
				LoadTexture(buffer);
				break;

			case DT_DIR:
				/* Scan sub-directory recursively */
				if (strcmp(ent->d_name, ".") != 0
					&& strcmp(ent->d_name, "..") != 0) {
					FindTextures(buffer);
				}
				break;

			default:
				/* Ignore device entries */
				/*NOP*/;
			}

		}

		closedir(dir);
		ok = 1;

	}
	else {
		DL_ASSERT(CU::Concatenate("Cannot open directory %s", aDirName));
	}
}
Esempio n. 4
0
void LevelFactory::ReadXML(const std::string& aFilePath)
{
	Prism::Engine::GetInstance()->GetModelLoader()->Pause();

	Prism::Engine::GetInstance()->myIsLoading = true;


	FindTextures("Data/Resource/Texture/Particle/");

	myCurrentLevel->myScene = new Prism::Scene();
	myCurrentLevel->myWeaponFactory = new WeaponFactory();
	myCurrentLevel->myWeaponFactory->LoadWeapons("Data/Script/LI_list_weapon.xml");
	myCurrentLevel->myWeaponFactory->LoadProjectiles("Data/Script/LI_list_projectile.xml");
	myCurrentLevel->myEntityFactory = new EntityFactory(myCurrentLevel->myWeaponFactory);
	myCurrentLevel->myEntityFactory->LoadEntites("Data/Script/LI_list_entity.xml", myDifficults[myCurrentDifficultyID].myMultiplier);
	myCurrentLevel->myCollisionManager = new CollisionManager();
	myCurrentLevel->myBulletManager = new BulletManager(*myCurrentLevel->myCollisionManager, *myCurrentLevel->myScene);
	myCurrentLevel->myBulletManager->LoadFromFactory(myCurrentLevel->myWeaponFactory, myCurrentLevel->myEntityFactory, "Data/Script/LI_list_projectile.xml");

	myDirectionalLights.DeleteAll();
	myPointLights.DeleteAll();
	mySpotLights.DeleteAll();


	LoadPlayer();

	myCurrentLevel->myEmitterManager = new EmitterManager(myCurrentLevel->myPlayer);
	

	ReadLevelSettings();
	myCurrentLevel->myEntities.Add(myCurrentLevel->myPlayer);
	myCurrentLevel->myCamera = new Prism::Camera(myCurrentLevel->myPlayer->myOrientation);
	myCurrentLevel->myPlayer->GetComponent<GUIComponent>()->SetCamera(myCurrentLevel->myCamera);
	myCurrentLevel->GetEmitterManager()->AddEmitter(myCurrentLevel->myPlayer->GetComponent<ParticleEmitterComponent>());
	myCurrentLevel->myPlayer->SetPlayerScene(*myCurrentLevel->myScene);

	Sleep(10);
	XMLReader reader;
	reader.OpenDocument(aFilePath);
	tinyxml2::XMLElement* levelElement = reader.ForceFindFirstChild("root");
	levelElement = reader.ForceFindFirstChild(levelElement, "scene");
	std::string skySphere;
	std::string cubeMap;
	std::string missionXML;
	std::string eventXML;
	std::string conversationXML;

	reader.ForceReadAttribute(reader.ForceFindFirstChild(levelElement, "missionxml"), "source", missionXML);
	reader.ForceReadAttribute(reader.ForceFindFirstChild(levelElement, "eventxml"), "source", eventXML);
	reader.ForceReadAttribute(reader.ForceFindFirstChild(levelElement, "conversationxml"), "source", conversationXML);

	CU::Vector3<float> playerPos;
	CU::Vector3<float> playerRot;
	tinyxml2::XMLElement* playerPosElement;
	playerPosElement = reader.ForceFindFirstChild(levelElement, "PlayerStartTranslate");
	playerPosElement = reader.ForceFindFirstChild(playerPosElement, "position");
	reader.ForceReadAttribute(playerPosElement, "X", playerPos.x);
	reader.ForceReadAttribute(playerPosElement, "Y", playerPos.y);
	reader.ForceReadAttribute(playerPosElement, "Z", playerPos.z);
	
	playerPosElement = reader.ForceFindFirstChild(levelElement, "PlayerStartTranslate");
	playerPosElement = reader.ForceFindFirstChild(playerPosElement, "rotation");
	reader.ForceReadAttribute(playerPosElement, "X", playerRot.x);
	reader.ForceReadAttribute(playerPosElement, "Y", playerRot.y);
	reader.ForceReadAttribute(playerPosElement, "Z", playerRot.z);

	myCurrentLevel->myPlayer->myOrientation = CU::Matrix44f();

	myCurrentLevel->myPlayer->myOrientation = myCurrentLevel->myPlayer->myOrientation.CreateRotateAroundX(playerRot.x) 
		* myCurrentLevel->myPlayer->myOrientation;
	myCurrentLevel->myPlayer->myOrientation = myCurrentLevel->myPlayer->myOrientation.CreateRotateAroundY(playerRot.y) 
		* myCurrentLevel->myPlayer->myOrientation;
	myCurrentLevel->myPlayer->myOrientation = myCurrentLevel->myPlayer->myOrientation.CreateRotateAroundZ(playerRot.z) 
		* myCurrentLevel->myPlayer->myOrientation;

	myCurrentLevel->myPlayer->myOrientation = CU::GetOrientation(myCurrentLevel->myPlayer->myOrientation, playerRot);

	myCurrentLevel->myPlayer->myOrientation.SetPos(playerPos * 10.f);
	myCurrentLevel->myPlayer->myOriginalOrientation = myCurrentLevel->myPlayer->myOrientation;

	myCurrentLevel->myPlayer->Reset();

	myCurrentLevel->myConversationManager = new ConversationManager(conversationXML);
	myCurrentLevel->myMissionManager = new MissionManager(*myCurrentLevel, *myCurrentLevel->myPlayer, missionXML);
	myCurrentLevel->myEventManager = new EventManager(eventXML, *myCurrentLevel->myConversationManager
		, *myCurrentLevel->myPlayer);

	reader.ReadAttribute(reader.ForceFindFirstChild(levelElement, "skysphere"), "source", skySphere);
	reader.ReadAttribute(reader.ForceFindFirstChild(levelElement, "cubemap"), "source", cubeMap);

	Prism::Engine::GetInstance()->GetEffectContainer()->SetCubeMap(cubeMap);

	SetSkySphere(skySphere, "Data/Resource/Shader/S_effect_skybox.fx");

	LoadLights(reader, levelElement);
	LoadProps(reader, levelElement);
	LoadDefendables(reader, levelElement, myDifficults[myCurrentDifficultyID].myHealthMultiplier);
	LoadStructures(reader, levelElement);
	LoadTriggers(reader, levelElement);
	LoadPowerups(reader, levelElement);
	
	reader.CloseDocument();

	myCurrentLevel->myEMPHexagon = new Entity(eEntityType::EMP, *myCurrentLevel->myScene, Prism::eOctreeType::STATIC
		, "EMP");
	myCurrentLevel->myEMPHexagon->AddComponent<GraphicsComponent>()->Init("Data/Resource/Model/Weapon/SM_emp_hexasphere.fbx"
		, "Data/Resource/Shader/S_effect_emp.fx");

	myCurrentLevel->myEMPHexagon2 = new Entity(eEntityType::EMP, *myCurrentLevel->myScene, Prism::eOctreeType::STATIC
		, "EMP");
	myCurrentLevel->myEMPHexagon2->AddComponent<GraphicsComponent>()->Init("Data/Resource/Model/Weapon/SM_emp_hexasphere.fbx"
		, "Data/Resource/Shader/S_effect_emp.fx");


	for (int i = 0; i < myCurrentLevel->myEntities.Size(); ++i)
	{
		if (myCurrentLevel->myEntities[i]->GetComponent<AIComponent>() != nullptr)
		{
			std::string targetName = myCurrentLevel->myEntities[i]->GetComponent<AIComponent>()->GetTargetName();
			Entity* target = myCurrentLevel->GetEntityWithName(targetName);
			myCurrentLevel->myEntities[i]->GetComponent<AIComponent>()->SetEntityToFollow(myCurrentLevel->myPlayer, myCurrentLevel->myPlayer);
			if (target != nullptr)
			{
				myCurrentLevel->myEntities[i]->GetComponent<AIComponent>()->SetEntityToFollow(target, myCurrentLevel->myPlayer);
			}
		}

		if (myCurrentLevel->myEntities[i]->GetComponent<ParticleEmitterComponent>() != nullptr)
		{
			myCurrentLevel->myEmitterManager->AddEmitter(myCurrentLevel->myEntities[i]->GetComponent<ParticleEmitterComponent>());
		}
	}

	for (int i = 0; i < static_cast<int>(eBulletType::COUNT); ++i)
	{
		if (i <= 8)
		{
			for (int j = 0; j < myCurrentLevel->myBulletManager->GetBullet(i)->myPlayerBullets.Size(); ++j)
			{
				if (myCurrentLevel->myBulletManager->GetBullet(i)->myPlayerBullets[j]->GetComponent<ParticleEmitterComponent>() != nullptr)
				{
					myCurrentLevel->myEmitterManager->AddEmitter(myCurrentLevel->myBulletManager->GetBullet(i)->myPlayerBullets[j]->GetComponent<ParticleEmitterComponent>());
				}
				if (myCurrentLevel->myBulletManager->GetBullet(i)->myEnemyBullets[j]->GetComponent<ParticleEmitterComponent>() != nullptr)
				{
					myCurrentLevel->myEmitterManager->AddEmitter(myCurrentLevel->myBulletManager->GetBullet(i)->myEnemyBullets[j]->GetComponent<ParticleEmitterComponent>());
				}
			}
		}
	}
	AddToScene();

	myCurrentLevel->myMissionManager->Init();

	myCurrentLevel->myPlayer->GetComponent<InputComponent>()->SetSkyPosition();
	myCurrentLevel->myPlayer->GetComponent<GUIComponent>()->SetCockpitOrientation();

	Prism::Engine::GetInstance()->GetModelLoader()->UnPause();
	Prism::Engine::GetInstance()->GetModelLoader()->WaitUntilFinished();


	
	Prism::Engine::GetInstance()->GetEffectContainer()->GetEffect("Data/Resource/Shader/S_effect_pbl.fx")->SetAmbientHue(myAmbientHue);
	Prism::Engine::GetInstance()->myIsLoading = false;

	myIsLoading = false;
}
Esempio n. 5
0
S3DModel* CAssParser::Load(const std::string& modelFilePath)
{
	LOG_SL(LOG_SECTION_MODEL, L_INFO, "Loading model: %s", modelFilePath.c_str());

	const std::string& modelPath = FileSystem::GetDirectory(modelFilePath);
	const std::string& modelName = FileSystem::GetBasename(modelFilePath);

	// Load the lua metafile. This contains properties unique to Spring models and must return a table
	std::string metaFileName = modelFilePath + ".lua";

	if (!CFileHandler::FileExists(metaFileName, SPRING_VFS_ZIP)) {
		// Try again without the model file extension
		metaFileName = modelPath + '/' + modelName + ".lua";
	}
	if (!CFileHandler::FileExists(metaFileName, SPRING_VFS_ZIP)) {
		LOG_SL(LOG_SECTION_MODEL, L_INFO, "No meta-file '%s'. Using defaults.", metaFileName.c_str());
	}

	LuaParser metaFileParser(metaFileName, SPRING_VFS_MOD_BASE, SPRING_VFS_ZIP);

	if (!metaFileParser.Execute()) {
		LOG_SL(LOG_SECTION_MODEL, L_INFO, "'%s': %s. Using defaults.", metaFileName.c_str(), metaFileParser.GetErrorLog().c_str());
	}

	// Get the (root-level) model table
	const LuaTable& modelTable = metaFileParser.GetRoot();

	if (!modelTable.IsValid()) {
		LOG_SL(LOG_SECTION_MODEL, L_INFO, "No valid model metadata in '%s' or no meta-file", metaFileName.c_str());
	}


	// Create a model importer instance
	Assimp::Importer importer;


	// Give the importer an IO class that handles Spring's VFS
	importer.SetIOHandler(new AssVFSSystem());
	// Speed-up processing by skipping things we don't need
	importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, ASS_IMPORTER_OPTIONS);

#ifndef BITMAP_NO_OPENGL
	{
		importer.SetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,   maxVertices);
		importer.SetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, maxIndices / 3);
	}
#endif

	// Read the model file to build a scene object
	LOG_SL(LOG_SECTION_MODEL, L_INFO, "Importing model file: %s", modelFilePath.c_str());

	const aiScene* scene = nullptr;

	{
		// ASSIMP spams many SIGFPEs atm in normal & tangent generation
		ScopedDisableFpuExceptions fe;
		scene = importer.ReadFile(modelFilePath, ASS_POSTPROCESS_OPTIONS);
	}

	if (scene != nullptr) {
		LOG_SL(LOG_SECTION_MODEL, L_INFO,
			"Processing scene for model: %s (%d meshes / %d materials / %d textures)",
			modelFilePath.c_str(), scene->mNumMeshes, scene->mNumMaterials,
			scene->mNumTextures);
	} else {
		throw content_error("[AssimpParser] Model Import: " + std::string(importer.GetErrorString()));
	}

	ModelPieceMap pieceMap;
	ParentNameMap parentMap;

	S3DModel* model = new S3DModel();
	model->name = modelFilePath;
	model->type = MODELTYPE_ASS;

	// Load textures
	FindTextures(model, scene, modelTable, modelPath, modelName);
	LOG_SL(LOG_SECTION_MODEL, L_INFO, "Loading textures. Tex1: '%s' Tex2: '%s'", model->texs[0].c_str(), model->texs[1].c_str());

	texturehandlerS3O->PreloadTexture(model, modelTable.GetBool("fliptextures", true), modelTable.GetBool("invertteamcolor", true));

	// Load all pieces in the model
	LOG_SL(LOG_SECTION_MODEL, L_INFO, "Loading pieces from root node '%s'", scene->mRootNode->mName.data);
	LoadPiece(model, scene->mRootNode, scene, modelTable, pieceMap, parentMap);

	// Update piece hierarchy based on metadata
	BuildPieceHierarchy(model, pieceMap, parentMap);
	CalculateModelProperties(model, modelTable);

	// Verbose logging of model properties
	LOG_SL(LOG_SECTION_MODEL, L_DEBUG, "model->name: %s", model->name.c_str());
	LOG_SL(LOG_SECTION_MODEL, L_DEBUG, "model->numobjects: %d", model->numPieces);
	LOG_SL(LOG_SECTION_MODEL, L_DEBUG, "model->radius: %f", model->radius);
	LOG_SL(LOG_SECTION_MODEL, L_DEBUG, "model->height: %f", model->height);
	LOG_SL(LOG_SECTION_MODEL, L_DEBUG, "model->mins: (%f,%f,%f)", model->mins[0], model->mins[1], model->mins[2]);
	LOG_SL(LOG_SECTION_MODEL, L_DEBUG, "model->maxs: (%f,%f,%f)", model->maxs[0], model->maxs[1], model->maxs[2]);
	LOG_SL(LOG_SECTION_MODEL, L_INFO, "Model %s Imported.", model->name.c_str());
	return model;
}