Retour
Version Originale

./aip/1.8aipmod/source/Irrlicht/CSceneLoaderIrr.cpp :


#include "CSceneLoaderIrr.h"
#include "ISceneNodeAnimatorFactory.h"
#include "ISceneUserDataSerializer.h"
#include "ISceneManager.h"
#include "IVideoDriver.h"
#include "IFileSystem.h"
#include "os.h"

namespace irr
{
namespace scene
{

//! Constructor

CSceneLoaderIrr::CSceneLoaderIrr(ISceneManager *smgr, io::IFileSystem* fs)
 : SceneManager(smgr), FileSystem(fs),
   IRR_XML_FORMAT_SCENE(L"irr_scene"), IRR_XML_FORMAT_NODE(L"node"), IRR_XML_FORMAT_NODE_ATTR_TYPE(L"type"),
   IRR_XML_FORMAT_ATTRIBUTES(L"attributes"), IRR_XML_FORMAT_MATERIALS(L"materials"),
   IRR_XML_FORMAT_ANIMATORS(L"animators"), IRR_XML_FORMAT_USERDATA(L"userData")
{

}

//! Destructor

CSceneLoaderIrr::~CSceneLoaderIrr()
{

}

//! Returns true if the class might be able to load this file.

bool CSceneLoaderIrr::isALoadableFileExtension(const io::path& filename) const
{
	return core::hasFileExtension(filename, "irr");
}

//! Returns true if the class might be able to load this file.

bool CSceneLoaderIrr::isALoadableFileFormat(io::IReadFile *file) const
{
	// todo: check inside the file

	return true;
}

//! Loads the scene into the scene manager.

bool CSceneLoaderIrr::loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer,
	ISceneNode* rootNode)
{
	if (!file)
	{
		os::Printer::log("Unable to open scene file", ELL_ERROR);
		return false;
	}

	io::IXMLReader* reader = FileSystem->createXMLReader(file);
	if (!reader)
	{
		os::Printer::log("Scene is not a valid XML file", file->getFileName().c_str(), ELL_ERROR);
		return false;
	}

	// TODO: COLLADA_CREATE_SCENE_INSTANCES can be removed when the COLLADA loader is a scene loader

	bool oldColladaSingleMesh = SceneManager->getParameters()->getAttributeAsBool(COLLADA_CREATE_SCENE_INSTANCES);
	SceneManager->getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, false);

	// read file

	while (reader->read())
	{
		readSceneNode(reader, rootNode, userDataSerializer);
	}

	// restore old collada parameters

	SceneManager->getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, oldColladaSingleMesh);

	// clean up

	reader->drop();
	return true;
}
//! Reads the next node

void CSceneLoaderIrr::readSceneNode(io::IXMLReader* reader, ISceneNode* parent,
	ISceneUserDataSerializer* userDataSerializer)
{
	if (!reader)
		return;

	scene::ISceneNode* node = 0;

	if (!parent && IRR_XML_FORMAT_SCENE==reader->getNodeName())
		node = SceneManager->getRootSceneNode();
	else if (parent && IRR_XML_FORMAT_NODE==reader->getNodeName())
	{
		// find node type and create it

		core::stringc attrName = reader->getAttributeValue(IRR_XML_FORMAT_NODE_ATTR_TYPE.c_str());

		node = SceneManager->addSceneNode(attrName.c_str(), parent);

		if (!node)
			os::Printer::log("Could not create scene node of unknown type", attrName.c_str());
	}

	// read attributes

	while(reader->read())
	{
		bool endreached = false;

		const wchar_t* name = reader->getNodeName();

		switch (reader->getNodeType())
		{
		case io::EXN_ELEMENT_END:
			if ((IRR_XML_FORMAT_NODE  == name) ||
				(IRR_XML_FORMAT_SCENE == name))
			{
				endreached = true;
			}
			break;
		case io::EXN_ELEMENT:
			if (IRR_XML_FORMAT_ATTRIBUTES == name)
			{
				// read attributes

				io::IAttributes* attr = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver());
				attr->read(reader, true);

				if (node)
					node->deserializeAttributes(attr);

				attr->drop();
			}
			else
			if (IRR_XML_FORMAT_MATERIALS == name)
				readMaterials(reader, node);
			else
			if (IRR_XML_FORMAT_ANIMATORS == name)
				readAnimators(reader, node);
			else
			if (IRR_XML_FORMAT_USERDATA  == name)
				readUserData(reader, node, userDataSerializer);
			else
			if ((IRR_XML_FORMAT_NODE  == name) ||
				(IRR_XML_FORMAT_SCENE == name))
			{
				readSceneNode(reader, node, userDataSerializer);
			}
			else
			{
				os::Printer::log("Found unknown element in irrlicht scene file",
						core::stringc(name).c_str());
			}
			break;
		default:
			break;
		}

		if (endreached)
			break;
	}
	if (node && userDataSerializer)
		userDataSerializer->OnCreateNode(node);
}

//! reads materials of a node

void CSceneLoaderIrr::readMaterials(io::IXMLReader* reader, ISceneNode* node)
{
	u32 nr = 0;

	while(reader->read())
	{
		const wchar_t* name = reader->getNodeName();

		switch(reader->getNodeType())
		{
		case io::EXN_ELEMENT_END:
			if (IRR_XML_FORMAT_MATERIALS == name)
				return;
			break;
		case io::EXN_ELEMENT:
			if (IRR_XML_FORMAT_ATTRIBUTES == name)
			{
				// read materials from attribute list

				io::IAttributes* attr = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver());
				attr->read(reader);

				if (node && node->getMaterialCount() > nr)
				{
					SceneManager->getVideoDriver()->fillMaterialStructureFromAttributes(
						node->getMaterial(nr), attr);
				}

				attr->drop();
				++nr;
			}
			break;
		default:
			break;
		}
	}
}


//! reads animators of a node

void CSceneLoaderIrr::readAnimators(io::IXMLReader* reader, ISceneNode* node)
{
	while(reader->read())
	{
		const wchar_t* name = reader->getNodeName();

		switch(reader->getNodeType())
		{
		case io::EXN_ELEMENT_END:
			if (IRR_XML_FORMAT_ANIMATORS == name)
				return;
			break;
		case io::EXN_ELEMENT:
			if (IRR_XML_FORMAT_ATTRIBUTES == name)
			{
				// read animator data from attribute list

				io::IAttributes* attr = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver());
				attr->read(reader);

				if (node)
				{
					core::stringc typeName = attr->getAttributeAsString("Type");
					ISceneNodeAnimator* anim = 0;

					// todo: need a method to add animator by name in the scene manager. This loader and others like it

					// have no business messing with the animator factories! 

					for (s32 i=SceneManager->getRegisteredSceneNodeAnimatorFactoryCount(); i >=0 && !anim; --i)
						anim = SceneManager->getSceneNodeAnimatorFactory(i)->createSceneNodeAnimator(typeName.c_str(), node);

					if (anim)
					{
						anim->deserializeAttributes(attr);
						anim->drop();
					}
				}

				attr->drop();
			}
			break;
		default:
			break;
		}
	}
}


//! reads user data of a node

void CSceneLoaderIrr::readUserData(io::IXMLReader* reader, ISceneNode* node, ISceneUserDataSerializer* userDataSerializer)
{
	while(reader->read())
	{
		const wchar_t* name = reader->getNodeName();

		switch(reader->getNodeType())
		{
		case io::EXN_ELEMENT_END:
			if (IRR_XML_FORMAT_USERDATA == name)
				return;
			break;
		case io::EXN_ELEMENT:
			if (IRR_XML_FORMAT_ATTRIBUTES == name)
			{
				// read user data from attribute list

				io::IAttributes* attr = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver());
				attr->read(reader);

				if (node && userDataSerializer)
				{
					userDataSerializer->OnReadUserData(node, attr);
				}

				attr->drop();
			}
			break;
		default:
			break;
		}
	}
}

} // scene

} // irr


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
881 membres
1426 sujets
11116 messages
Dernier membre inscrit: Bidule
16 invités en ligne
Aucun membre connecté
RSS Feed