| /* |
| Open Asset Import Library (assimp) |
| ---------------------------------------------------------------------- |
| |
| Copyright (c) 2006-2017, assimp team |
| |
| All rights reserved. |
| |
| Redistribution and use of this software in source and binary forms, |
| with or without modification, are permitted provided that the |
| following conditions are met: |
| |
| * Redistributions of source code must retain the above |
| copyright notice, this list of conditions and the |
| following disclaimer. |
| |
| * Redistributions in binary form must reproduce the above |
| copyright notice, this list of conditions and the |
| following disclaimer in the documentation and/or other |
| materials provided with the distribution. |
| |
| * Neither the name of the assimp team, nor the names of its |
| contributors may be used to endorse or promote products |
| derived from this software without specific prior |
| written permission of the assimp team. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| ---------------------------------------------------------------------- |
| */ |
| /// \file X3DImporter_Postprocess.cpp |
| /// \brief Convert built scenegraph and objects to Assimp scenegraph. |
| /// \date 2015-2016 |
| /// \author smal.root@gmail.com |
| |
| #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER |
| |
| #include "X3DImporter.hpp" |
| |
| // Header files, Assimp. |
| #include <assimp/ai_assert.h> |
| #include "StandardShapes.h" |
| #include "StringUtils.h" |
| |
| // Header files, stdlib. |
| #include <algorithm> |
| #include <iterator> |
| #include <string> |
| |
| namespace Assimp |
| { |
| |
| aiMatrix4x4 X3DImporter::PostprocessHelper_Matrix_GlobalToCurrent() const |
| { |
| CX3DImporter_NodeElement* cur_node; |
| std::list<aiMatrix4x4> matr; |
| aiMatrix4x4 out_matr; |
| |
| // starting walk from current element to root |
| cur_node = NodeElement_Cur; |
| if(cur_node != nullptr) |
| { |
| do |
| { |
| // if cur_node is group then store group transformation matrix in list. |
| if(cur_node->Type == CX3DImporter_NodeElement::ENET_Group) matr.push_back(((CX3DImporter_NodeElement_Group*)cur_node)->Transformation); |
| |
| cur_node = cur_node->Parent; |
| } while(cur_node != nullptr); |
| } |
| |
| // multiplicate all matrices in reverse order |
| for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); rit++) out_matr = out_matr * (*rit); |
| |
| return out_matr; |
| } |
| |
| void X3DImporter::PostprocessHelper_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, std::list<CX3DImporter_NodeElement*>& pList) const |
| { |
| // walk through childs and find for metadata. |
| for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++) |
| { |
| if(((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaBoolean) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaDouble) || |
| ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaFloat) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaInteger) || |
| ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaString)) |
| { |
| pList.push_back(*el_it); |
| } |
| else if((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaSet) |
| { |
| PostprocessHelper_CollectMetadata(**el_it, pList); |
| } |
| }// for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++) |
| } |
| |
| bool X3DImporter::PostprocessHelper_ElementIsMetadata(const CX3DImporter_NodeElement::EType pType) const |
| { |
| if((pType == CX3DImporter_NodeElement::ENET_MetaBoolean) || (pType == CX3DImporter_NodeElement::ENET_MetaDouble) || |
| (pType == CX3DImporter_NodeElement::ENET_MetaFloat) || (pType == CX3DImporter_NodeElement::ENET_MetaInteger) || |
| (pType == CX3DImporter_NodeElement::ENET_MetaString) || (pType == CX3DImporter_NodeElement::ENET_MetaSet)) |
| { |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| } |
| |
| bool X3DImporter::PostprocessHelper_ElementIsMesh(const CX3DImporter_NodeElement::EType pType) const |
| { |
| if((pType == CX3DImporter_NodeElement::ENET_Arc2D) || (pType == CX3DImporter_NodeElement::ENET_ArcClose2D) || |
| (pType == CX3DImporter_NodeElement::ENET_Box) || (pType == CX3DImporter_NodeElement::ENET_Circle2D) || |
| (pType == CX3DImporter_NodeElement::ENET_Cone) || (pType == CX3DImporter_NodeElement::ENET_Cylinder) || |
| (pType == CX3DImporter_NodeElement::ENET_Disk2D) || (pType == CX3DImporter_NodeElement::ENET_ElevationGrid) || |
| (pType == CX3DImporter_NodeElement::ENET_Extrusion) || (pType == CX3DImporter_NodeElement::ENET_IndexedFaceSet) || |
| (pType == CX3DImporter_NodeElement::ENET_IndexedLineSet) || (pType == CX3DImporter_NodeElement::ENET_IndexedTriangleFanSet) || |
| (pType == CX3DImporter_NodeElement::ENET_IndexedTriangleSet) || (pType == CX3DImporter_NodeElement::ENET_IndexedTriangleStripSet) || |
| (pType == CX3DImporter_NodeElement::ENET_PointSet) || (pType == CX3DImporter_NodeElement::ENET_LineSet) || |
| (pType == CX3DImporter_NodeElement::ENET_Polyline2D) || (pType == CX3DImporter_NodeElement::ENET_Polypoint2D) || |
| (pType == CX3DImporter_NodeElement::ENET_Rectangle2D) || (pType == CX3DImporter_NodeElement::ENET_Sphere) || |
| (pType == CX3DImporter_NodeElement::ENET_TriangleFanSet) || (pType == CX3DImporter_NodeElement::ENET_TriangleSet) || |
| (pType == CX3DImporter_NodeElement::ENET_TriangleSet2D) || (pType == CX3DImporter_NodeElement::ENET_TriangleStripSet)) |
| { |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| } |
| |
| void X3DImporter::Postprocess_BuildLight(const CX3DImporter_NodeElement& pNodeElement, std::list<aiLight*>& pSceneLightList) const |
| { |
| const CX3DImporter_NodeElement_Light& ne = *( ( CX3DImporter_NodeElement_Light* ) &pNodeElement ); |
| aiMatrix4x4 transform_matr = PostprocessHelper_Matrix_GlobalToCurrent(); |
| aiLight* new_light = new aiLight; |
| |
| new_light->mName = ne.ID; |
| new_light->mColorAmbient = ne.Color * ne.AmbientIntensity; |
| new_light->mColorDiffuse = ne.Color * ne.Intensity; |
| new_light->mColorSpecular = ne.Color * ne.Intensity; |
| switch(pNodeElement.Type) |
| { |
| case CX3DImporter_NodeElement::ENET_DirectionalLight: |
| new_light->mType = aiLightSource_DIRECTIONAL; |
| new_light->mDirection = ne.Direction, new_light->mDirection *= transform_matr; |
| |
| break; |
| case CX3DImporter_NodeElement::ENET_PointLight: |
| new_light->mType = aiLightSource_POINT; |
| new_light->mPosition = ne.Location, new_light->mPosition *= transform_matr; |
| new_light->mAttenuationConstant = ne.Attenuation.x; |
| new_light->mAttenuationLinear = ne.Attenuation.y; |
| new_light->mAttenuationQuadratic = ne.Attenuation.z; |
| |
| break; |
| case CX3DImporter_NodeElement::ENET_SpotLight: |
| new_light->mType = aiLightSource_SPOT; |
| new_light->mPosition = ne.Location, new_light->mPosition *= transform_matr; |
| new_light->mDirection = ne.Direction, new_light->mDirection *= transform_matr; |
| new_light->mAttenuationConstant = ne.Attenuation.x; |
| new_light->mAttenuationLinear = ne.Attenuation.y; |
| new_light->mAttenuationQuadratic = ne.Attenuation.z; |
| new_light->mAngleInnerCone = ne.BeamWidth; |
| new_light->mAngleOuterCone = ne.CutOffAngle; |
| |
| break; |
| default: |
| throw DeadlyImportError("Postprocess_BuildLight. Unknown type of light: " + to_string(pNodeElement.Type) + "."); |
| } |
| |
| pSceneLightList.push_back(new_light); |
| } |
| |
| void X3DImporter::Postprocess_BuildMaterial(const CX3DImporter_NodeElement& pNodeElement, aiMaterial** pMaterial) const |
| { |
| // check argument |
| if(pMaterial == nullptr) throw DeadlyImportError("Postprocess_BuildMaterial. pMaterial is nullptr."); |
| if(*pMaterial != nullptr) throw DeadlyImportError("Postprocess_BuildMaterial. *pMaterial must be nullptr."); |
| |
| *pMaterial = new aiMaterial; |
| aiMaterial& taimat = **pMaterial;// creating alias for convenience. |
| |
| // at this point pNodeElement point to <Appearance> node. Walk through childs and add all stored data. |
| for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++) |
| { |
| if((*el_it)->Type == CX3DImporter_NodeElement::ENET_Material) |
| { |
| aiColor3D tcol3; |
| float tvalf; |
| CX3DImporter_NodeElement_Material& tnemat = *((CX3DImporter_NodeElement_Material*)*el_it); |
| |
| tcol3.r = tnemat.AmbientIntensity, tcol3.g = tnemat.AmbientIntensity, tcol3.b = tnemat.AmbientIntensity; |
| taimat.AddProperty(&tcol3, 1, AI_MATKEY_COLOR_AMBIENT); |
| taimat.AddProperty(&tnemat.DiffuseColor, 1, AI_MATKEY_COLOR_DIFFUSE); |
| taimat.AddProperty(&tnemat.EmissiveColor, 1, AI_MATKEY_COLOR_EMISSIVE); |
| taimat.AddProperty(&tnemat.SpecularColor, 1, AI_MATKEY_COLOR_SPECULAR); |
| tvalf = 1; |
| taimat.AddProperty(&tvalf, 1, AI_MATKEY_SHININESS_STRENGTH); |
| taimat.AddProperty(&tnemat.Shininess, 1, AI_MATKEY_SHININESS); |
| tvalf = 1.0f - tnemat.Transparency; |
| taimat.AddProperty(&tvalf, 1, AI_MATKEY_OPACITY); |
| }// if((*el_it)->Type == CX3DImporter_NodeElement::ENET_Material) |
| else if((*el_it)->Type == CX3DImporter_NodeElement::ENET_ImageTexture) |
| { |
| CX3DImporter_NodeElement_ImageTexture& tnetex = *((CX3DImporter_NodeElement_ImageTexture*)*el_it); |
| aiString url_str(tnetex.URL.c_str()); |
| int mode = aiTextureOp_Multiply; |
| |
| taimat.AddProperty(&url_str, AI_MATKEY_TEXTURE_DIFFUSE(0)); |
| taimat.AddProperty(&tnetex.RepeatS, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0)); |
| taimat.AddProperty(&tnetex.RepeatT, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0)); |
| taimat.AddProperty(&mode, 1, AI_MATKEY_TEXOP_DIFFUSE(0)); |
| }// else if((*el_it)->Type == CX3DImporter_NodeElement::ENET_ImageTexture) |
| else if((*el_it)->Type == CX3DImporter_NodeElement::ENET_TextureTransform) |
| { |
| aiUVTransform trans; |
| CX3DImporter_NodeElement_TextureTransform& tnetextr = *((CX3DImporter_NodeElement_TextureTransform*)*el_it); |
| |
| trans.mTranslation = tnetextr.Translation - tnetextr.Center; |
| trans.mScaling = tnetextr.Scale; |
| trans.mRotation = tnetextr.Rotation; |
| taimat.AddProperty(&trans, 1, AI_MATKEY_UVTRANSFORM_DIFFUSE(0)); |
| }// else if((*el_it)->Type == CX3DImporter_NodeElement::ENET_TextureTransform) |
| }// for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++) |
| } |
| |
| void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeElement, aiMesh** pMesh) const |
| { |
| // check argument |
| if(pMesh == nullptr) throw DeadlyImportError("Postprocess_BuildMesh. pMesh is nullptr."); |
| if(*pMesh != nullptr) throw DeadlyImportError("Postprocess_BuildMesh. *pMesh must be nullptr."); |
| |
| /************************************************************************************************************************************/ |
| /************************************************************ Geometry2D ************************************************************/ |
| /************************************************************************************************************************************/ |
| if((pNodeElement.Type == CX3DImporter_NodeElement::ENET_Arc2D) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_ArcClose2D) || |
| (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Circle2D) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Disk2D) || |
| (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Polyline2D) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Polypoint2D) || |
| (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Rectangle2D) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleSet2D)) |
| { |
| CX3DImporter_NodeElement_Geometry2D& tnemesh = *((CX3DImporter_NodeElement_Geometry2D*)&pNodeElement);// create alias for convenience |
| std::vector<aiVector3D> tarr; |
| |
| tarr.reserve(tnemesh.Vertices.size()); |
| for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); it++) tarr.push_back(*it); |
| *pMesh = StandardShapes::MakeMesh(tarr, static_cast<unsigned int>(tnemesh.NumIndices));// create mesh from vertices using Assimp help. |
| |
| return;// mesh is build, nothing to do anymore. |
| } |
| /************************************************************************************************************************************/ |
| /************************************************************ Geometry3D ************************************************************/ |
| /************************************************************************************************************************************/ |
| // |
| // Predefined figures |
| // |
| if((pNodeElement.Type == CX3DImporter_NodeElement::ENET_Box) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Cone) || |
| (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Cylinder) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Sphere)) |
| { |
| CX3DImporter_NodeElement_Geometry3D& tnemesh = *((CX3DImporter_NodeElement_Geometry3D*)&pNodeElement);// create alias for convenience |
| std::vector<aiVector3D> tarr; |
| |
| tarr.reserve(tnemesh.Vertices.size()); |
| for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); it++) tarr.push_back(*it); |
| |
| *pMesh = StandardShapes::MakeMesh(tarr, static_cast<unsigned int>(tnemesh.NumIndices));// create mesh from vertices using Assimp help. |
| |
| return;// mesh is build, nothing to do anymore. |
| } |
| // |
| // Parametric figures |
| // |
| if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_ElevationGrid) |
| { |
| CX3DImporter_NodeElement_ElevationGrid& tnemesh = *((CX3DImporter_NodeElement_ElevationGrid*)&pNodeElement);// create alias for convenience |
| |
| // at first create mesh from existing vertices. |
| *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIdx, tnemesh.Vertices); |
| // copy additional information from children |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) |
| MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA) |
| MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, tnemesh.ColorPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Normal) |
| MeshGeometry_AddNormal(**pMesh, ((CX3DImporter_NodeElement_Normal*)*ch_it)->Value, tnemesh.NormalPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate) |
| MeshGeometry_AddTexCoord(**pMesh, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); |
| else |
| throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of ElevationGrid: " + to_string((*ch_it)->Type) + "."); |
| }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| |
| return;// mesh is build, nothing to do anymore. |
| }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_ElevationGrid) |
| // |
| // Indexed primitives sets |
| // |
| if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedFaceSet) |
| { |
| CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience |
| |
| // at first search for <Coordinate> node and create mesh. |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| { |
| *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value); |
| } |
| } |
| |
| // copy additional information from children |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) |
| MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA) |
| MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, |
| tnemesh.ColorPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| {} // skip because already read when mesh created. |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Normal) |
| MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((CX3DImporter_NodeElement_Normal*)*ch_it)->Value, |
| tnemesh.NormalPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate) |
| MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); |
| else |
| throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedFaceSet: " + to_string((*ch_it)->Type) + "."); |
| }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| |
| return;// mesh is build, nothing to do anymore. |
| }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedFaceSet) |
| |
| if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedLineSet) |
| { |
| CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience |
| |
| // at first search for <Coordinate> node and create mesh. |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| { |
| *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value); |
| } |
| } |
| |
| // copy additional information from children |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| ai_assert(*pMesh); |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) |
| MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA) |
| MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, |
| tnemesh.ColorPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| {} // skip because already read when mesh created. |
| else |
| throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedLineSet: " + to_string((*ch_it)->Type) + "."); |
| }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| |
| return;// mesh is build, nothing to do anymore. |
| }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedLineSet) |
| |
| if((pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleSet) || |
| (pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleFanSet) || |
| (pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleStripSet)) |
| { |
| CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience |
| |
| // at first search for <Coordinate> node and create mesh. |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| { |
| *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value); |
| } |
| } |
| |
| // copy additional information from children |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| ai_assert(*pMesh); |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) |
| MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA) |
| MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, |
| tnemesh.ColorPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| {} // skip because already read when mesh created. |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Normal) |
| MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((CX3DImporter_NodeElement_Normal*)*ch_it)->Value, |
| tnemesh.NormalPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate) |
| MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); |
| else |
| throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedTriangleSet or IndexedTriangleFanSet, or \ |
| IndexedTriangleStripSet: " + to_string((*ch_it)->Type) + "."); |
| }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| |
| return;// mesh is build, nothing to do anymore. |
| }// if((pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleFanSet) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleStripSet)) |
| |
| if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Extrusion) |
| { |
| CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience |
| |
| *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, tnemesh.Vertices); |
| |
| return;// mesh is build, nothing to do anymore. |
| }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Extrusion) |
| |
| // |
| // Primitives sets |
| // |
| if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_PointSet) |
| { |
| CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience |
| |
| // at first search for <Coordinate> node and create mesh. |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| { |
| std::vector<aiVector3D> vec_copy; |
| |
| vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size()); |
| for(std::list<aiVector3D>::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin(); |
| it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); it++) |
| { |
| vec_copy.push_back(*it); |
| } |
| |
| *pMesh = StandardShapes::MakeMesh(vec_copy, 1); |
| } |
| } |
| |
| // copy additional information from children |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| ai_assert(*pMesh); |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) |
| MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, true); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA) |
| MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, true); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| {} // skip because already read when mesh created. |
| else |
| throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of PointSet: " + to_string((*ch_it)->Type) + "."); |
| }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| |
| return;// mesh is build, nothing to do anymore. |
| }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_PointSet) |
| |
| if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_LineSet) |
| { |
| CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience |
| |
| // at first search for <Coordinate> node and create mesh. |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| { |
| *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value); |
| } |
| } |
| |
| // copy additional information from children |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| ai_assert(*pMesh); |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) |
| MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, true); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA) |
| MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, true); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| {} // skip because already read when mesh created. |
| else |
| throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of LineSet: " + to_string((*ch_it)->Type) + "."); |
| }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| |
| return;// mesh is build, nothing to do anymore. |
| }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_LineSet) |
| |
| if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleFanSet) |
| { |
| CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience |
| |
| // at first search for <Coordinate> node and create mesh. |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| { |
| *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value); |
| } |
| } |
| |
| // copy additional information from children |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| if ( nullptr == *pMesh ) { |
| break; |
| } |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) |
| MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value,tnemesh.ColorPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA) |
| MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, tnemesh.ColorPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| {} // skip because already read when mesh created. |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Normal) |
| MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((CX3DImporter_NodeElement_Normal*)*ch_it)->Value, |
| tnemesh.NormalPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate) |
| MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); |
| else |
| throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeFanSet: " + to_string((*ch_it)->Type) + "."); |
| }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| |
| return;// mesh is build, nothing to do anymore. |
| }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleFanSet) |
| |
| if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleSet) |
| { |
| CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience |
| |
| // at first search for <Coordinate> node and create mesh. |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| { |
| std::vector<aiVector3D> vec_copy; |
| |
| vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size()); |
| for(std::list<aiVector3D>::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin(); |
| it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); it++) |
| { |
| vec_copy.push_back(*it); |
| } |
| |
| *pMesh = StandardShapes::MakeMesh(vec_copy, 3); |
| } |
| } |
| |
| // copy additional information from children |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| ai_assert(*pMesh); |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) |
| MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA) |
| MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, tnemesh.ColorPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| {} // skip because already read when mesh created. |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Normal) |
| MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((CX3DImporter_NodeElement_Normal*)*ch_it)->Value, |
| tnemesh.NormalPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate) |
| MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); |
| else |
| throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeSet: " + to_string((*ch_it)->Type) + "."); |
| }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| |
| return;// mesh is build, nothing to do anymore. |
| }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleSet) |
| |
| if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleStripSet) |
| { |
| CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience |
| |
| // at first search for <Coordinate> node and create mesh. |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| { |
| *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value); |
| } |
| } |
| |
| // copy additional information from children |
| for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| { |
| ai_assert(*pMesh); |
| if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) |
| MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA) |
| MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, tnemesh.ColorPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) |
| {} // skip because already read when mesh created. |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Normal) |
| MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((CX3DImporter_NodeElement_Normal*)*ch_it)->Value, |
| tnemesh.NormalPerVertex); |
| else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate) |
| MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); |
| else |
| throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TriangleStripSet: " + to_string((*ch_it)->Type) + "."); |
| }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) |
| |
| return;// mesh is build, nothing to do anymore. |
| }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleStripSet) |
| |
| throw DeadlyImportError("Postprocess_BuildMesh. Unknown mesh type: " + to_string(pNodeElement.Type) + "."); |
| } |
| |
| void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode, std::list<aiMesh*>& pSceneMeshList, |
| std::list<aiMaterial*>& pSceneMaterialList, std::list<aiLight*>& pSceneLightList) const |
| { |
| std::list<CX3DImporter_NodeElement*>::const_iterator chit_begin = pNodeElement.Child.begin(); |
| std::list<CX3DImporter_NodeElement*>::const_iterator chit_end = pNodeElement.Child.end(); |
| std::list<aiNode*> SceneNode_Child; |
| std::list<unsigned int> SceneNode_Mesh; |
| |
| // At first read all metadata |
| Postprocess_CollectMetadata(pNodeElement, pSceneNode); |
| // check if we have deal with grouping node. Which can contain transformation or switch |
| if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Group) |
| { |
| const CX3DImporter_NodeElement_Group& tne_group = *((CX3DImporter_NodeElement_Group*)&pNodeElement);// create alias for convenience |
| |
| pSceneNode.mTransformation = tne_group.Transformation; |
| if(tne_group.UseChoice) |
| { |
| // If Choice is less than zero or greater than the number of nodes in the children field, nothing is chosen. |
| if((tne_group.Choice < 0) || ((size_t)tne_group.Choice >= pNodeElement.Child.size())) |
| { |
| chit_begin = pNodeElement.Child.end(); |
| chit_end = pNodeElement.Child.end(); |
| } |
| else |
| { |
| for(size_t i = 0; i < (size_t)tne_group.Choice; i++) chit_begin++;// forward iterator to chosen node. |
| |
| chit_end = chit_begin; |
| chit_end++;// point end iterator to next element after chosen node. |
| } |
| }// if(tne_group.UseChoice) |
| }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Group) |
| |
| // Reserve memory for fast access and check children. |
| for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; it++) |
| {// in this loop we do not read metadata because it's already read at begin. |
| if((*it)->Type == CX3DImporter_NodeElement::ENET_Group) |
| { |
| // if child is group then create new node and do recursive call. |
| aiNode* new_node = new aiNode; |
| |
| new_node->mName = (*it)->ID; |
| new_node->mParent = &pSceneNode; |
| SceneNode_Child.push_back(new_node); |
| Postprocess_BuildNode(**it, *new_node, pSceneMeshList, pSceneMaterialList, pSceneLightList); |
| } |
| else if((*it)->Type == CX3DImporter_NodeElement::ENET_Shape) |
| { |
| // shape can contain only one geometry and one appearance nodes. |
| Postprocess_BuildShape(*((CX3DImporter_NodeElement_Shape*)*it), SceneNode_Mesh, pSceneMeshList, pSceneMaterialList); |
| } |
| else if(((*it)->Type == CX3DImporter_NodeElement::ENET_DirectionalLight) || ((*it)->Type == CX3DImporter_NodeElement::ENET_PointLight) || |
| ((*it)->Type == CX3DImporter_NodeElement::ENET_SpotLight)) |
| { |
| Postprocess_BuildLight(*((CX3DImporter_NodeElement_Light*)*it), pSceneLightList); |
| } |
| else if(!PostprocessHelper_ElementIsMetadata((*it)->Type))// skip metadata |
| { |
| throw DeadlyImportError("Postprocess_BuildNode. Unknown type: " + to_string((*it)->Type) + "."); |
| } |
| }// for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; it++) |
| |
| // copy data about children and meshes to aiNode. |
| if(SceneNode_Child.size() > 0) |
| { |
| std::list<aiNode*>::const_iterator it = SceneNode_Child.begin(); |
| |
| pSceneNode.mNumChildren = static_cast<unsigned int>(SceneNode_Child.size()); |
| pSceneNode.mChildren = new aiNode*[pSceneNode.mNumChildren]; |
| for(size_t i = 0; i < pSceneNode.mNumChildren; i++) pSceneNode.mChildren[i] = *it++; |
| } |
| |
| if(SceneNode_Mesh.size() > 0) |
| { |
| std::list<unsigned int>::const_iterator it = SceneNode_Mesh.begin(); |
| |
| pSceneNode.mNumMeshes = static_cast<unsigned int>(SceneNode_Mesh.size()); |
| pSceneNode.mMeshes = new unsigned int[pSceneNode.mNumMeshes]; |
| for(size_t i = 0; i < pSceneNode.mNumMeshes; i++) pSceneNode.mMeshes[i] = *it++; |
| } |
| |
| // that's all. return to previous deals |
| } |
| |
| void X3DImporter::Postprocess_BuildShape(const CX3DImporter_NodeElement_Shape& pShapeNodeElement, std::list<unsigned int>& pNodeMeshInd, |
| std::list<aiMesh*>& pSceneMeshList, std::list<aiMaterial*>& pSceneMaterialList) const |
| { |
| aiMaterial* tmat = nullptr; |
| aiMesh* tmesh = nullptr; |
| CX3DImporter_NodeElement::EType mesh_type = CX3DImporter_NodeElement::ENET_Invalid; |
| unsigned int mat_ind = 0; |
| |
| for(std::list<CX3DImporter_NodeElement*>::const_iterator it = pShapeNodeElement.Child.begin(); it != pShapeNodeElement.Child.end(); it++) |
| { |
| if(PostprocessHelper_ElementIsMesh((*it)->Type)) |
| { |
| Postprocess_BuildMesh(**it, &tmesh); |
| if(tmesh != nullptr) |
| { |
| // if mesh successfully built then add data about it to arrays |
| pNodeMeshInd.push_back(static_cast<unsigned int>(pSceneMeshList.size())); |
| pSceneMeshList.push_back(tmesh); |
| // keep mesh type. Need above for texture coordinate generation. |
| mesh_type = (*it)->Type; |
| } |
| } |
| else if((*it)->Type == CX3DImporter_NodeElement::ENET_Appearance) |
| { |
| Postprocess_BuildMaterial(**it, &tmat); |
| if(tmat != nullptr) |
| { |
| // if material successfully built then add data about it to array |
| mat_ind = static_cast<unsigned int>(pSceneMaterialList.size()); |
| pSceneMaterialList.push_back(tmat); |
| } |
| } |
| }// for(std::list<CX3DImporter_NodeElement*>::const_iterator it = pShapeNodeElement.Child.begin(); it != pShapeNodeElement.Child.end(); it++) |
| |
| // associate read material with read mesh. |
| if((tmesh != nullptr) && (tmat != nullptr)) |
| { |
| tmesh->mMaterialIndex = mat_ind; |
| // Check texture mapping. If material has texture but mesh has no texture coordinate then try to ask Assimp to generate texture coordinates. |
| if((tmat->GetTextureCount(aiTextureType_DIFFUSE) != 0) && !tmesh->HasTextureCoords(0)) |
| { |
| int32_t tm; |
| aiVector3D tvec3; |
| |
| switch(mesh_type) |
| { |
| case CX3DImporter_NodeElement::ENET_Box: |
| tm = aiTextureMapping_BOX; |
| break; |
| case CX3DImporter_NodeElement::ENET_Cone: |
| case CX3DImporter_NodeElement::ENET_Cylinder: |
| tm = aiTextureMapping_CYLINDER; |
| break; |
| case CX3DImporter_NodeElement::ENET_Sphere: |
| tm = aiTextureMapping_SPHERE; |
| break; |
| default: |
| tm = aiTextureMapping_PLANE; |
| break; |
| }// switch(mesh_type) |
| |
| tmat->AddProperty(&tm, 1, AI_MATKEY_MAPPING_DIFFUSE(0)); |
| }// if((tmat->GetTextureCount(aiTextureType_DIFFUSE) != 0) && !tmesh->HasTextureCoords(0)) |
| }// if((tmesh != nullptr) && (tmat != nullptr)) |
| } |
| |
| void X3DImporter::Postprocess_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode) const |
| { |
| std::list<CX3DImporter_NodeElement*> meta_list; |
| size_t meta_idx; |
| |
| PostprocessHelper_CollectMetadata(pNodeElement, meta_list);// find metadata in current node element. |
| if ( !meta_list.empty() ) |
| { |
| if ( pSceneNode.mMetaData != nullptr ) { |
| throw DeadlyImportError( "Postprocess. MetaData member in node are not nullptr. Something went wrong." ); |
| } |
| |
| // copy collected metadata to output node. |
| pSceneNode.mMetaData = aiMetadata::Alloc( static_cast<unsigned int>(meta_list.size()) ); |
| meta_idx = 0; |
| for(std::list<CX3DImporter_NodeElement*>::const_iterator it = meta_list.begin(); it != meta_list.end(); it++, meta_idx++) |
| { |
| CX3DImporter_NodeElement_Meta* cur_meta = (CX3DImporter_NodeElement_Meta*)*it; |
| |
| // due to limitations we can add only first element of value list. |
| // Add an element according to its type. |
| if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaBoolean) |
| { |
| if(((CX3DImporter_NodeElement_MetaBoolean*)cur_meta)->Value.size() > 0) |
| pSceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx), cur_meta->Name, *(((CX3DImporter_NodeElement_MetaBoolean*)cur_meta)->Value.begin())); |
| } |
| else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaDouble) |
| { |
| if(((CX3DImporter_NodeElement_MetaDouble*)cur_meta)->Value.size() > 0) |
| pSceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx), cur_meta->Name, (float)*(((CX3DImporter_NodeElement_MetaDouble*)cur_meta)->Value.begin())); |
| } |
| else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaFloat) |
| { |
| if(((CX3DImporter_NodeElement_MetaFloat*)cur_meta)->Value.size() > 0) |
| pSceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx), cur_meta->Name, *(((CX3DImporter_NodeElement_MetaFloat*)cur_meta)->Value.begin())); |
| } |
| else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaInteger) |
| { |
| if(((CX3DImporter_NodeElement_MetaInteger*)cur_meta)->Value.size() > 0) |
| pSceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx), cur_meta->Name, *(((CX3DImporter_NodeElement_MetaInteger*)cur_meta)->Value.begin())); |
| } |
| else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaString) |
| { |
| if(((CX3DImporter_NodeElement_MetaString*)cur_meta)->Value.size() > 0) |
| { |
| aiString tstr(((CX3DImporter_NodeElement_MetaString*)cur_meta)->Value.begin()->data()); |
| |
| pSceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx), cur_meta->Name, tstr); |
| } |
| } |
| else |
| { |
| throw DeadlyImportError("Postprocess. Unknown metadata type."); |
| }// if((*it)->Type == CX3DImporter_NodeElement::ENET_Meta*) else |
| }// for(std::list<CX3DImporter_NodeElement*>::const_iterator it = meta_list.begin(); it != meta_list.end(); it++) |
| }// if( !meta_list.empty() ) |
| } |
| |
| }// namespace Assimp |
| |
| #endif // !ASSIMP_BUILD_NO_X3D_IMPORTER |