/// \file X3DImporter.hpp /// \brief X3D-format files importer for Assimp. /// \date 2015-2016 /// \author smal.root@gmail.com // Thanks to acorn89 for support. #ifndef INCLUDED_AI_X3D_IMPORTER_H #define INCLUDED_AI_X3D_IMPORTER_H #include "X3DImporter_Node.hpp" // Header files, Assimp. #include "assimp/DefaultLogger.hpp" #include "assimp/importerdesc.h" #include "assimp/ProgressHandler.hpp" #include "assimp/types.h" #include "BaseImporter.h" #include "irrXMLWrapper.h" namespace Assimp { /// \class X3DImporter /// Class that holding scene graph which include: groups, geometry, metadata etc. /// /// Limitations. /// /// Pay attention that X3D is format for interactive graphic and simulations for web browsers. /// So not all features can be imported using Assimp. /// /// Unsupported nodes: /// CAD geometry component: /// "CADAssembly", "CADFace", "CADLayer", "CADPart", "IndexedQuadSet", "QuadSet" /// Core component: /// "ROUTE", "ExternProtoDeclare", "ProtoDeclare", "ProtoInstance", "ProtoInterface", "WorldInfo" /// Distributed interactive simulation (DIS) component: /// "DISEntityManager", "DISEntityTypeMapping", "EspduTransform", "ReceiverPdu", "SignalPdu", "TransmitterPdu" /// Cube map environmental texturing component: /// "ComposedCubeMapTexture", "GeneratedCubeMapTexture", "ImageCubeMapTexture" /// Environmental effects component: /// "Background", "Fog", "FogCoordinate", "LocalFog", "TextureBackground" /// Environmental sensor component: /// "ProximitySensor", "TransformSensor", "VisibilitySensor" /// Followers component: /// "ColorChaser", "ColorDamper", "CoordinateChaser", "CoordinateDamper", "OrientationChaser", "OrientationDamper", "PositionChaser", /// "PositionChaser2D", "PositionDamper", "PositionDamper2D", "ScalarChaser", "ScalarDamper", "TexCoordChaser2D", "TexCoordDamper2D" /// Geospatial component: /// "GeoCoordinate", "GeoElevationGrid", "GeoLocation", "GeoLOD", "GeoMetadata", "GeoOrigin", "GeoPositionInterpolator", "GeoProximitySensor", /// "GeoTouchSensor", "GeoTransform", "GeoViewpoint" /// Humanoid Animation (H-Anim) component: /// "HAnimDisplacer", "HAnimHumanoid", "HAnimJoint", "HAnimSegment", "HAnimSite" /// Interpolation component: /// "ColorInterpolator", "CoordinateInterpolator", "CoordinateInterpolator2D", "EaseInEaseOut", "NormalInterpolator", "OrientationInterpolator", /// "PositionInterpolator", "PositionInterpolator2D", "ScalarInterpolator", "SplinePositionInterpolator", "SplinePositionInterpolator2D", /// "SplineScalarInterpolator", "SquadOrientationInterpolator", /// Key device sensor component: /// "KeySensor", "StringSensor" /// Layering component: /// "Layer", "LayerSet", "Viewport" /// Layout component: /// "Layout", "LayoutGroup", "LayoutLayer", "ScreenFontStyle", "ScreenGroup" /// Navigation component: /// "Billboard", "Collision", "LOD", "NavigationInfo", "OrthoViewpoint", "Viewpoint", "ViewpointGroup" /// Networking component: /// "Anchor", "LoadSensor" /// NURBS component: /// "Contour2D", "ContourPolyline2D", "CoordinateDouble", "NurbsCurve", "NurbsCurve2D", "NurbsOrientationInterpolator", "NurbsPatchSurface", /// "NurbsPositionInterpolator", "NurbsSet", "NurbsSurfaceInterpolator", "NurbsSweptSurface", "NurbsSwungSurface", "NurbsTextureCoordinate", /// "NurbsTrimmedSurface" /// Particle systems component: /// "BoundedPhysicsModel", "ConeEmitter", "ExplosionEmitter", "ForcePhysicsModel", "ParticleSystem", "PointEmitter", "PolylineEmitter", /// "SurfaceEmitter", "VolumeEmitter", "WindPhysicsModel" /// Picking component: /// "LinePickSensor", "PickableGroup", "PointPickSensor", "PrimitivePickSensor", "VolumePickSensor" /// Pointing device sensor component: /// "CylinderSensor", "PlaneSensor", "SphereSensor", "TouchSensor" /// Rendering component: /// "ClipPlane" /// Rigid body physics: /// "BallJoint", "CollidableOffset", "CollidableShape", "CollisionCollection", "CollisionSensor", "CollisionSpace", "Contact", "DoubleAxisHingeJoint", /// "MotorJoint", "RigidBody", "RigidBodyCollection", "SingleAxisHingeJoint", "SliderJoint", "UniversalJoint" /// Scripting component: /// "Script" /// Programmable shaders component: /// "ComposedShader", "FloatVertexAttribute", "Matrix3VertexAttribute", "Matrix4VertexAttribute", "PackagedShader", "ProgramShader", "ShaderPart", /// "ShaderProgram", /// Shape component: /// "FillProperties", "LineProperties", "TwoSidedMaterial" /// Sound component: /// "AudioClip", "Sound" /// Text component: /// "FontStyle", "Text" /// Texturing3D Component: /// "ComposedTexture3D", "ImageTexture3D", "PixelTexture3D", "TextureCoordinate3D", "TextureCoordinate4D", "TextureTransformMatrix3D", /// "TextureTransform3D" /// Texturing component: /// "MovieTexture", "MultiTexture", "MultiTextureCoordinate", "MultiTextureTransform", "PixelTexture", "TextureCoordinateGenerator", /// "TextureProperties", /// Time component: /// "TimeSensor" /// Event Utilities component: /// "BooleanFilter", "BooleanSequencer", "BooleanToggle", "BooleanTrigger", "IntegerSequencer", "IntegerTrigger", "TimeTrigger", /// Volume rendering component: /// "BlendedVolumeStyle", "BoundaryEnhancementVolumeStyle", "CartoonVolumeStyle", "ComposedVolumeStyle", "EdgeEnhancementVolumeStyle", /// "IsoSurfaceVolumeData", "OpacityMapVolumeStyle", "ProjectionVolumeStyle", "SegmentedVolumeData", "ShadedVolumeStyle", /// "SilhouetteEnhancementVolumeStyle", "ToneMappedVolumeStyle", "VolumeData" /// /// Supported nodes: /// Core component: /// "MetadataBoolean", "MetadataDouble", "MetadataFloat", "MetadataInteger", "MetadataSet", "MetadataString" /// Geometry2D component: /// "Arc2D", "ArcClose2D", "Circle2D", "Disk2D", "Polyline2D", "Polypoint2D", "Rectangle2D", "TriangleSet2D" /// Geometry3D component: /// "Box", "Cone", "Cylinder", "ElevationGrid", "Extrusion", "IndexedFaceSet", "Sphere" /// Grouping component: /// "Group", "StaticGroup", "Switch", "Transform" /// Lighting component: /// "DirectionalLight", "PointLight", "SpotLight" /// Networking component: /// "Inline" /// Rendering component: /// "Color", "ColorRGBA", "Coordinate", "IndexedLineSet", "IndexedTriangleFanSet", "IndexedTriangleSet", "IndexedTriangleStripSet", "LineSet", /// "PointSet", "TriangleFanSet", "TriangleSet", "TriangleStripSet", "Normal" /// Shape component: /// "Shape", "Appearance", "Material" /// Texturing component: /// "ImageTexture", "TextureCoordinate", "TextureTransform" /// /// Limitations of attribute "USE". /// If "USE" is set then node must be empty, like that: /// /// not the /// /// /// Ignored attributes: "creaseAngle", "convex", "solid". /// /// Texture coordinates generating: only for Sphere, Cone, Cylinder. In all other case used PLANE mapping. /// It's better that Assimp main code has powerfull texture coordinates generator. Then is not needed to /// duplicate this code in every importer. /// /// Lighting limitations. /// If light source placed in some group with "DEF" set. And after that some node is use it group with "USE" attribute then /// you will get error about duplicate light sources. That's happening because Assimp require names for lights but do not like /// duplicates of it )). /// /// Color for faces. /// That's happening when attribute "colorPerVertex" is set to "false". But Assimp do not hold how many colors has mesh and require /// equal length for mVertices and mColors. You will see the colors but vertices will use call which last used in "colorIdx". /// /// That's all for now. Enjoy /// class X3DImporter : public BaseImporter { /***********************************************/ /******************** Types ********************/ /***********************************************/ /***********************************************/ /****************** Constants ******************/ /***********************************************/ private: static const aiImporterDesc Description; /***********************************************/ /****************** Variables ******************/ /***********************************************/ private: CX3DImporter_NodeElement* NodeElement_Cur;///< Current element. irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object std::string mFileDir; public: std::list NodeElement_List;///< All elements of scene graph. /***********************************************/ /****************** Functions ******************/ /***********************************************/ private: /// \fn X3DImporter(const X3DImporter& pScene) /// Disabled copy constructor. X3DImporter(const X3DImporter& pScene); /// \fn X3DImporter& operator=(const X3DImporter& pScene) /// Disabled assign operator. X3DImporter& operator=(const X3DImporter& pScene); /// \fn void Clear() /// Clear all temporary data. void Clear(); /***********************************************/ /************* Functions: find set *************/ /***********************************************/ /// \fn bool FindNodeElement_FromRoot(const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement) /// Find requested node element. Search will be made in all existing nodes. /// \param [in] pID - ID of requested element. /// \param [in] pType - type of requested element. /// \param [out] pElement - pointer to pointer to item found. /// \return true - if the element is found, else - false. bool FindNodeElement_FromRoot(const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement); /// \fn bool FindNodeElement_FromNode(CX3DImporter_NodeElement* pStartNode, const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement) /// Find requested node element. Search will be made from pointed node down to childs. /// \param [in] pStartNode - pointer to start node. /// \param [in] pID - ID of requested element. /// \param [in] pType - type of requested element. /// \param [out] pElement - pointer to pointer to item found. /// \return true - if the element is found, else - false. bool FindNodeElement_FromNode(CX3DImporter_NodeElement* pStartNode, const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement); /// \fn bool FindNodeElement(const std::string& pName, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement) /// Find requested node element. For "Node"'s accounting flag "Static". /// \param [in] pName - name of requested element. /// \param [in] pType - type of requested element. /// \param [out] pElement - pointer to pointer to item found. /// \return true - if the element is found, else - false. bool FindNodeElement(const std::string& pName, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement); /***********************************************/ /********* Functions: postprocess set **********/ /***********************************************/ /// \fn aiMatrix4x4 PostprocessHelper_Matrix_GlobalToCurrent() const /// \return transformation matrix from global coordinate system to local. aiMatrix4x4 PostprocessHelper_Matrix_GlobalToCurrent() const; /// \fn void PostprocessHelper_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, std::list& pList) const /// Check if child elements of node element is metadata and add it to temporary list. /// \param [in] pNodeElement - node element where metadata is searching. /// \param [out] pList - temporary list for collected metadata. void PostprocessHelper_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, std::list& pList) const; /// \fn bool bool PostprocessHelper_ElementIsMetadata(const CX3DImporter_NodeElement::EType pType) const /// Check if type of node element is metadata. E.g. , . /// \param [in] pType - checked type. /// \return true - if the type corresponds to the metadata. bool PostprocessHelper_ElementIsMetadata(const CX3DImporter_NodeElement::EType pType) const; /// \fn bool PostprocessHelper_ElementIsMesh(const CX3DImporter_NodeElement::EType pType) const /// Check if type of node element is geometry object and can be used to build mesh. E.g. , . /// \param [in] pType - checked type. /// \return true - if the type corresponds to the mesh. bool PostprocessHelper_ElementIsMesh(const CX3DImporter_NodeElement::EType pType) const; /// \fn void Postprocess_BuildLight(const CX3DImporter_NodeElement& pNodeElement, std::list& pSceneLightList) const /// Read CX3DImporter_NodeElement_Light, create aiLight and add it to list of the lights. /// \param [in] pNodeElement - reference to lisght element(, , ). /// \param [out] pSceneLightList - reference to list of the lights. void Postprocess_BuildLight(const CX3DImporter_NodeElement& pNodeElement, std::list& pSceneLightList) const; /// \fn void Postprocess_BuildMaterial(const CX3DImporter_NodeElement& pNodeElement, aiMaterial** pMaterial) const /// Create filled structure with type \ref aiMaterial from \ref CX3DImporter_NodeElement. This function itseld extract /// all needed data from scene graph. /// \param [in] pNodeElement - reference to material element(). /// \param [out] pMaterial - pointer to pointer to created material. *pMaterial must be nullptr. void Postprocess_BuildMaterial(const CX3DImporter_NodeElement& pNodeElement, aiMaterial** pMaterial) const; /// \fn void Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeElement, aiMesh** pMesh) const /// Create filled structure with type \ref aiMaterial from \ref CX3DImporter_NodeElement. This function itseld extract /// all needed data from scene graph. /// \param [in] pNodeElement - reference to geometry object. /// \param [out] pMesh - pointer to pointer to created mesh. *pMesh must be nullptr. void Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeElement, aiMesh** pMesh) const; /// \fn void Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode, std::list& pSceneMeshList, std::list& pSceneMaterialList, std::list& pSceneLightList) const /// Create aiNode from CX3DImporter_NodeElement. Also function check children and make recursive call. /// \param [out] pNode - pointer to pointer to created node. *pNode must be nullptr. /// \param [in] pNodeElement - CX3DImporter_NodeElement which read. /// \param [out] pSceneNode - aiNode for filling. /// \param [out] pSceneMeshList - list with aiMesh which belong to scene. /// \param [out] pSceneMaterialList - list with aiMaterial which belong to scene. /// \param [out] pSceneLightList - list with aiLight which belong to scene. void Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode, std::list& pSceneMeshList, std::list& pSceneMaterialList, std::list& pSceneLightList) const; /// \fn void Postprocess_BuildShape(const CX3DImporter_NodeElement_Shape& pShapeNodeElement, std::list& pNodeMeshInd, std::list& pSceneMeshList, std::list& pSceneMaterialList) const /// To create mesh and material kept in . /// \param pShapeNodeElement - reference to node element which kept data. /// \param pNodeMeshInd - reference to list with mesh indices. When pShapeNodeElement will read new mesh index will be added to this list. /// \param pSceneMeshList - reference to list with meshes. When pShapeNodeElement will read new mesh will be added to this list. /// \param pSceneMaterialList - reference to list with materials. When pShapeNodeElement will read new material will be added to this list. void Postprocess_BuildShape(const CX3DImporter_NodeElement_Shape& pShapeNodeElement, std::list& pNodeMeshInd, std::list& pSceneMeshList, std::list& pSceneMaterialList) const; /// \fn void Postprocess_CollectMetadata(aiNode& pSceneNode, const CX3DImporter_NodeElement& pNodeElement) const /// Check if child elements of node element is metadata and add it to scene node. /// \param [in] pNodeElement - node element where metadata is searching. /// \param [out] pSceneNode - scene node in which metadata will be added. void Postprocess_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode) const; /***********************************************/ /************* Functions: throw set ************/ /***********************************************/ /// \fn void Throw_ArgOutOfRange(const std::string& pArgument) /// Call that function when argument is out of range and exception must be raised. /// \throw DeadlyImportError. /// \param [in] pArgument - argument name. void Throw_ArgOutOfRange(const std::string& pArgument); /// \fn void Throw_CloseNotFound(const std::string& pNode) /// Call that function when close tag of node not found and exception must be raised. /// E.g.: /// /// /// /// \throw DeadlyImportError. /// \param [in] pNode - node name in which exception happened. void Throw_CloseNotFound(const std::string& pNode); /// \fn void Throw_ConvertFail_Str2ArrF(const std::string& pAttrValue) /// Call that function when string value can not be converted to floating point value and exception must be raised. /// \param [in] pAttrValue - attribute value. /// \throw DeadlyImportError. void Throw_ConvertFail_Str2ArrF(const std::string& pAttrValue); /// \fn void Throw_DEF_And_USE() /// Call that function when in node defined attributes "DEF" and "USE" and exception must be raised. /// E.g.: /// \throw DeadlyImportError. void Throw_DEF_And_USE(); /// \fn void Throw_IncorrectAttr(const std::string& pAttrName) /// Call that function when attribute name is incorrect and exception must be raised. /// \param [in] pAttrName - attribute name. /// \throw DeadlyImportError. void Throw_IncorrectAttr(const std::string& pAttrName); /// \fn void Throw_IncorrectAttrValue(const std::string& pAttrName) /// Call that function when attribute value is incorrect and exception must be raised. /// \param [in] pAttrName - attribute name. /// \throw DeadlyImportError. void Throw_IncorrectAttrValue(const std::string& pAttrName); /// \fn void Throw_MoreThanOnceDefined(const std::string& pNode, const std::string& pDescription) /// Call that function when some type of nodes are defined twice or more when must be used only once and exception must be raised. /// E.g.: /// /// /// /// /// \throw DeadlyImportError. /// \param [in] pNodeType - type of node which defined one more time. /// \param [in] pDescription - message about error. E.g. what the node defined while exception raised. void Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription); /// \fn void Throw_TagCountIncorrect(const std::string& pNode) /// Call that function when count of opening and closing tags which create group(e.g. ) are not equal and exception must be raised. /// E.g.: /// /// /// /// /// /// \throw DeadlyImportError. /// \param [in] pNode - node name in which exception happened. void Throw_TagCountIncorrect(const std::string& pNode); /// \fn void Throw_USE_NotFound(const std::string& pAttrValue) /// Call that function when defined in "USE" element are not found in graph and exception must be raised. /// \param [in] pAttrValue - "USE" attribute value. /// \throw DeadlyImportError. void Throw_USE_NotFound(const std::string& pAttrValue); /***********************************************/ /************** Functions: LOG set *************/ /***********************************************/ /// \fn void LogInfo(const std::string& pMessage) /// Short variant for calling \ref DefaultLogger::get()->info() void LogInfo(const std::string& pMessage) { DefaultLogger::get()->info(pMessage); } /***********************************************/ /************** Functions: XML set *************/ /***********************************************/ /// \fn void XML_CheckNode_MustBeEmpty() /// Chek if current node is empty: . If not then exception will throwed. void XML_CheckNode_MustBeEmpty(); /// \fn bool XML_CheckNode_NameEqual(const std::string& pNodeName) /// Chek if current node name is equal to pNodeName. /// \param [in] pNodeName - name for checking. /// return true if current node name is equal to pNodeName, else - false. bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; } /// \fn void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName) /// Skip unsupported node and report about that. Depend on node name can be skipped begin tag of node all whole node. /// \param [in] pParentNodeName - parent node name. Used for reporting. void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName); /// \fn bool XML_SearchNode(const std::string& pNodeName) /// Search for specified node in file. XML file read pointer(mReader) will point to found node or file end after search is end. /// \param [in] pNodeName - requested node name. /// return true - if node is found, else - false. bool XML_SearchNode(const std::string& pNodeName); /// \fn bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \return read data. bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx); /// \fn float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \return read data. float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx); /// \fn int32_t XML_ReadNode_GetAttrVal_AsI32(const int pAttrIdx) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \return read data. int32_t XML_ReadNode_GetAttrVal_AsI32(const int pAttrIdx); /// \fn void XML_ReadNode_GetAttrVal_AsCol3f(const int pAttrIdx, aiColor3D& pValue) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. void XML_ReadNode_GetAttrVal_AsCol3f(const int pAttrIdx, aiColor3D& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsVec2f(const int pAttrIdx, aiVector2D& pValue) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. void XML_ReadNode_GetAttrVal_AsVec2f(const int pAttrIdx, aiVector2D& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsVec3f(const int pAttrIdx, aiVector3D& pValue) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. void XML_ReadNode_GetAttrVal_AsVec3f(const int pAttrIdx, aiVector3D& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsListB(const int pAttrIdx, std::list& pValue) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. void XML_ReadNode_GetAttrVal_AsListB(const int pAttrIdx, std::list& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsArrB(const int pAttrIdx, std::vector& pValue) /// \overload void XML_ReadNode_GetAttrVal_AsListBool(const int pAttrIdx, std::list& pValue) void XML_ReadNode_GetAttrVal_AsArrB(const int pAttrIdx, std::vector& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsListI32(const int pAttrIdx, std::list& pValue) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. void XML_ReadNode_GetAttrVal_AsListI32(const int pAttrIdx, std::list& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsArrI32(const int pAttrIdx, std::vector& pValue) /// \overload void XML_ReadNode_GetAttrVal_AsListI32(const int pAttrIdx, std::list& pValue) void XML_ReadNode_GetAttrVal_AsArrI32(const int pAttrIdx, std::vector& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsListF(const int pAttrIdx, std::list& pValue) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. void XML_ReadNode_GetAttrVal_AsListF(const int pAttrIdx, std::list& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector& pValue) /// \overload void XML_ReadNode_GetAttrVal_AsListF(const int pAttrIdx, std::list& pValue) void XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsListD(const int pAttrIdx, std::list& pValue) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. void XML_ReadNode_GetAttrVal_AsListD(const int pAttrIdx, std::list& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsArrD(const int pAttrIdx, std::vector& pValue) /// \overload void XML_ReadNode_GetAttrVal_AsListD(const int pAttrIdx, std::list& pValue) void XML_ReadNode_GetAttrVal_AsArrD(const int pAttrIdx, std::vector& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::list& pValue) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. void XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::list& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::vector& pValue) /// \overload void XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::vector& pValue) void XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::vector& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list& pValue) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. void XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsArrCol4f(const int pAttrIdx, std::vector& pValue) /// \overload void XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list& pValue) void XML_ReadNode_GetAttrVal_AsArrCol4f(const int pAttrIdx, std::vector& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list& pValue) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. void XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsArrVec2f(const int pAttrIdx, std::vector& pValue) /// \overload void XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list& pValue) void XML_ReadNode_GetAttrVal_AsArrVec2f(const int pAttrIdx, std::vector& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list& pValue) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. void XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsArrVec3f(const int pAttrIdx, std::vector& pValue) /// \overload void XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list& pValue) void XML_ReadNode_GetAttrVal_AsArrVec3f(const int pAttrIdx, std::vector& pValue); /// \fn void XML_ReadNode_GetAttrVal_AsListS(const int pAttrIdx, std::list& pValue) /// Read attribute value. /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [out] pValue - read data. void XML_ReadNode_GetAttrVal_AsListS(const int pAttrIdx, std::list& pValue); /***********************************************/ /******* Functions: geometry helper set *******/ /***********************************************/ /// \fn aiVector3D GeometryHelper_Make_Point2D(const float pAngle, const float pRadius) /// Make point on surface oXY. /// \param [in] pAngle - angle in radians between radius-vector of point and oX axis. Angle extends from the oX axis counterclockwise to the radius-vector. /// \param [in] pRadius - length of radius-vector. /// \return made point coordinates. aiVector3D GeometryHelper_Make_Point2D(const float pAngle, const float pRadius); /// \fn void GeometryHelper_Make_Arc2D(const float pStartAngle, const float pEndAngle, const float pRadius, size_t pNumSegments, std::list& pVertices) /// Make 2D figure - linear circular arc with center in (0, 0). The z-coordinate is 0. The arc extends from the pStartAngle counterclockwise /// to the pEndAngle. If pStartAngle and pEndAngle have the same value, a circle is specified. If the absolute difference between pStartAngle /// and pEndAngle is greater than or equal to 2pi, a circle is specified. /// \param [in] pStartAngle - angle in radians of start of the arc. /// \param [in] pEndAngle - angle in radians of end of the arc. /// \param [in] pRadius - radius of the arc. /// \param [out] pNumSegments - number of segments in arc. In other words - tesselation factor. /// \param [out] pVertices - generated vertices. void GeometryHelper_Make_Arc2D(const float pStartAngle, const float pEndAngle, const float pRadius, size_t pNumSegments, std::list& pVertices); /// \fn void GeometryHelper_Extend_PointToLine(const std::list& pPoint, std::list& pLine) /// Create line set from point set. /// \param [in] pPoint - input points list. /// \param [out] pLine - made lines list. void GeometryHelper_Extend_PointToLine(const std::list& pPoint, std::list& pLine); /// \fn GeometryHelper_Extend_PolylineIdxToLineIdx(const std::list& pPolylineCoordIdx, std::list& pLineCoordIdx) /// Create CoordIdx of line set from CoordIdx of polyline set. /// \param [in] pPolylineCoordIdx - vertices indices divided by delimiter "-1". Must contain faces with two or more indices. /// \param [out] pLineCoordIdx - made CoordIdx of line set. void GeometryHelper_Extend_PolylineIdxToLineIdx(const std::list& pPolylineCoordIdx, std::list& pLineCoordIdx); /// \fn void GeometryHelper_MakeQL_RectParallelepiped(const aiVector3D& pSize, std::list& pVertices) /// Make 3D body - rectangular parallelepiped with center in (0, 0). QL mean quadlist (\sa pVertices). /// \param [in] pSize - scale factor for body for every axis. E.g. (1, 2, 1) mean: X-size and Z-size - 1, Y-size - 2. /// \param [out] pVertices - generated vertices. The list of vertices is grouped in quads. void GeometryHelper_MakeQL_RectParallelepiped(const aiVector3D& pSize, std::list& pVertices); /// \fn void GeometryHelper_CoordIdxStr2FacesArr(const std::list& pCoordIdx, std::vector& pFaces, unsigned int& pPrimitiveTypes) const /// Create faces array from vertices indices array. /// \param [in] pCoordIdx - vertices indices divided by delimiter "-1". /// \param [in] pFaces - created faces array. /// \param [in] pPrimitiveTypes - type of primitives in faces. void GeometryHelper_CoordIdxStr2FacesArr(const std::list& pCoordIdx, std::vector& pFaces, unsigned int& pPrimitiveTypes) const; /// \fn void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColors, const bool pColorPerVertex) const /// Add colors to mesh. /// a. If colorPerVertex is FALSE, colours are applied to each face, as follows: /// If the colorIndex field is not empty, one colour is used for each face of the mesh. There shall be at least as many indices in the /// colorIndex field as there are faces in the mesh. The colorIndex field shall not contain any negative entries. /// If the colorIndex field is empty, the colours in the X3DColorNode node are applied to each face of the mesh in order. /// There shall be at least as many colours in the X3DColorNode node as there are faces. /// b. If colorPerVertex is TRUE, colours are applied to each vertex, as follows: /// If the colorIndex field is not empty, colours are applied to each vertex of the mesh in exactly the same manner that the coordIndex /// field is used to choose coordinates for each vertex from the node. The colorIndex field shall contain end-of-face markers (−1) /// in exactly the same places as the coordIndex field. /// If the colorIndex field is empty, the coordIndex field is used to choose colours from the X3DColorNode node. /// \param [in] pMesh - mesh for adding data. /// \param [in] pCoordIdx - vertices indices divided by delimiter "-1". /// \param [in] pColorIdx - color indices for every vertex divided by delimiter "-1" if \ref pColorPerVertex is true. if \ref pColorPerVertex is false /// then pColorIdx contain color indices for every faces and must not contain delimiter "-1". /// \param [in] pColors - defined colors. /// \param [in] pColorPerVertex - if \ref pColorPerVertex is true then color in \ref pColors defined for every vertex, if false - for every face. void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColorIdx, const std::list& pColors, const bool pColorPerVertex) const; /// \fn void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColorIdx, const std::list& pColors, const bool pColorPerVertex) const; /// \overload void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColorIdx, const std::list& pColors, const bool pColorPerVertex) const; void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColorIdx, const std::list& pColors, const bool pColorPerVertex) const; /// \fn void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pColors, const bool pColorPerVertex) const /// Add colors to mesh. /// \param [in] pMesh - mesh for adding data. /// \param [in] pColors - defined colors. /// \param [in] pColorPerVertex - if \ref pColorPerVertex is true then color in \ref pColors defined for every vertex, if false - for every face. void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pColors, const bool pColorPerVertex) const; /// \fn void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pColors, const bool pColorPerVertex) const /// \overload void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pColors, const bool pColorPerVertex) const void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pColors, const bool pColorPerVertex) const; /// \fn void MeshGeometry_AddNormal(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pNormalIdx, const std::list& pNormals, const bool pNormalPerVertex) const /// Add normals to mesh. Function work similar to \ref MeshGeometry_AddColor; void MeshGeometry_AddNormal(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pNormalIdx, const std::list& pNormals, const bool pNormalPerVertex) const; /// \fn void MeshGeometry_AddNormal(aiMesh& pMesh, const std::list& pNormals, const bool pNormalPerVertex) const /// Add normals to mesh. Function work similar to \ref MeshGeometry_AddColor; void MeshGeometry_AddNormal(aiMesh& pMesh, const std::list& pNormals, const bool pNormalPerVertex) const; /// \fn void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pTexCoordIdx, const std::list& pTexCoords) const /// Add texture coordinates to mesh. Function work similar to \ref MeshGeometry_AddColor; void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pTexCoordIdx, const std::list& pTexCoords) const; /// \fn void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list& pTexCoords) const /// Add texture coordinates to mesh. Function work similar to \ref MeshGeometry_AddColor; void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list& pTexCoords) const; /// \fn aiMesh* GeometryHelper_MakeMesh(const std::list& pCoordIdx, const std::list& pVertices) const /// Create mesh. /// \param [in] pCoordIdx - vertices indices divided by delimiter "-1". /// \param [in] pVertices - vertices of mesh. /// \return created mesh. aiMesh* GeometryHelper_MakeMesh(const std::list& pCoordIdx, const std::list& pVertices) const; /***********************************************/ /******** Functions: parse set private *********/ /***********************************************/ /// \fn void ParseHelper_Group_Begin() /// Create node element with type "Node" in scene graph. That operation is needed when you enter to X3D group node /// like , etc. When exiting from X3D group node(e.g. ) \ref ParseHelper_Node_Exit must /// be called. /// \param [in] pStatic - flag: if true then static node is created(e.g. ). void ParseHelper_Group_Begin(const bool pStatic = false); /// \fn void ParseHelper_Node_Enter(CX3DImporter_NodeElement* pNode) /// Make pNode as current and enter deeper for parsing child nodes. At end \ref ParseHelper_Node_Exit must be called. /// \param [in] pNode - new current node. void ParseHelper_Node_Enter(CX3DImporter_NodeElement* pNode); /// \fn void ParseHelper_Group_End() /// This function must be called when exiting from X3D group node(e.g. ). \ref ParseHelper_Group_Begin. void ParseHelper_Node_Exit(); /// \fn void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString) /// Attribute values of floating point types can take form ".x"(without leading zero). irrXMLReader can not read this form of values and it /// must be converted to right form - "0.xxx". /// \param [in] pInStr - pointer to input string which can contain incorrect form of values. /// \param [out[ pOutString - output string with right form of values. void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString); /// \fn bool ParseHelper_CheckRead_X3DMetadataObject() /// Check if current node has nodes of type X3DMetadataObject. Why we must do it? Because X3DMetadataObject can be in any non-empty X3DNode. /// Meaning that X3DMetadataObject can be in any non-empty node in . /// \return true - if metadata node are found and parsed, false - metadata not found. bool ParseHelper_CheckRead_X3DMetadataObject(); /// \fn bool ParseHelper_CheckRead_X3DMetadataObject() /// Check if current node has nodes of type X3DGeometricPropertyNode. X3DGeometricPropertyNode /// X3DGeometricPropertyNode inheritors: /// , , , , , , , , /// , , , , , /// , , . /// \return true - if nodes are found and parsed, false - nodes not found. bool ParseHelper_CheckRead_X3DGeometricPropertyNode(); /// \fn void ParseNode_Root() /// Parse node of the file. void ParseNode_Root(); /// \fn void ParseNode_Head() /// Parse node of the file. void ParseNode_Head(); /// \fn void ParseNode_Root() /// Parse node of the file. void ParseNode_Scene(); /// \fn void ParseNode_Metadata(CX3DImporter_NodeElement* pParent, const std::string& pNodeName) /// Parse child nodes of node. /// \param [in] pNodeName - parsed node name. Must be set because that function is general and name needed for checking the end /// and error reporing. /// \param [in] pParentElement - parent metadata element. void ParseNode_Metadata(CX3DImporter_NodeElement* pParentElement, const std::string& pNodeName); /// \fn void ParseNode_MetadataBoolean() /// Parse node of the file. void ParseNode_MetadataBoolean(); /// \fn void ParseNode_MetadataDouble() /// Parse node of the file. void ParseNode_MetadataDouble(); /// \fn void ParseNode_MetadataFloat() /// Parse node of the file. void ParseNode_MetadataFloat(); /// \fn void ParseNode_MetadataInteger() /// Parse node of the file. void ParseNode_MetadataInteger(); /// \fn void ParseNode_MetadataSet() /// Parse node of the file. void ParseNode_MetadataSet(); /// \fn void ParseNode_MetadataString() /// Parse node of the file. void ParseNode_MetadataString(); /// \fn void ParseNode_Geometry2D_Arc2D() /// Parse node of the file. void ParseNode_Geometry2D_Arc2D(); /// \fn void ParseNode_Geometry2D_ArcClose2D() /// Parse node of the file. void ParseNode_Geometry2D_ArcClose2D(); /// \fn void ParseNode_Geometry2D_Circle2D() /// Parse node of the file. void ParseNode_Geometry2D_Circle2D(); /// \fn void ParseNode_Geometry2D_Disk2D() /// Parse node of the file. void ParseNode_Geometry2D_Disk2D(); /// \fn void ParseNode_Geometry2D_Polyline2D() /// Parse node of the file. void ParseNode_Geometry2D_Polyline2D(); /// \fn void ParseNode_Geometry2D_Polypoint2D() /// Parse node of the file. void ParseNode_Geometry2D_Polypoint2D(); /// \fn void ParseNode_Geometry2D_Rectangle2D() /// Parse node of the file. void ParseNode_Geometry2D_Rectangle2D(); /// \fn void ParseNode_Geometry2D_TriangleSet2D() /// Parse node of the file. void ParseNode_Geometry2D_TriangleSet2D(); /// \fn void ParseNode_Geometry3D_Box() /// Parse node of the file. void ParseNode_Geometry3D_Box(); /// \fn void ParseNode_Geometry3D_Cone() /// Parse node of the file. void ParseNode_Geometry3D_Cone(); /// \fn void ParseNode_Geometry3D_Cylinder() /// Parse node of the file. void ParseNode_Geometry3D_Cylinder(); /// \fn void ParseNode_Geometry3D_ElevationGrid() /// Parse node of the file. void ParseNode_Geometry3D_ElevationGrid(); /// \fn void ParseNode_Geometry3D_Extrusion() /// Parse node of the file. void ParseNode_Geometry3D_Extrusion(); /// \fn void ParseNode_Geometry3D_IndexedFaceSet() /// Parse node of the file. void ParseNode_Geometry3D_IndexedFaceSet(); /// \fn void ParseNode_Geometry3D_Sphere() /// Parse node of the file. void ParseNode_Geometry3D_Sphere(); /// \fn void ParseNode_Grouping_Group() /// Parse node of the file. And create new node in scene graph. void ParseNode_Grouping_Group(); /// \fn void ParseNode_Grouping_GroupEnd() /// Doing actions at an exit from . Walk up in scene graph. void ParseNode_Grouping_GroupEnd(); /// \fn void ParseNode_Grouping_StaticGroup() /// Parse node of the file. And create new node in scene graph. void ParseNode_Grouping_StaticGroup(); /// \fn void ParseNode_Grouping_StaticGroupEnd() /// Doing actions at an exit from . Walk up in scene graph. void ParseNode_Grouping_StaticGroupEnd(); /// \fn void ParseNode_Grouping_Switch() /// Parse node of the file. And create new node in scene graph. void ParseNode_Grouping_Switch(); /// \fn void ParseNode_Grouping_SwitchEnd() /// Doing actions at an exit from . Walk up in scene graph. void ParseNode_Grouping_SwitchEnd(); /// \fn void ParseNode_Grouping_Transform() /// Parse node of the file. And create new node in scene graph. void ParseNode_Grouping_Transform(); /// \fn void ParseNode_Grouping_TransformEnd() /// Doing actions at an exit from . Walk up in scene graph. void ParseNode_Grouping_TransformEnd(); /// \fn void ParseNode_Rendering_Color() /// Parse node of the file. void ParseNode_Rendering_Color(); /// \fn void ParseNode_Rendering_ColorRGBA() /// Parse node of the file. void ParseNode_Rendering_ColorRGBA(); /// \fn void ParseNode_Rendering_Coordinate() /// Parse node of the file. void ParseNode_Rendering_Coordinate(); /// \fn void ParseNode_Rendering_Normal() /// Parse node of the file. void ParseNode_Rendering_Normal(); /// \fn void ParseNode_Rendering_IndexedLineSet() /// Parse node of the file. void ParseNode_Rendering_IndexedLineSet(); /// \fn void ParseNode_Rendering_IndexedTriangleFanSet() /// Parse node of the file. void ParseNode_Rendering_IndexedTriangleFanSet(); /// \fn void ParseNode_Rendering_IndexedTriangleSet() /// Parse node of the file. void ParseNode_Rendering_IndexedTriangleSet(); /// \fn void ParseNode_Rendering_IndexedTriangleStripSet() /// Parse node of the file. void ParseNode_Rendering_IndexedTriangleStripSet(); /// \fn void ParseNode_Rendering_LineSet() /// Parse node of the file. void ParseNode_Rendering_LineSet(); /// \fn void ParseNode_Rendering_PointSet() /// Parse node of the file. void ParseNode_Rendering_PointSet(); /// \fn void ParseNode_Rendering_TriangleFanSet() /// Parse node of the file. void ParseNode_Rendering_TriangleFanSet(); /// \fn void ParseNode_Rendering_TriangleSet() /// Parse node of the file. void ParseNode_Rendering_TriangleSet(); /// \fn void ParseNode_Rendering_TriangleStripSet() /// Parse node of the file. void ParseNode_Rendering_TriangleStripSet(); /// \fn void ParseNode_Texturing_ImageTexture() /// Parse node of the file. void ParseNode_Texturing_ImageTexture(); /// \fn void ParseNode_Texturing_TextureCoordinate() /// Parse node of the file. void ParseNode_Texturing_TextureCoordinate(); /// \fn void ParseNode_Texturing_TextureTransform() /// Parse node of the file. void ParseNode_Texturing_TextureTransform(); /// \fn void ParseNode_Shape_Shape() /// Parse node of the file. void ParseNode_Shape_Shape(); /// \fn void ParseNode_Shape_Appearance() /// Parse node of the file. void ParseNode_Shape_Appearance(); /// \fn void ParseNode_Shape_Material() /// Parse node of the file. void ParseNode_Shape_Material(); /// \fn void ParseNode_Networking_Inline() /// Parse node of the file. void ParseNode_Networking_Inline(); /// \fn void ParseNode_Lighting_DirectionalLight() /// Parse node of the file. void ParseNode_Lighting_DirectionalLight(); /// \fn void ParseNode_Lighting_PointLight() /// Parse node of the file. void ParseNode_Lighting_PointLight(); /// \fn void ParseNode_Lighting_SpotLight() /// Parse node of the file. void ParseNode_Lighting_SpotLight(); public: /// \fn X3DImporter() /// Default constructor. X3DImporter() : NodeElement_Cur(nullptr), mReader(nullptr) {} /// \fn ~X3DImporter() /// Default destructor. ~X3DImporter(); /***********************************************/ /******** Functions: parse set, public *********/ /***********************************************/ /// \fn void ParseFile(const std::string& pFile, IOSystem* pIOHandler) /// Parse X3D file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph. /// Also exception can be throwed if trouble will found. /// \param [in] pFile - name of file to be parsed. /// \param [in] pIOHandler - pointer to IO helper object. void ParseFile(const std::string& pFile, IOSystem* pIOHandler); /***********************************************/ /********* Functions: BaseImporter set *********/ /***********************************************/ bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const; void GetExtensionList(std::set& pExtensionList); void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); const aiImporterDesc* GetInfo ()const; };// class X3DImporter }// namespace Assimp #endif // INCLUDED_AI_X3D_IMPORTER_H