From f9158592e1478b2013afc7041d9ed041cf2d2f4a Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Mon, 13 Jan 2014 19:47:58 +1000 Subject: Update Irrlicht to 1.8.1. Include actual change markers this time. lol --- .../source/Irrlicht/CColladaFileLoader.cpp | 2957 -------------------- 1 file changed, 2957 deletions(-) delete mode 100644 libraries/irrlicht-1.8/source/Irrlicht/CColladaFileLoader.cpp (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CColladaFileLoader.cpp') diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CColladaFileLoader.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CColladaFileLoader.cpp deleted file mode 100644 index 210a59b..0000000 --- a/libraries/irrlicht-1.8/source/Irrlicht/CColladaFileLoader.cpp +++ /dev/null @@ -1,2957 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#include "IrrCompileConfig.h" -#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_ - -#include "CColladaFileLoader.h" -#include "os.h" -#include "IXMLReader.h" -#include "IDummyTransformationSceneNode.h" -#include "SAnimatedMesh.h" -#include "fast_atof.h" -#include "quaternion.h" -#include "ILightSceneNode.h" -#include "ICameraSceneNode.h" -#include "IMeshManipulator.h" -#include "IReadFile.h" -#include "IAttributes.h" -#include "IMeshCache.h" -#include "IMeshSceneNode.h" -#include "SMeshBufferLightMap.h" -#include "irrMap.h" - -#ifdef _DEBUG -#define COLLADA_READER_DEBUG -#endif -namespace irr -{ -namespace scene -{ -namespace -{ - // currently supported COLLADA tag names - const core::stringc colladaSectionName = "COLLADA"; - const core::stringc librarySectionName = "library"; - const core::stringc libraryNodesSectionName = "library_nodes"; - const core::stringc libraryGeometriesSectionName = "library_geometries"; - const core::stringc libraryMaterialsSectionName = "library_materials"; - const core::stringc libraryImagesSectionName = "library_images"; - const core::stringc libraryVisualScenesSectionName = "library_visual_scenes"; - const core::stringc libraryCamerasSectionName = "library_cameras"; - const core::stringc libraryLightsSectionName = "library_lights"; - const core::stringc libraryEffectsSectionName = "library_effects"; - const core::stringc assetSectionName = "asset"; - const core::stringc sceneSectionName = "scene"; - const core::stringc visualSceneSectionName = "visual_scene"; - - const core::stringc lightPrefabName = "light"; - const core::stringc cameraPrefabName = "camera"; - const core::stringc materialSectionName = "material"; - const core::stringc geometrySectionName = "geometry"; - const core::stringc imageSectionName = "image"; - const core::stringc textureSectionName = "texture"; - const core::stringc effectSectionName = "effect"; - - const core::stringc pointSectionName = "point"; - const core::stringc directionalSectionName ="directional"; - const core::stringc spotSectionName = "spot"; - const core::stringc ambientSectionName = "ambient"; - const core::stringc meshSectionName = "mesh"; - const core::stringc sourceSectionName = "source"; - const core::stringc arraySectionName = "array"; - const core::stringc floatArraySectionName ="float_array"; - const core::stringc intArraySectionName = "int_array"; - const core::stringc techniqueCommonSectionName = "technique_common"; - const core::stringc accessorSectionName = "accessor"; - const core::stringc verticesSectionName = "vertices"; - const core::stringc inputTagName = "input"; - const core::stringc polylistSectionName = "polylist"; - const core::stringc trianglesSectionName = "triangles"; - const core::stringc polygonsSectionName = "polygons"; - const core::stringc primitivesName = "p"; - const core::stringc vcountName = "vcount"; - - const core::stringc upAxisNodeName = "up_axis"; - const core::stringc nodeSectionName = "node"; - const core::stringc lookatNodeName = "lookat"; - const core::stringc matrixNodeName = "matrix"; - const core::stringc perspectiveNodeName = "perspective"; - const core::stringc rotateNodeName = "rotate"; - const core::stringc scaleNodeName = "scale"; - const core::stringc translateNodeName = "translate"; - const core::stringc skewNodeName = "skew"; - const core::stringc bboxNodeName = "boundingbox"; - const core::stringc minNodeName = "min"; - const core::stringc maxNodeName = "max"; - const core::stringc instanceName = "instance"; - const core::stringc instanceGeometryName = "instance_geometry"; - const core::stringc instanceSceneName = "instance_visual_scene"; - const core::stringc instanceEffectName = "instance_effect"; - const core::stringc instanceMaterialName = "instance_material"; - const core::stringc instanceLightName = "instance_light"; - const core::stringc instanceNodeName = "instance_node"; - const core::stringc bindMaterialName = "bind_material"; - const core::stringc extraNodeName = "extra"; - const core::stringc techniqueNodeName = "technique"; - const core::stringc colorNodeName = "color"; - const core::stringc floatNodeName = "float"; - const core::stringc float2NodeName = "float2"; - const core::stringc float3NodeName = "float3"; - - const core::stringc newParamName = "newparam"; - const core::stringc paramTagName = "param"; - const core::stringc initFromName = "init_from"; - const core::stringc dataName = "data"; - const core::stringc wrapsName = "wrap_s"; - const core::stringc wraptName = "wrap_t"; - const core::stringc minfilterName = "minfilter"; - const core::stringc magfilterName = "magfilter"; - const core::stringc mipfilterName = "mipfilter"; - - const core::stringc textureNodeName = "texture"; - const core::stringc doubleSidedNodeName = "double_sided"; - const core::stringc constantAttenuationNodeName = "constant_attenuation"; - const core::stringc linearAttenuationNodeName = "linear_attenuation"; - const core::stringc quadraticAttenuationNodeName = "quadratic_attenuation"; - const core::stringc falloffAngleNodeName = "falloff_angle"; - const core::stringc falloffExponentNodeName = "falloff_exponent"; - - const core::stringc profileCOMMONSectionName = "profile_COMMON"; - const core::stringc profileCOMMONAttributeName = "COMMON"; - - const char* const inputSemanticNames[] = {"POSITION", "VERTEX", "NORMAL", "TEXCOORD", - "UV", "TANGENT", "IMAGE", "TEXTURE", 0}; - - // We have to read ambient lights like other light types here, so we need a type for it - const video::E_LIGHT_TYPE ELT_AMBIENT = video::E_LIGHT_TYPE(video::ELT_COUNT+1); -} - - //! following class is for holding and creating instances of library - //! objects, named prefabs in this loader. - class CPrefab : public IColladaPrefab - { - public: - - CPrefab(const core::stringc& id) : Id(id) - { - } - - //! creates an instance of this prefab - virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, - scene::ISceneManager* mgr) - { - // empty implementation - return 0; - } - - //! returns id of this prefab - virtual const core::stringc& getId() - { - return Id; - } - - protected: - - core::stringc Id; - }; - - - //! prefab for a light scene node - class CLightPrefab : public CPrefab - { - public: - - CLightPrefab(const core::stringc& id) : CPrefab(id) - { - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA: loaded light prefab", Id.c_str(), ELL_DEBUG); - #endif - } - - video::SLight LightData; // publically accessible - - //! creates an instance of this prefab - virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, - scene::ISceneManager* mgr) - { - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA: Constructing light instance", Id.c_str(), ELL_DEBUG); - #endif - - if ( LightData.Type == ELT_AMBIENT ) - { - mgr->setAmbientLight( LightData.DiffuseColor ); - return 0; - } - - scene::ILightSceneNode* l = mgr->addLightSceneNode(parent); - if (l) - { - l->setLightData ( LightData ); - l->setName(getId()); - } - return l; - } - }; - - - //! prefab for a mesh scene node - class CGeometryPrefab : public CPrefab - { - public: - - CGeometryPrefab(const core::stringc& id) : CPrefab(id) - { - } - - scene::IMesh* Mesh; - - //! creates an instance of this prefab - virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, - scene::ISceneManager* mgr) - { - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA: Constructing mesh instance", Id.c_str(), ELL_DEBUG); - #endif - - scene::ISceneNode* m = mgr->addMeshSceneNode(Mesh, parent); - if (m) - { - m->setName(getId()); -// m->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false); -// m->setDebugDataVisible(scene::EDS_FULL); - } - return m; - } - }; - - - //! prefab for a camera scene node - class CCameraPrefab : public CPrefab - { - public: - - CCameraPrefab(const core::stringc& id) - : CPrefab(id), YFov(core::PI / 2.5f), ZNear(1.0f), ZFar(3000.0f) - { - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA: loaded camera prefab", Id.c_str(), ELL_DEBUG); - #endif - } - - // publicly accessible data - f32 YFov; - f32 ZNear; - f32 ZFar; - - //! creates an instance of this prefab - virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, - scene::ISceneManager* mgr) - { - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA: Constructing camera instance", Id.c_str(), ELL_DEBUG); - #endif - - scene::ICameraSceneNode* c = mgr->addCameraSceneNode(parent); - if (c) - { - c->setFOV(YFov); - c->setNearValue(ZNear); - c->setFarValue(ZFar); - c->setName(getId()); - } - return c; - } - }; - - - //! prefab for a container scene node - //! Collects other prefabs and instantiates them upon instantiation - //! Uses a dummy scene node to return the children as one scene node - class CScenePrefab : public CPrefab - { - public: - CScenePrefab(const core::stringc& id) : CPrefab(id) - { - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA: loaded scene prefab", Id.c_str(), ELL_DEBUG); - #endif - } - - //! creates an instance of this prefab - virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, - scene::ISceneManager* mgr) - { - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA: Constructing scene instance", Id.c_str(), ELL_DEBUG); - #endif - - if (Children.size()==0) - return 0; - - scene::IDummyTransformationSceneNode* s = mgr->addDummyTransformationSceneNode(parent); - if (s) - { - s->setName(getId()); - s->getRelativeTransformationMatrix() = Transformation; - s->updateAbsolutePosition(); - core::stringc t; - for (u32 i=0; i<16; ++i) - { - t+=core::stringc((double)Transformation[i]); - t+=" "; - } - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA: Transformation", t.c_str(), ELL_DEBUG); - #endif - - for (u32 i=0; iaddInstance(s, mgr); - } - - return s; - } - - core::array Children; - core::matrix4 Transformation; - }; - - -//! Constructor -CColladaFileLoader::CColladaFileLoader(scene::ISceneManager* smgr, - io::IFileSystem* fs) -: SceneManager(smgr), FileSystem(fs), DummyMesh(0), - FirstLoadedMesh(0), LoadedMeshCount(0), CreateInstances(false) -{ - #ifdef _DEBUG - setDebugName("CColladaFileLoader"); - #endif -} - - -//! destructor -CColladaFileLoader::~CColladaFileLoader() -{ - if (DummyMesh) - DummyMesh->drop(); - - if (FirstLoadedMesh) - FirstLoadedMesh->drop(); -} - - -//! Returns true if the file maybe is able to be loaded by this class. -/** This decision should be based only on the file extension (e.g. ".cob") */ -bool CColladaFileLoader::isALoadableFileExtension(const io::path& filename) const -{ - return core::hasFileExtension ( filename, "xml", "dae" ); -} - - -//! creates/loads an animated mesh from the file. -//! \return Pointer to the created mesh. Returns 0 if loading failed. -//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). -//! See IReferenceCounted::drop() for more information. -IAnimatedMesh* CColladaFileLoader::createMesh(io::IReadFile* file) -{ - io::IXMLReaderUTF8* reader = FileSystem->createXMLReaderUTF8(file); - if (!reader) - return 0; - - CurrentlyLoadingMesh = file->getFileName(); - CreateInstances = SceneManager->getParameters()->getAttributeAsBool( - scene::COLLADA_CREATE_SCENE_INSTANCES); - Version = 0; - FlipAxis = false; - - // read until COLLADA section, skip other parts - - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - if (colladaSectionName == reader->getNodeName()) - readColladaSection(reader); - else - skipSection(reader, true); // unknown section - } - } - - reader->drop(); - if (!Version) - return 0; - - // because this loader loads and creates a complete scene instead of - // a single mesh, return an empty dummy mesh to make the scene manager - // know that everything went well. - if (!DummyMesh) - DummyMesh = new SAnimatedMesh(); - scene::IAnimatedMesh* returnMesh = DummyMesh; - - if (Version < 10400) - instantiateNode(SceneManager->getRootSceneNode()); - - // add the first loaded mesh into the mesh cache too, if more than one - // meshes have been loaded from the file - if (LoadedMeshCount>1 && FirstLoadedMesh) - { - os::Printer::log("Added COLLADA mesh", FirstLoadedMeshName.c_str()); - SceneManager->getMeshCache()->addMesh(FirstLoadedMeshName.c_str(), FirstLoadedMesh); - } - - // clean up temporary loaded data - clearData(); - - returnMesh->grab(); // store until this loader is destroyed - - DummyMesh->drop(); - DummyMesh = 0; - - if (FirstLoadedMesh) - FirstLoadedMesh->drop(); - FirstLoadedMesh = 0; - LoadedMeshCount = 0; - - return returnMesh; -} - - -//! skips an (unknown) section in the collada document -void CColladaFileLoader::skipSection(io::IXMLReaderUTF8* reader, bool reportSkipping) -{ - #ifndef COLLADA_READER_DEBUG - if (reportSkipping) // always report in COLLADA_READER_DEBUG mode - #endif - os::Printer::log("COLLADA skipping section", core::stringc(reader->getNodeName()).c_str(), ELL_DEBUG); - - // skip if this element is empty anyway. - if (reader->isEmptyElement()) - return; - - // read until we've reached the last element in this section - u32 tagCounter = 1; - - while(tagCounter && reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT && - !reader->isEmptyElement()) - { - #ifdef COLLADA_READER_DEBUG - if (reportSkipping) - os::Printer::log("Skipping COLLADA unknown element", core::stringc(reader->getNodeName()).c_str(), ELL_DEBUG); - #endif - - ++tagCounter; - } - else - if (reader->getNodeType() == io::EXN_ELEMENT_END) - --tagCounter; - } -} - - -//! reads the section and its content -void CColladaFileLoader::readColladaSection(io::IXMLReaderUTF8* reader) -{ - if (reader->isEmptyElement()) - return; - - // todo: patch level needs to be handled - const f32 version = core::fast_atof(core::stringc(reader->getAttributeValue("version")).c_str()); - Version = core::floor32(version)*10000+core::round32(core::fract(version)*1000.0f); - // Version 1.4 can be checked for by if (Version >= 10400) - - while(reader->read()) - if (reader->getNodeType() == io::EXN_ELEMENT) - { - if (assetSectionName == reader->getNodeName()) - readAssetSection(reader); - else - if (librarySectionName == reader->getNodeName()) - readLibrarySection(reader); - else - if (libraryNodesSectionName == reader->getNodeName()) - readLibrarySection(reader); - else - if (libraryGeometriesSectionName == reader->getNodeName()) - readLibrarySection(reader); - else - if (libraryMaterialsSectionName == reader->getNodeName()) - readLibrarySection(reader); - else - if (libraryEffectsSectionName == reader->getNodeName()) - readLibrarySection(reader); - else - if (libraryImagesSectionName == reader->getNodeName()) - readLibrarySection(reader); - else - if (libraryCamerasSectionName == reader->getNodeName()) - readLibrarySection(reader); - else - if (libraryLightsSectionName == reader->getNodeName()) - readLibrarySection(reader); - else - if (libraryVisualScenesSectionName == reader->getNodeName()) - readVisualScene(reader); - else - if (assetSectionName == reader->getNodeName()) - readAssetSection(reader); - else - if (sceneSectionName == reader->getNodeName()) - readSceneSection(reader); - else - { - os::Printer::log("COLLADA loader warning: Wrong tag usage found", reader->getNodeName(), ELL_WARNING); - skipSection(reader, true); // unknown section - } - } -} - - -//! reads a section and its content -void CColladaFileLoader::readLibrarySection(io::IXMLReaderUTF8* reader) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading library", ELL_DEBUG); - #endif - - if (reader->isEmptyElement()) - return; - - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - // animation section tbd - if (cameraPrefabName == reader->getNodeName()) - readCameraPrefab(reader); - else - // code section tbd - // controller section tbd - if (geometrySectionName == reader->getNodeName()) - readGeometry(reader); - else - if (imageSectionName == reader->getNodeName()) - readImage(reader); - else - if (lightPrefabName == reader->getNodeName()) - readLightPrefab(reader); - else - if (materialSectionName == reader->getNodeName()) - readMaterial(reader); - else - if (nodeSectionName == reader->getNodeName()) - { - CScenePrefab p(""); - - readNodeSection(reader, SceneManager->getRootSceneNode(), &p); - } - else - if (effectSectionName == reader->getNodeName()) - readEffect(reader); - else - // program section tbd - if (textureSectionName == reader->getNodeName()) - readTexture(reader); - else - skipSection(reader, true); // unknown section, not all allowed supported yet - } - else - if (reader->getNodeType() == io::EXN_ELEMENT_END) - { - if (librarySectionName == reader->getNodeName()) - break; // end reading. - if (libraryNodesSectionName == reader->getNodeName()) - break; // end reading. - if (libraryGeometriesSectionName == reader->getNodeName()) - break; // end reading. - if (libraryMaterialsSectionName == reader->getNodeName()) - break; // end reading. - if (libraryEffectsSectionName == reader->getNodeName()) - break; // end reading. - if (libraryImagesSectionName == reader->getNodeName()) - break; // end reading. - if (libraryLightsSectionName == reader->getNodeName()) - break; // end reading. - if (libraryCamerasSectionName == reader->getNodeName()) - break; // end reading. - } - } -} - - -//! reads a element and stores it as a prefab -void CColladaFileLoader::readVisualScene(io::IXMLReaderUTF8* reader) -{ - CScenePrefab* p = 0; - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - if (visualSceneSectionName == reader->getNodeName()) - p = new CScenePrefab(readId(reader)); - else - if (p && nodeSectionName == reader->getNodeName()) // as a child of visual_scene - readNodeSection(reader, SceneManager->getRootSceneNode(), p); - else - if (assetSectionName == reader->getNodeName()) - readAssetSection(reader); - else - if (extraNodeName == reader->getNodeName()) - skipSection(reader, false); // ignore all other sections - else - { - os::Printer::log("COLLADA loader warning: Wrong tag usage found", reader->getNodeName(), ELL_WARNING); - skipSection(reader, true); // ignore all other sections - } - } - else - if (reader->getNodeType() == io::EXN_ELEMENT_END) - { - if (libraryVisualScenesSectionName == reader->getNodeName()) - return; - else - if ((visualSceneSectionName == reader->getNodeName()) && p) - { - Prefabs.push_back(p); - p = 0; - } - } - } -} - - -//! reads a section and its content -void CColladaFileLoader::readSceneSection(io::IXMLReaderUTF8* reader) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading scene", ELL_DEBUG); - #endif - - if (reader->isEmptyElement()) - return; - - // read the scene - - core::matrix4 transform; // transformation of this node - core::aabbox3df bbox; - scene::IDummyTransformationSceneNode* node = 0; - - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - if (lookatNodeName == reader->getNodeName()) - transform *= readLookAtNode(reader); - else - if (matrixNodeName == reader->getNodeName()) - transform *= readMatrixNode(reader); - else - if (perspectiveNodeName == reader->getNodeName()) - transform *= readPerspectiveNode(reader); - else - if (rotateNodeName == reader->getNodeName()) - transform *= readRotateNode(reader); - else - if (scaleNodeName == reader->getNodeName()) - transform *= readScaleNode(reader); - else - if (skewNodeName == reader->getNodeName()) - transform *= readSkewNode(reader); - else - if (translateNodeName == reader->getNodeName()) - transform *= readTranslateNode(reader); - else - if (bboxNodeName == reader->getNodeName()) - readBboxNode(reader, bbox); - else - if (nodeSectionName == reader->getNodeName()) - { - // create dummy node if there is none yet. - if (!node) - node = SceneManager->addDummyTransformationSceneNode(SceneManager->getRootSceneNode()); - - readNodeSection(reader, node); - } - else - if ((instanceSceneName == reader->getNodeName())) - readInstanceNode(reader, SceneManager->getRootSceneNode(), 0, 0,instanceSceneName); - else - if (extraNodeName == reader->getNodeName()) - skipSection(reader, false); - else - { - os::Printer::log("COLLADA loader warning: Wrong tag usage found", reader->getNodeName(), ELL_WARNING); - skipSection(reader, true); // ignore all other sections - } - } - else - if ((reader->getNodeType() == io::EXN_ELEMENT_END) && - (sceneSectionName == reader->getNodeName())) - return; - } - if (node) - node->getRelativeTransformationMatrix() = transform; -} - - -//! reads a section and its content -void CColladaFileLoader::readAssetSection(io::IXMLReaderUTF8* reader) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading asset", ELL_DEBUG); - #endif - - if (reader->isEmptyElement()) - return; - - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - if (upAxisNodeName == reader->getNodeName()) - { - reader->read(); - FlipAxis = (core::stringc("Z_UP") == reader->getNodeData()); - } - } - else - if ((reader->getNodeType() == io::EXN_ELEMENT_END) && - (assetSectionName == reader->getNodeName())) - return; - } -} - - -//! reads a section and its content -void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISceneNode* parent, CScenePrefab* p) -{ - if (reader->isEmptyElement()) - { - return; - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading empty node", ELL_DEBUG); - #endif - } - - core::stringc name = readId(reader); - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading node", name, ELL_DEBUG); - #endif - - core::matrix4 transform; // transformation of this node - core::aabbox3df bbox; - scene::ISceneNode* node = 0; // instance - CScenePrefab* nodeprefab = 0; // prefab for library_nodes usage - - if (p) - { - nodeprefab = new CScenePrefab(readId(reader)); - p->Children.push_back(nodeprefab); - Prefabs.push_back(nodeprefab); // in order to delete them later on - } - - // read the node - - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - if (assetSectionName == reader->getNodeName()) - readAssetSection(reader); - else - if (lookatNodeName == reader->getNodeName()) - transform *= readLookAtNode(reader); - else - if (matrixNodeName == reader->getNodeName()) - transform *= readMatrixNode(reader); - else - if (perspectiveNodeName == reader->getNodeName()) - transform *= readPerspectiveNode(reader); - else - if (rotateNodeName == reader->getNodeName()) - transform *= readRotateNode(reader); - else - if (scaleNodeName == reader->getNodeName()) - transform *= readScaleNode(reader); - else - if (skewNodeName == reader->getNodeName()) - transform *= readSkewNode(reader); - else - if (translateNodeName == reader->getNodeName()) - transform *= readTranslateNode(reader); - else - if (bboxNodeName == reader->getNodeName()) - readBboxNode(reader, bbox); - else - if ((instanceName == reader->getNodeName()) || - (instanceNodeName == reader->getNodeName()) || - (instanceGeometryName == reader->getNodeName()) || - (instanceLightName == reader->getNodeName())) - { - scene::ISceneNode* newnode = 0; - readInstanceNode(reader, parent, &newnode, nodeprefab, reader->getNodeName()); - - if (node && newnode) - { - // move children from dummy to new node - ISceneNodeList::ConstIterator it = node->getChildren().begin(); - for (; it != node->getChildren().end(); it = node->getChildren().begin()) - (*it)->setParent(newnode); - - // remove previous dummy node - node->remove(); - node = newnode; - } - } - else - if (nodeSectionName == reader->getNodeName()) - { - // create dummy node if there is none yet. - if (CreateInstances && !node) - { - scene::IDummyTransformationSceneNode* dummy = - SceneManager->addDummyTransformationSceneNode(parent); - dummy->getRelativeTransformationMatrix() = transform; - node = dummy; - } - else - node = parent; - - // read and add child - readNodeSection(reader, node, nodeprefab); - } - else - if (extraNodeName == reader->getNodeName()) - skipSection(reader, false); - else - skipSection(reader, true); // ignore all other sections - - } // end if node - else - if (reader->getNodeType() == io::EXN_ELEMENT_END) - { - if (nodeSectionName == reader->getNodeName()) - break; - } - } - - if (nodeprefab) - nodeprefab->Transformation = transform; - else - if (node) - { - // set transformation correctly into node. - node->setPosition(transform.getTranslation()); - node->setRotation(transform.getRotationDegrees()); - node->setScale(transform.getScale()); - node->updateAbsolutePosition(); - - node->setName(name); - } -} - - -//! reads a element and its content and creates a matrix from it -core::matrix4 CColladaFileLoader::readLookAtNode(io::IXMLReaderUTF8* reader) -{ - core::matrix4 mat; - if (reader->isEmptyElement()) - return mat; - - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading look at node", ELL_DEBUG); - #endif - - f32 floats[9]; - readFloatsInsideElement(reader, floats, 9); - - mat.buildCameraLookAtMatrixLH( - core::vector3df(floats[0], floats[1], floats[2]), - core::vector3df(floats[3], floats[4], floats[5]), - core::vector3df(floats[6], floats[7], floats[8])); - - return mat; -} - - -//! reads a element and its content and creates a matrix from it -core::matrix4 CColladaFileLoader::readSkewNode(io::IXMLReaderUTF8* reader) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading skew node", ELL_DEBUG); - #endif - - core::matrix4 mat; - if (reader->isEmptyElement()) - return mat; - - f32 floats[7]; // angle rotation-axis translation-axis - readFloatsInsideElement(reader, floats, 7); - - // build skew matrix from these 7 floats - core::quaternion q; - q.fromAngleAxis(floats[0]*core::DEGTORAD, core::vector3df(floats[1], floats[2], floats[3])); - mat = q.getMatrix(); - - if (floats[4]==1.f) // along x-axis - { - mat[4]=0.f; - mat[6]=0.f; - mat[8]=0.f; - mat[9]=0.f; - } - else - if (floats[5]==1.f) // along y-axis - { - mat[1]=0.f; - mat[2]=0.f; - mat[8]=0.f; - mat[9]=0.f; - } - else - if (floats[6]==1.f) // along z-axis - { - mat[1]=0.f; - mat[2]=0.f; - mat[4]=0.f; - mat[6]=0.f; - } - - return mat; -} - - -//! reads a element and its content and stores it in bbox -void CColladaFileLoader::readBboxNode(io::IXMLReaderUTF8* reader, - core::aabbox3df& bbox) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading boundingbox node", ELL_DEBUG); - #endif - - bbox.reset(core::aabbox3df()); - - if (reader->isEmptyElement()) - return; - - f32 floats[3]; - - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - if (minNodeName == reader->getNodeName()) - { - readFloatsInsideElement(reader, floats, 3); - bbox.MinEdge.set(floats[0], floats[1], floats[2]); - } - else - if (maxNodeName == reader->getNodeName()) - { - readFloatsInsideElement(reader, floats, 3); - bbox.MaxEdge.set(floats[0], floats[1], floats[2]); - } - else - skipSection(reader, true); // ignore all other sections - } - else - if (reader->getNodeType() == io::EXN_ELEMENT_END) - { - if (bboxNodeName == reader->getNodeName()) - break; - } - } -} - - -//! reads a element and its content and creates a matrix from it -core::matrix4 CColladaFileLoader::readMatrixNode(io::IXMLReaderUTF8* reader) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading matrix node", ELL_DEBUG); - #endif - - core::matrix4 mat; - if (reader->isEmptyElement()) - return mat; - - readFloatsInsideElement(reader, mat.pointer(), 16); - // put translation into the correct place - if (FlipAxis) - { - core::matrix4 mat2(mat, core::matrix4::EM4CONST_TRANSPOSED); - mat2[1]=mat[8]; - mat2[2]=mat[4]; - mat2[4]=mat[2]; - mat2[5]=mat[10]; - mat2[6]=mat[6]; - mat2[8]=mat[1]; - mat2[9]=mat[9]; - mat2[10]=mat[5]; - mat2[12]=mat[3]; - mat2[13]=mat[11]; - mat2[14]=mat[7]; - return mat2; - } - else - return core::matrix4(mat, core::matrix4::EM4CONST_TRANSPOSED); -} - - -//! reads a element and its content and creates a matrix from it -core::matrix4 CColladaFileLoader::readPerspectiveNode(io::IXMLReaderUTF8* reader) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading perspective node", ELL_DEBUG); - #endif - - core::matrix4 mat; - if (reader->isEmptyElement()) - return mat; - - f32 floats[1]; - readFloatsInsideElement(reader, floats, 1); - - // TODO: build perspecitve matrix from this float - - os::Printer::log("COLLADA loader warning: not implemented yet.", ELL_WARNING); - - return mat; -} - - -//! reads a element and its content and creates a matrix from it -core::matrix4 CColladaFileLoader::readRotateNode(io::IXMLReaderUTF8* reader) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading rotate node", ELL_DEBUG); - #endif - - core::matrix4 mat; - if (reader->isEmptyElement()) - return mat; - - f32 floats[4]; - readFloatsInsideElement(reader, floats, 4); - - if (!core::iszero(floats[3])) - { - core::quaternion q; - if (FlipAxis) - q.fromAngleAxis(floats[3]*core::DEGTORAD, core::vector3df(floats[0], floats[2], floats[1])); - else - q.fromAngleAxis(floats[3]*core::DEGTORAD, core::vector3df(floats[0], floats[1], floats[2])); - return q.getMatrix(); - } - else - return core::IdentityMatrix; -} - - -//! reads a element and its content and creates a matrix from it -core::matrix4 CColladaFileLoader::readScaleNode(io::IXMLReaderUTF8* reader) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading scale node", ELL_DEBUG); - #endif - - core::matrix4 mat; - if (reader->isEmptyElement()) - return mat; - - f32 floats[3]; - readFloatsInsideElement(reader, floats, 3); - - if (FlipAxis) - mat.setScale(core::vector3df(floats[0], floats[2], floats[1])); - else - mat.setScale(core::vector3df(floats[0], floats[1], floats[2])); - - return mat; -} - - -//! reads a element and its content and creates a matrix from it -core::matrix4 CColladaFileLoader::readTranslateNode(io::IXMLReaderUTF8* reader) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading translate node", ELL_DEBUG); - #endif - - core::matrix4 mat; - if (reader->isEmptyElement()) - return mat; - - f32 floats[3]; - readFloatsInsideElement(reader, floats, 3); - - if (FlipAxis) - mat.setTranslation(core::vector3df(floats[0], floats[2], floats[1])); - else - mat.setTranslation(core::vector3df(floats[0], floats[1], floats[2])); - - return mat; -} - - -//! reads any kind of node -void CColladaFileLoader::readInstanceNode(io::IXMLReaderUTF8* reader, - scene::ISceneNode* parent, scene::ISceneNode** outNode, - CScenePrefab* p, const core::stringc& type) -{ - // find prefab of the specified id - core::stringc url = reader->getAttributeValue("url"); - uriToId(url); - - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading instance", url, ELL_DEBUG); - #endif - - if (!reader->isEmptyElement()) - { - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - if (bindMaterialName == reader->getNodeName()) - readBindMaterialSection(reader,url); - else - if (extraNodeName == reader->getNodeName()) - skipSection(reader, false); - } - else - if (reader->getNodeType() == io::EXN_ELEMENT_END) - break; - } - } - instantiateNode(parent, outNode, p, url, type); -} - - -void CColladaFileLoader::instantiateNode(scene::ISceneNode* parent, - scene::ISceneNode** outNode, CScenePrefab* p, const core::stringc& url, - const core::stringc& type) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA instantiate node", ELL_DEBUG); - #endif - - for (u32 i=0; igetId()) - { - if (p) - p->Children.push_back(Prefabs[i]); - else - if (CreateInstances) - { - scene::ISceneNode * newNode - = Prefabs[i]->addInstance(parent, SceneManager); - if (outNode) - { - *outNode = newNode; - if (*outNode) - (*outNode)->setName(url); - } - } - return; - } - } - if (p) - { - if (instanceGeometryName==type) - { - Prefabs.push_back(new CGeometryPrefab(url)); - p->Children.push_back(Prefabs.getLast()); - } - } -} - - -//! reads a element and stores it as prefab -void CColladaFileLoader::readCameraPrefab(io::IXMLReaderUTF8* reader) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading camera prefab", ELL_DEBUG); - #endif - - CCameraPrefab* prefab = new CCameraPrefab(readId(reader)); - - if (!reader->isEmptyElement()) - { - // read techniques optics and imager (the latter is completely ignored, though) - readColladaParameters(reader, cameraPrefabName); - - SColladaParam* p; - - // XFOV not yet supported - p = getColladaParameter(ECPN_YFOV); - if (p && p->Type == ECPT_FLOAT) - prefab->YFov = p->Floats[0]; - - p = getColladaParameter(ECPN_ZNEAR); - if (p && p->Type == ECPT_FLOAT) - prefab->ZNear = p->Floats[0]; - - p = getColladaParameter(ECPN_ZFAR); - if (p && p->Type == ECPT_FLOAT) - prefab->ZFar = p->Floats[0]; - // orthographic camera uses LEFT, RIGHT, TOP, and BOTTOM - } - - Prefabs.push_back(prefab); -} - - -//! reads a element and stores it in the image section -void CColladaFileLoader::readImage(io::IXMLReaderUTF8* reader) -{ - // add image to list of loaded images. - Images.push_back(SColladaImage()); - SColladaImage& image=Images.getLast(); - - image.Id = readId(reader); - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading image", core::stringc(image.Id), ELL_DEBUG); - #endif - image.Dimension.Height = (u32)reader->getAttributeValueAsInt("height"); - image.Dimension.Width = (u32)reader->getAttributeValueAsInt("width"); - - if (Version >= 10400) // start with 1.4 - { - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - if (assetSectionName == reader->getNodeName()) - skipSection(reader, false); - else - if (initFromName == reader->getNodeName()) - { - reader->read(); - image.Source = reader->getNodeData(); - image.Source.trim(); - image.SourceIsFilename=true; - } - else - if (dataName == reader->getNodeName()) - { - reader->read(); - image.Source = reader->getNodeData(); - image.Source.trim(); - image.SourceIsFilename=false; - } - else - if (extraNodeName == reader->getNodeName()) - skipSection(reader, false); - } - else - if (reader->getNodeType() == io::EXN_ELEMENT_END) - { - if (initFromName == reader->getNodeName()) - return; - } - } - } - else - { - image.Source = reader->getAttributeValue("source"); - image.Source.trim(); - image.SourceIsFilename=false; - } -} - - -//! reads a element and stores it in the texture section -void CColladaFileLoader::readTexture(io::IXMLReaderUTF8* reader) -{ - // add texture to list of loaded textures. - Textures.push_back(SColladaTexture()); - SColladaTexture& texture=Textures.getLast(); - - texture.Id = readId(reader); - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading texture", core::stringc(texture.Id), ELL_DEBUG); - #endif - - if (!reader->isEmptyElement()) - { - readColladaInputs(reader, textureSectionName); - SColladaInput* input = getColladaInput(ECIS_IMAGE); - if (input) - { - const core::stringc imageName = input->Source; - texture.Texture = getTextureFromImage(imageName, NULL); - } - } -} - - -//! reads a element and stores it in the material section -void CColladaFileLoader::readMaterial(io::IXMLReaderUTF8* reader) -{ - // add material to list of loaded materials. - Materials.push_back(SColladaMaterial()); - - SColladaMaterial& material = Materials.getLast(); - material.Id = readId(reader); - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading material", core::stringc(material.Id), ELL_DEBUG); - #endif - - if (Version >= 10400) - { - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT && - instanceEffectName == reader->getNodeName()) - { - material.InstanceEffectId = reader->getAttributeValue("url"); - uriToId(material.InstanceEffectId); - } - else - if (reader->getNodeType() == io::EXN_ELEMENT_END && - materialSectionName == reader->getNodeName()) - { - break; - } - } // end while reader->read(); - } - else - { - if (!reader->isEmptyElement()) - { - readColladaInputs(reader, materialSectionName); - SColladaInput* input = getColladaInput(ECIS_TEXTURE); - if (input) - { - core::stringc textureName = input->Source; - uriToId(textureName); - for (u32 i=0; iType == ECPT_FLOAT3) - material.Mat.AmbientColor = video::SColorf(p->Floats[0],p->Floats[1],p->Floats[2]).toSColor(); - p = getColladaParameter(ECPN_DIFFUSE); - if (p && p->Type == ECPT_FLOAT3) - material.Mat.DiffuseColor = video::SColorf(p->Floats[0],p->Floats[1],p->Floats[2]).toSColor(); - p = getColladaParameter(ECPN_SPECULAR); - if (p && p->Type == ECPT_FLOAT3) - material.Mat.DiffuseColor = video::SColorf(p->Floats[0],p->Floats[1],p->Floats[2]).toSColor(); - p = getColladaParameter(ECPN_SHININESS); - if (p && p->Type == ECPT_FLOAT) - material.Mat.Shininess = p->Floats[0]; -#endif - } - } -} - -void CColladaFileLoader::readEffect(io::IXMLReaderUTF8* reader, SColladaEffect * effect) -{ - static const core::stringc constantNode("constant"); - static const core::stringc lambertNode("lambert"); - static const core::stringc phongNode("phong"); - static const core::stringc blinnNode("blinn"); - static const core::stringc emissionNode("emission"); - static const core::stringc ambientNode("ambient"); - static const core::stringc diffuseNode("diffuse"); - static const core::stringc specularNode("specular"); - static const core::stringc shininessNode("shininess"); - static const core::stringc reflectiveNode("reflective"); - static const core::stringc reflectivityNode("reflectivity"); - static const core::stringc transparentNode("transparent"); - static const core::stringc transparencyNode("transparency"); - static const core::stringc indexOfRefractionNode("index_of_refraction"); - - if (!effect) - { - Effects.push_back(SColladaEffect()); - effect = &Effects.getLast(); - effect->Parameters = new io::CAttributes(); - effect->Id = readId(reader); - effect->Transparency = 1.f; - effect->Mat.Lighting=true; - effect->Mat.NormalizeNormals=true; - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading effect", core::stringc(effect->Id), ELL_DEBUG); - #endif - } - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - // first come the tags we descend, but ignore the top-levels - if (!reader->isEmptyElement() && ((profileCOMMONSectionName == reader->getNodeName()) || - (techniqueNodeName == reader->getNodeName()))) - readEffect(reader,effect); - else - if (newParamName == reader->getNodeName()) - readParameter(reader, effect->Parameters); - else - // these are the actual materials inside technique - if (constantNode == reader->getNodeName() || - lambertNode == reader->getNodeName() || - phongNode == reader->getNodeName() || - blinnNode == reader->getNodeName()) - { - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading effect part", reader->getNodeName(), ELL_DEBUG); - #endif - effect->Mat.setFlag(irr::video::EMF_GOURAUD_SHADING, - phongNode == reader->getNodeName() || - blinnNode == reader->getNodeName()); - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - const core::stringc node = reader->getNodeName(); - if (emissionNode == node || ambientNode == node || - diffuseNode == node || specularNode == node || - reflectiveNode == node || transparentNode == node ) - { - // color or texture types - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT && - colorNodeName == reader->getNodeName()) - { - const video::SColorf colorf = readColorNode(reader); - const video::SColor color = colorf.toSColor(); - if (emissionNode == node) - effect->Mat.EmissiveColor = color; - else - if (ambientNode == node) - effect->Mat.AmbientColor = color; - else - if (diffuseNode == node) - effect->Mat.DiffuseColor = color; - else - if (specularNode == node) - effect->Mat.SpecularColor = color; - else - if (transparentNode == node) - effect->Transparency = colorf.getAlpha(); - } - else - if (reader->getNodeType() == io::EXN_ELEMENT && - textureNodeName == reader->getNodeName()) - { - effect->Textures.push_back(reader->getAttributeValue("texture")); - break; - } - else - if (reader->getNodeType() == io::EXN_ELEMENT) - skipSection(reader, false); - else - if (reader->getNodeType() == io::EXN_ELEMENT_END && - node == reader->getNodeName()) - break; - } - } - else - if (shininessNode == node || reflectivityNode == node || - transparencyNode == node || indexOfRefractionNode == node ) - { - // float or param types - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT && - floatNodeName == reader->getNodeName()) - { - f32 f = readFloatNode(reader); - if (shininessNode == node) - effect->Mat.Shininess = f; - else - if (transparencyNode == node) - effect->Transparency *= f; - } - else - if (reader->getNodeType() == io::EXN_ELEMENT) - skipSection(reader, false); - else - if (reader->getNodeType() == io::EXN_ELEMENT_END && - node == reader->getNodeName()) - break; - } - } - else - skipSection(reader, true); // ignore all other nodes - } - else - if (reader->getNodeType() == io::EXN_ELEMENT_END && ( - constantNode == reader->getNodeName() || - lambertNode == reader->getNodeName() || - phongNode == reader->getNodeName() || - blinnNode == reader->getNodeName() - )) - break; - } - } - else - if (!reader->isEmptyElement() && (extraNodeName == reader->getNodeName())) - readEffect(reader,effect); - else - if (doubleSidedNodeName == reader->getNodeName()) - { - // read the GoogleEarth extra flag for double sided polys - s32 doubleSided = 0; - readIntsInsideElement(reader,&doubleSided,1); - if (doubleSided) - { - #ifdef COLLADA_READER_DEBUG - os::Printer::log("Setting double sided flag for effect.", ELL_DEBUG); - #endif - - effect->Mat.setFlag(irr::video::EMF_BACK_FACE_CULLING,false); - } - } - else - skipSection(reader, true); // ignore all other sections - } - else - if (reader->getNodeType() == io::EXN_ELEMENT_END) - { - if (effectSectionName == reader->getNodeName()) - break; - else - if (profileCOMMONSectionName == reader->getNodeName()) - break; - else - if (techniqueNodeName == reader->getNodeName()) - break; - else - if (extraNodeName == reader->getNodeName()) - break; - } - } - - if (effect->Mat.AmbientColor == video::SColor(0) && - effect->Mat.DiffuseColor != video::SColor(0)) - effect->Mat.AmbientColor = effect->Mat.DiffuseColor; - if (effect->Mat.DiffuseColor == video::SColor(0) && - effect->Mat.AmbientColor != video::SColor(0)) - effect->Mat.DiffuseColor = effect->Mat.AmbientColor; - if ((effect->Transparency != 0.0f) && (effect->Transparency != 1.0f)) - { - effect->Mat.MaterialType = irr::video::EMT_TRANSPARENT_VERTEX_ALPHA; - effect->Mat.ZWriteEnable = false; - } - - video::E_TEXTURE_CLAMP twu = video::ETC_REPEAT; - s32 idx = effect->Parameters->findAttribute(wrapsName.c_str()); - if ( idx >= 0 ) - twu = (video::E_TEXTURE_CLAMP)(effect->Parameters->getAttributeAsInt(idx)); - video::E_TEXTURE_CLAMP twv = video::ETC_REPEAT; - idx = effect->Parameters->findAttribute(wraptName.c_str()); - if ( idx >= 0 ) - twv = (video::E_TEXTURE_CLAMP)(effect->Parameters->getAttributeAsInt(idx)); - - for (u32 i=0; iMat.TextureLayer[i].TextureWrapU = twu; - effect->Mat.TextureLayer[i].TextureWrapV = twv; - } - - effect->Mat.setFlag(video::EMF_BILINEAR_FILTER, effect->Parameters->getAttributeAsBool("bilinear")); - effect->Mat.setFlag(video::EMF_TRILINEAR_FILTER, effect->Parameters->getAttributeAsBool("trilinear")); - effect->Mat.setFlag(video::EMF_ANISOTROPIC_FILTER, effect->Parameters->getAttributeAsBool("anisotropic")); -} - - -const SColladaMaterial* CColladaFileLoader::findMaterial(const core::stringc& materialName) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA find material", materialName, ELL_DEBUG); - #endif - - // do a quick lookup in the materials - SColladaMaterial matToFind; - matToFind.Id = materialName; - s32 mat = Materials.binary_search(matToFind); - if (mat == -1) - return 0; - // instantiate the material effect if needed - if (Materials[mat].InstanceEffectId.size() != 0) - { - // do a quick lookup in the effects - SColladaEffect effectToFind; - effectToFind.Id = Materials[mat].InstanceEffectId; - s32 effect = Effects.binary_search(effectToFind); - if (effect != -1) - { - // found the effect, instantiate by copying into the material - Materials[mat].Mat = Effects[effect].Mat; - if (Effects[effect].Textures.size()) - Materials[mat].Mat.setTexture(0, getTextureFromImage(Effects[effect].Textures[0], &(Effects[effect]))); - Materials[mat].Transparency = Effects[effect].Transparency; - // and indicate the material is instantiated by removing the effect ref - Materials[mat].InstanceEffectId = ""; - } - else - return 0; - } - return &Materials[mat]; -} - - -void CColladaFileLoader::readBindMaterialSection(io::IXMLReaderUTF8* reader, const core::stringc & id) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading bind material", ELL_DEBUG); - #endif - - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - if (instanceMaterialName == reader->getNodeName()) - { - // the symbol to retarget, and the target material - core::stringc meshbufferReference = reader->getAttributeValue("symbol"); - if (meshbufferReference.size()==0) - continue; - core::stringc target = reader->getAttributeValue("target"); - uriToId(target); - if (target.size()==0) - continue; - const SColladaMaterial * material = findMaterial(target); - if (!material) - continue; - // bind any pending materials for this node - meshbufferReference = id+"/"+meshbufferReference; -#ifdef COLLADA_READER_DEBUG - os::Printer::log((core::stringc("Material binding: ")+meshbufferReference+" "+target).c_str(), ELL_DEBUG); -#endif - if (MaterialsToBind.find(meshbufferReference)) - { - core::array & toBind - = MeshesToBind[MaterialsToBind[meshbufferReference]]; -#ifdef COLLADA_READER_DEBUG - os::Printer::log("Material binding now ",material->Id.c_str(), ELL_DEBUG); - os::Printer::log("#meshbuffers",core::stringc(toBind.size()).c_str(), ELL_DEBUG); -#endif - SMesh tmpmesh; - for (u32 i = 0; i < toBind.size(); ++i) - { - toBind[i]->getMaterial() = material->Mat; - tmpmesh.addMeshBuffer(toBind[i]); - - if ((material->Transparency!=0.0f) && (material->Transparency!=1.0f)) - { - toBind[i]->getMaterial().MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; - toBind[i]->getMaterial().ZWriteEnable = false; - } - } - SceneManager->getMeshManipulator()->setVertexColors(&tmpmesh,material->Mat.DiffuseColor); - if ((material->Transparency!=0.0f) && (material->Transparency!=1.0f)) - { - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA found transparency material", core::stringc(material->Transparency).c_str(), ELL_DEBUG); - #endif - SceneManager->getMeshManipulator()->setVertexColorAlpha(&tmpmesh, core::floor32(material->Transparency*255.0f)); - } - } - } - } - else - if (reader->getNodeType() == io::EXN_ELEMENT_END && - bindMaterialName == reader->getNodeName()) - break; - } -} - - -//! reads a element and stores it as mesh if possible -void CColladaFileLoader::readGeometry(io::IXMLReaderUTF8* reader) -{ - core::stringc id = readId(reader); - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading geometry", id, ELL_DEBUG); - #endif - - SAnimatedMesh* amesh = new SAnimatedMesh(); - scene::SMesh* mesh = new SMesh(); - amesh->addMesh(mesh); - core::array sources; - bool okToReadArray = false; - - // handles geometry node and the mesh children in this loop - // read sources with arrays and accessor for each mesh - if (!reader->isEmptyElement()) - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - const char* nodeName = reader->getNodeName(); - if (meshSectionName == nodeName) - { - // inside a mesh section. Don't have to do anything here. - } - else - if (sourceSectionName == nodeName) - { - // create a new source - sources.push_back(SSource()); - sources.getLast().Id = readId(reader); - - #ifdef COLLADA_READER_DEBUG - os::Printer::log("Reading source", sources.getLast().Id.c_str(), ELL_DEBUG); - #endif - } - else - if (arraySectionName == nodeName || floatArraySectionName == nodeName || intArraySectionName == nodeName) - { - // create a new array and read it. - if (!sources.empty()) - { - sources.getLast().Array.Name = readId(reader); - - int count = reader->getAttributeValueAsInt("count"); - sources.getLast().Array.Data.set_used(count); // pre allocate - - // check if type of array is ok - const char* type = reader->getAttributeValue("type"); - okToReadArray = (type && (!strcmp("float", type) || !strcmp("int", type))) || floatArraySectionName == nodeName || intArraySectionName == nodeName; - - #ifdef COLLADA_READER_DEBUG - os::Printer::log("Read array", sources.getLast().Array.Name.c_str(), ELL_DEBUG); - #endif - } - #ifdef COLLADA_READER_DEBUG - else - os::Printer::log("Warning, array outside source found", - readId(reader).c_str(), ELL_DEBUG); - #endif - - } - else - if (accessorSectionName == nodeName) // child of source (below a technique tag) - { - #ifdef COLLADA_READER_DEBUG - os::Printer::log("Reading accessor", ELL_DEBUG); - #endif - SAccessor accessor; - accessor.Count = reader->getAttributeValueAsInt("count"); - accessor.Offset = reader->getAttributeValueAsInt("offset"); - accessor.Stride = reader->getAttributeValueAsInt("stride"); - if (accessor.Stride == 0) - accessor.Stride = 1; - - // the accessor contains some information on how to access (boi!) the array, - // the info is stored in collada style parameters, so just read them. - readColladaParameters(reader, accessorSectionName); - if (!sources.empty()) - { - sources.getLast().Accessors.push_back(accessor); - sources.getLast().Accessors.getLast().Parameters = ColladaParameters; - } - } - else - if (verticesSectionName == nodeName) - { - #ifdef COLLADA_READER_DEBUG - os::Printer::log("Reading vertices", ELL_DEBUG); - #endif - // read vertex input position source - readColladaInputs(reader, verticesSectionName); - } - else - // lines and linestrips missing - if (polygonsSectionName == nodeName || - polylistSectionName == nodeName || - trianglesSectionName == nodeName) - { - // read polygons section - readPolygonSection(reader, sources, mesh, id); - } - else - // trifans, and tristrips missing - if (doubleSidedNodeName == reader->getNodeName()) - { - // read the extra flag for double sided polys - s32 doubleSided = 0; - readIntsInsideElement(reader,&doubleSided,1); - if (doubleSided) - { - #ifdef COLLADA_READER_DEBUG - os::Printer::log("Setting double sided flag for mesh.", ELL_DEBUG); - #endif - amesh->setMaterialFlag(irr::video::EMF_BACK_FACE_CULLING,false); - } - } - else - // techniqueCommon or 'technique profile=common' must not be skipped - if ((techniqueCommonSectionName != nodeName) // Collada 1.2/1.3 - && (techniqueNodeName != nodeName) // Collada 1.4+ - && (extraNodeName != nodeName)) - { - os::Printer::log("COLLADA loader warning: Wrong tag usage found in geometry", reader->getNodeName(), ELL_WARNING); - skipSection(reader, true); // ignore all other sections - } - } // end if node type is element - else - if (reader->getNodeType() == io::EXN_TEXT) - { - // read array data - if (okToReadArray && !sources.empty()) - { - core::array& a = sources.getLast().Array.Data; - core::stringc data = reader->getNodeData(); - data.trim(); - const c8* p = &data[0]; - - for (u32 i=0; igetNodeType() == io::EXN_ELEMENT_END) - { - if (geometrySectionName == reader->getNodeName()) - { - // end of geometry section reached, cancel out - break; - } - } - } // end while reader->read(); - - // add mesh as geometry - - mesh->recalculateBoundingBox(); - amesh->recalculateBoundingBox(); - - // create virtual file name - io::path filename = CurrentlyLoadingMesh; - filename += '#'; - filename += id; - - // add to scene manager - if (LoadedMeshCount) - { - SceneManager->getMeshCache()->addMesh(filename.c_str(), amesh); - os::Printer::log("Added COLLADA mesh", filename.c_str(), ELL_DEBUG); - } - else - { - FirstLoadedMeshName = filename; - FirstLoadedMesh = amesh; - FirstLoadedMesh->grab(); - } - - ++LoadedMeshCount; - mesh->drop(); - amesh->drop(); - - // create geometry prefab - u32 i; - for (i=0; igetId()==id) - { - ((CGeometryPrefab*)Prefabs[i])->Mesh=mesh; - break; - } - } - if (i==Prefabs.size()) - { - CGeometryPrefab* prefab = new CGeometryPrefab(id); - prefab->Mesh = mesh; - Prefabs.push_back(prefab); - } - - // store as dummy mesh if no instances will be created - if (!CreateInstances && !DummyMesh) - { - DummyMesh = amesh; - DummyMesh->grab(); - } -} - - -struct SPolygon -{ - core::array Indices; -}; - -//! reads a polygons section and creates a mesh from it -void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader, - core::array& sources, scene::SMesh* mesh, - const core::stringc& geometryId) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading polygon section", ELL_DEBUG); - #endif - - core::stringc materialName = reader->getAttributeValue("material"); - - core::stringc polygonType = reader->getNodeName(); - const int polygonCount = reader->getAttributeValueAsInt("count"); // Not useful because it only determines the number of primitives, which have arbitrary vertices in case of polygon - core::array polygons; - if (polygonType == polygonsSectionName) - polygons.reallocate(polygonCount); - core::array vCounts; - bool parsePolygonOK = false; - bool parseVcountOK = false; - u32 inputSemanticCount = 0; - bool unresolvedInput=false; - u32 maxOffset = 0; - core::array localInputs; - - // read all and primitives - if (!reader->isEmptyElement()) - while(reader->read()) - { - const char* nodeName = reader->getNodeName(); - - if (reader->getNodeType() == io::EXN_ELEMENT) - { - // polygon node may contain params - if (inputTagName == nodeName) - { - // read input tag - readColladaInput(reader, localInputs); - - // resolve input source - SColladaInput& inp = localInputs.getLast(); - - // get input source array id, if it is a vertex input, take - // the -source attribute. - if (inp.Semantic == ECIS_VERTEX) - { - inp.Source = Inputs[0].Source; - for (u32 i=1; igetNodeType() == io::EXN_ELEMENT_END) - { - if (primitivesName == nodeName) - parsePolygonOK = false; // end parsing a polygon - else - if (vcountName == nodeName) - parseVcountOK = false; // end parsing vcounts - else - if (polygonType == nodeName) - break; // cancel out and create mesh - - } // end is element end - else - if (reader->getNodeType() == io::EXN_TEXT) - { - if (parseVcountOK) - { - core::stringc data = reader->getNodeData(); - data.trim(); - const c8* p = &data[0]; - while(*p) - { - findNextNoneWhiteSpace(&p); - if (*p) - vCounts.push_back(readInt(&p)); - } - parseVcountOK = false; - } - else - if (parsePolygonOK && polygons.size()) - { - core::stringc data = reader->getNodeData(); - data.trim(); - const c8* p = &data[0]; - SPolygon& poly = polygons.getLast(); - if (polygonType == polygonsSectionName) - poly.Indices.reallocate((maxOffset+1)*3); - else - poly.Indices.reallocate(polygonCount*(maxOffset+1)*3); - - if (vCounts.empty()) - { - while(*p) - { - findNextNoneWhiteSpace(&p); - poly.Indices.push_back(readInt(&p)); - } - } - else - { - for (u32 i = 0; i < vCounts.size(); i++) - { - const int polyVCount = vCounts[i]; - core::array polyCorners; - - for (u32 j = 0; j < polyVCount * inputSemanticCount; j++) - { - if (!*p) - break; - findNextNoneWhiteSpace(&p); - polyCorners.push_back(readInt(&p)); - } - - while (polyCorners.size() >= 3 * inputSemanticCount) - { - // add one triangle's worth of indices - for (u32 k = 0; k < inputSemanticCount * 3; ++k) - { - poly.Indices.push_back(polyCorners[k]); - } - - // remove one corner from our poly - polyCorners.erase(inputSemanticCount,inputSemanticCount); - } - polyCorners.clear(); - } - vCounts.clear(); - } - parsePolygonOK = false; - } - } - } // end while reader->read() - - // find source array (we'll ignore accessors for this implementation) - for (u32 i=0; i vertMap; - - for (u32 i=0; i indices; - const u32 vertexCount = polygons[i].Indices.size() / maxOffset; - mbuffer->Vertices.reallocate(mbuffer->Vertices.size()+vertexCount); - - // for all index/semantic groups - for (u32 v=0; v::Node* n = vertMap.find(vtx); - if (n) - { - indices.push_back(n->getValue()); - } - else - { - indices.push_back(mbuffer->getVertexCount()); - mbuffer->Vertices.push_back(vtx); - vertMap.insert(vtx, mbuffer->getVertexCount()-1); - } - } // end for all vertices - - if (polygonsSectionName == polygonType && - indices.size() > 3) - { - // need to tesselate for polygons of 4 or more vertices - // for now we naively turn interpret it as a triangle fan - // as full tesselation is problematic - if (FlipAxis) - { - for (u32 ind = indices.size()-3; ind>0 ; --ind) - { - mbuffer->Indices.push_back(indices[0]); - mbuffer->Indices.push_back(indices[ind+2]); - mbuffer->Indices.push_back(indices[ind+1]); - } - } - else - { - for (u32 ind = 0; ind+2 < indices.size(); ++ind) - { - mbuffer->Indices.push_back(indices[0]); - mbuffer->Indices.push_back(indices[ind+1]); - mbuffer->Indices.push_back(indices[ind+2]); - } - } - } - else - { - // it's just triangles - for (u32 ind = 0; ind < indices.size(); ind+=3) - { - if (FlipAxis) - { - mbuffer->Indices.push_back(indices[ind+2]); - mbuffer->Indices.push_back(indices[ind+1]); - mbuffer->Indices.push_back(indices[ind+0]); - } - else - { - mbuffer->Indices.push_back(indices[ind+0]); - mbuffer->Indices.push_back(indices[ind+1]); - mbuffer->Indices.push_back(indices[ind+2]); - } - } - } - - } // end for all polygons - } - else - { - // lightmap mesh buffer - - scene::SMeshBufferLightMap* mbuffer = new SMeshBufferLightMap(); - buffer = mbuffer; - - for (u32 i=0; iVertices.reallocate(mbuffer->Vertices.size()+vertexCount); - // for all vertices in array - for (u32 v=0; vVertices.push_back(vtx); - - } // end for all vertices - - // add vertex indices - const u32 oldVertexCount = mbuffer->Vertices.size() - vertexCount; - for (u32 face=0; faceIndices.push_back(oldVertexCount + 0); - mbuffer->Indices.push_back(oldVertexCount + 1 + face); - mbuffer->Indices.push_back(oldVertexCount + 2 + face); - } - - } // end for all polygons - } - - const SColladaMaterial* m = findMaterial(materialName); - if (m) - { - buffer->getMaterial() = m->Mat; - SMesh tmpmesh; - tmpmesh.addMeshBuffer(buffer); - SceneManager->getMeshManipulator()->setVertexColors(&tmpmesh,m->Mat.DiffuseColor); - if (m->Transparency != 1.0f) - SceneManager->getMeshManipulator()->setVertexColorAlpha(&tmpmesh,core::floor32(m->Transparency*255.0f)); - } - // add future bind reference for the material - core::stringc meshbufferReference = geometryId+"/"+materialName; - if (!MaterialsToBind.find(meshbufferReference)) - { - MaterialsToBind[meshbufferReference] = MeshesToBind.size(); - MeshesToBind.push_back(core::array()); - } - MeshesToBind[MaterialsToBind[meshbufferReference]].push_back(buffer); - - // calculate normals if there is no slot for it - - if (!normalSlotCount) - SceneManager->getMeshManipulator()->recalculateNormals(buffer, true); - - // recalculate bounding box - buffer->recalculateBoundingBox(); - - // add mesh buffer - mesh->addMeshBuffer(buffer); - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA added meshbuffer", core::stringc(buffer->getVertexCount())+" vertices, "+core::stringc(buffer->getIndexCount())+" indices.", ELL_DEBUG); - #endif - - buffer->drop(); -} - - -//! reads a element and stores it as prefab -void CColladaFileLoader::readLightPrefab(io::IXMLReaderUTF8* reader) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading light prefab", ELL_DEBUG); - #endif - - CLightPrefab* prefab = new CLightPrefab(readId(reader)); - - if (!reader->isEmptyElement()) - { - if (Version >= 10400) // start with 1.4 - { - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - if (pointSectionName == reader->getNodeName()) - prefab->LightData.Type=video::ELT_POINT; - else - if (directionalSectionName == reader->getNodeName()) - prefab->LightData.Type=video::ELT_DIRECTIONAL; - else - if (spotSectionName == reader->getNodeName()) - prefab->LightData.Type=video::ELT_SPOT; - else - if (ambientSectionName == reader->getNodeName()) - prefab->LightData.Type=ELT_AMBIENT; - else - if (colorNodeName == reader->getNodeName()) - prefab->LightData.DiffuseColor=readColorNode(reader); - else - if (constantAttenuationNodeName == reader->getNodeName()) - readFloatsInsideElement(reader,&prefab->LightData.Attenuation.X,1); - else - if (linearAttenuationNodeName == reader->getNodeName()) - readFloatsInsideElement(reader,&prefab->LightData.Attenuation.Y,1); - else - if (quadraticAttenuationNodeName == reader->getNodeName()) - readFloatsInsideElement(reader,&prefab->LightData.Attenuation.Z,1); - else - if (falloffAngleNodeName == reader->getNodeName()) - { - readFloatsInsideElement(reader,&prefab->LightData.OuterCone,1); - prefab->LightData.OuterCone *= core::DEGTORAD; - } - else - if (falloffExponentNodeName == reader->getNodeName()) - readFloatsInsideElement(reader,&prefab->LightData.Falloff,1); - } - else - if (reader->getNodeType() == io::EXN_ELEMENT_END) - { - if ((pointSectionName == reader->getNodeName()) || - (directionalSectionName == reader->getNodeName()) || - (spotSectionName == reader->getNodeName()) || - (ambientSectionName == reader->getNodeName())) - break; - } - } - } - else - { - readColladaParameters(reader, lightPrefabName); - - SColladaParam* p = getColladaParameter(ECPN_COLOR); - if (p && p->Type == ECPT_FLOAT3) - prefab->LightData.DiffuseColor.set(p->Floats[0], p->Floats[1], p->Floats[2]); - } - } - - Prefabs.push_back(prefab); -} - - -//! returns a collada parameter or none if not found -SColladaParam* CColladaFileLoader::getColladaParameter(ECOLLADA_PARAM_NAME name) -{ - for (u32 i=0; i& inputs) -{ - // parse param - SColladaInput p; - - // get type - core::stringc semanticName = reader->getAttributeValue("semantic"); - for (u32 i=0; inputSemanticNames[i]; ++i) - { - if (semanticName == inputSemanticNames[i]) - { - p.Semantic = (ECOLLADA_INPUT_SEMANTIC)i; - break; - } - } - - // get source - p.Source = reader->getAttributeValue("source"); - if (reader->getAttributeValue("offset")) // Collada 1.4+ - p.Offset = (u32)reader->getAttributeValueAsInt("offset"); - else // Collada 1.2/1.3 - p.Offset = (u32)reader->getAttributeValueAsInt("idx"); - p.Set = (u32)reader->getAttributeValueAsInt("set"); - - // add input - inputs.push_back(p); -} - -//! parses all collada inputs inside an element and stores them in Inputs -void CColladaFileLoader::readColladaInputs(io::IXMLReaderUTF8* reader, const core::stringc& parentName) -{ - Inputs.clear(); - - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT && - inputTagName == reader->getNodeName()) - { - readColladaInput(reader, Inputs); - } - else - if (reader->getNodeType() == io::EXN_ELEMENT_END) - { - if (parentName == reader->getNodeName()) - return; // end of parent reached - } - - } // end while reader->read(); -} - -//! parses all collada parameters inside an element and stores them in ColladaParameters -void CColladaFileLoader::readColladaParameters(io::IXMLReaderUTF8* reader, - const core::stringc& parentName) -{ - ColladaParameters.clear(); - - const char* const paramNames[] = {"COLOR", "AMBIENT", "DIFFUSE", - "SPECULAR", "SHININESS", "YFOV", "ZNEAR", "ZFAR", 0}; - - const char* const typeNames[] = {"float", "float2", "float3", 0}; - - while(reader->read()) - { - const char* nodeName = reader->getNodeName(); - if (reader->getNodeType() == io::EXN_ELEMENT && - paramTagName == nodeName) - { - // parse param - SColladaParam p; - - // get type - u32 i; - core::stringc typeName = reader->getAttributeValue("type"); - for (i=0; typeNames[i]; ++i) - if (typeName == typeNames[i]) - { - p.Type = (ECOLLADA_PARAM_TYPE)i; - break; - } - - // get name - core::stringc nameName = reader->getAttributeValue("name"); - for (i=0; typeNames[i]; ++i) - if (nameName == paramNames[i]) - { - p.Name = (ECOLLADA_PARAM_NAME)i; - break; - } - - // read parameter data inside parameter tags - switch(p.Type) - { - case ECPT_FLOAT: - case ECPT_FLOAT2: - case ECPT_FLOAT3: - case ECPT_FLOAT4: - readFloatsInsideElement(reader, p.Floats, p.Type - ECPT_FLOAT + 1); - break; - - // TODO: other types of data (ints, bools or whatever) - default: - break; - } - - // add param - ColladaParameters.push_back(p); - } - else - if (reader->getNodeType() == io::EXN_ELEMENT_END) - { - if (parentName == reader->getNodeName()) - return; // end of parent reached - } - - } // end while reader->read(); -} - - -//! parses a float from a char pointer and moves the pointer -//! to the end of the parsed float -inline f32 CColladaFileLoader::readFloat(const c8** p) -{ - f32 ftmp; - *p = core::fast_atof_move(*p, ftmp); - return ftmp; -} - - -//! parses an int from a char pointer and moves the pointer to -//! the end of the parsed float -inline s32 CColladaFileLoader::readInt(const c8** p) -{ - return (s32)readFloat(p); -} - - -//! places pointer to next begin of a token -void CColladaFileLoader::findNextNoneWhiteSpace(const c8** start) -{ - const c8* p = *start; - - while(*p && (*p==' ' || *p=='\n' || *p=='\r' || *p=='\t')) - ++p; - - // TODO: skip comments - - *start = p; -} - - -//! reads floats from inside of xml element until end of xml element -void CColladaFileLoader::readFloatsInsideElement(io::IXMLReaderUTF8* reader, f32* floats, u32 count) -{ - if (reader->isEmptyElement()) - return; - - while(reader->read()) - { - // TODO: check for comments inside the element - // and ignore them. - - if (reader->getNodeType() == io::EXN_TEXT) - { - // parse float data - core::stringc data = reader->getNodeData(); - data.trim(); - const c8* p = &data[0]; - - for (u32 i=0; igetNodeType() == io::EXN_ELEMENT_END) - break; // end parsing text - } -} - - -//! reads ints from inside of xml element until end of xml element -void CColladaFileLoader::readIntsInsideElement(io::IXMLReaderUTF8* reader, s32* ints, u32 count) -{ - if (reader->isEmptyElement()) - return; - - while(reader->read()) - { - // TODO: check for comments inside the element - // and ignore them. - - if (reader->getNodeType() == io::EXN_TEXT) - { - // parse float data - core::stringc data = reader->getNodeData(); - data.trim(); - const c8* p = &data[0]; - - for (u32 i=0; igetNodeType() == io::EXN_ELEMENT_END) - break; // end parsing text - } -} - - -video::SColorf CColladaFileLoader::readColorNode(io::IXMLReaderUTF8* reader) -{ - if (reader->getNodeType() == io::EXN_ELEMENT && - colorNodeName == reader->getNodeName()) - { - f32 color[4]; - readFloatsInsideElement(reader,color,4); - return video::SColorf(color[0], color[1], color[2], color[3]); - } - - return video::SColorf(); -} - - -f32 CColladaFileLoader::readFloatNode(io::IXMLReaderUTF8* reader) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading ", ELL_DEBUG); - #endif - - f32 result = 0.0f; - if (reader->getNodeType() == io::EXN_ELEMENT && - floatNodeName == reader->getNodeName()) - { - readFloatsInsideElement(reader,&result,1); - } - - return result; -} - - -//! clears all loaded data -void CColladaFileLoader::clearData() -{ - // delete all prefabs - - for (u32 i=0; idrop(); - - Prefabs.clear(); - - // clear all parameters - ColladaParameters.clear(); - - // clear all materials - Images.clear(); - - // clear all materials - Textures.clear(); - - // clear all materials - Materials.clear(); - - // clear all inputs - Inputs.clear(); - - // clear all effects - for ( u32 i=0; idrop(); - Effects.clear(); - - // clear all the materials to bind - MaterialsToBind.clear(); - MeshesToBind.clear(); -} - - -//! changes the XML URI into an internal id -void CColladaFileLoader::uriToId(core::stringc& str) -{ - // currently, we only remove the # from the begin if there - // because we simply don't support referencing other files. - if (!str.size()) - return; - - if (str[0] == '#') - str.erase(0); -} - - -//! read Collada Id, uses id or name if id is missing -core::stringc CColladaFileLoader::readId(io::IXMLReaderUTF8* reader) -{ - core::stringc id = reader->getAttributeValue("id"); - if (id.size()==0) - id = reader->getAttributeValue("name"); - return id; -} - - -//! create an Irrlicht texture from the reference -video::ITexture* CColladaFileLoader::getTextureFromImage(core::stringc uri, SColladaEffect * effect) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA searching texture", uri, ELL_DEBUG); - #endif - video::IVideoDriver* driver = SceneManager->getVideoDriver(); - for (;;) - { - uriToId(uri); - for (u32 i=0; iexistFile(Images[i].Source)) - return driver->getTexture(Images[i].Source); - return driver->getTexture((FileSystem->getFileDir(CurrentlyLoadingMesh)+"/"+Images[i].Source)); - } - else - if (Images[i].Source.size()) - { - //const u32 size = Images[i].Dimension.getArea(); - const u32 size = Images[i].Dimension.Width * Images[i].Dimension.Height;; - u32* data = new u32[size]; // we assume RGBA - u32* ptrdest = data; - const c8* ptrsrc = Images[i].Source.c_str(); - for (u32 j=0; jcreateImageFromData(video::ECF_A8R8G8B8, Images[i].Dimension, data, true, true); - video::ITexture* tex = driver->addTexture((CurrentlyLoadingMesh+"#"+Images[i].Id).c_str(), img); - img->drop(); - return tex; - } - break; - } - } - if (effect && effect->Parameters->getAttributeType(uri.c_str())==io::EAT_STRING) - { - uri = effect->Parameters->getAttributeAsString(uri.c_str()); -#ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA now searching texture", uri.c_str(), ELL_DEBUG); -#endif - } - else - break; - } - return 0; -} - - -//! read a parameter and value -void CColladaFileLoader::readParameter(io::IXMLReaderUTF8* reader, io::IAttributes* parameters) -{ - #ifdef COLLADA_READER_DEBUG - os::Printer::log("COLLADA reading parameter", ELL_DEBUG); - #endif - - if ( !parameters ) - return; - - const core::stringc name = reader->getAttributeValue("sid"); - if (!reader->isEmptyElement()) - { - while(reader->read()) - { - if (reader->getNodeType() == io::EXN_ELEMENT) - { - if (floatNodeName == reader->getNodeName()) - { - const f32 f = readFloatNode(reader); - parameters->addFloat(name.c_str(), f); - } - else - if (float2NodeName == reader->getNodeName()) - { - f32 f[2]; - readFloatsInsideElement(reader, f, 2); -// Parameters.addVector2d(name.c_str(), core::vector2df(f[0],f[1])); - } - else - if (float3NodeName == reader->getNodeName()) - { - f32 f[3]; - readFloatsInsideElement(reader, f, 3); - parameters->addVector3d(name.c_str(), core::vector3df(f[0],f[1],f[2])); - } - else - if ((initFromName == reader->getNodeName()) || - (sourceSectionName == reader->getNodeName())) - { - reader->read(); - parameters->addString(name.c_str(), reader->getNodeData()); - } - else - if (wrapsName == reader->getNodeName()) - { - reader->read(); - const core::stringc val = reader->getNodeData(); - if (val == "WRAP") - parameters->addInt(wrapsName.c_str(), (int)video::ETC_REPEAT); - else if ( val== "MIRROR") - parameters->addInt(wrapsName.c_str(), (int)video::ETC_MIRROR); - else if ( val== "CLAMP") - parameters->addInt(wrapsName.c_str(), (int)video::ETC_CLAMP_TO_EDGE); - else if ( val== "BORDER") - parameters->addInt(wrapsName.c_str(), (int)video::ETC_CLAMP_TO_BORDER); - else if ( val== "NONE") - parameters->addInt(wrapsName.c_str(), (int)video::ETC_CLAMP_TO_BORDER); - } - else - if (wraptName == reader->getNodeName()) - { - reader->read(); - const core::stringc val = reader->getNodeData(); - if (val == "WRAP") - parameters->addInt(wraptName.c_str(), (int)video::ETC_REPEAT); - else if ( val== "MIRROR") - parameters->addInt(wraptName.c_str(), (int)video::ETC_MIRROR); - else if ( val== "CLAMP") - parameters->addInt(wraptName.c_str(), (int)video::ETC_CLAMP_TO_EDGE); - else if ( val== "BORDER") - parameters->addInt(wraptName.c_str(), (int)video::ETC_CLAMP_TO_BORDER); - else if ( val== "NONE") - parameters->addInt(wraptName.c_str(), (int)video::ETC_CLAMP_TO_BORDER); - } - else - if (minfilterName == reader->getNodeName()) - { - reader->read(); - const core::stringc val = reader->getNodeData(); - if (val == "LINEAR_MIPMAP_LINEAR") - parameters->addBool("trilinear", true); - else - if (val == "LINEAR_MIPMAP_NEAREST") - parameters->addBool("bilinear", true); - } - else - if (magfilterName == reader->getNodeName()) - { - reader->read(); - const core::stringc val = reader->getNodeData(); - if (val != "LINEAR") - { - parameters->addBool("bilinear", false); - parameters->addBool("trilinear", false); - } - } - else - if (mipfilterName == reader->getNodeName()) - { - parameters->addBool("anisotropic", true); - } - } - else - if(reader->getNodeType() == io::EXN_ELEMENT_END) - { - if (newParamName == reader->getNodeName()) - break; - } - } - } -} - - -} // end namespace scene -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_COLLADA_LOADER_ - -- cgit v1.1