X3DImporter_Shape.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. Open Asset Import Library (assimp)
  3. ----------------------------------------------------------------------
  4. Copyright (c) 2006-2020, assimp team
  5. All rights reserved.
  6. Redistribution and use of this software in source and binary forms,
  7. with or without modification, are permitted provided that the
  8. following conditions are met:
  9. * Redistributions of source code must retain the above
  10. copyright notice, this list of conditions and the
  11. following disclaimer.
  12. * Redistributions in binary form must reproduce the above
  13. copyright notice, this list of conditions and the
  14. following disclaimer in the documentation and/or other
  15. materials provided with the distribution.
  16. * Neither the name of the assimp team, nor the names of its
  17. contributors may be used to endorse or promote products
  18. derived from this software without specific prior
  19. written permission of the assimp team.
  20. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. ----------------------------------------------------------------------
  32. */
  33. /// \file X3DImporter_Shape.cpp
  34. /// \brief Parsing data from nodes of "Shape" set of X3D.
  35. /// \date 2015-2016
  36. /// \author [email protected]
  37. #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
  38. #include "X3DImporter.hpp"
  39. #include "X3DImporter_Macro.hpp"
  40. namespace Assimp
  41. {
  42. // <Shape
  43. // DEF="" ID
  44. // USE="" IDREF
  45. // bboxCenter="0 0 0" SFVec3f [initializeOnly]
  46. // bboxSize="-1 -1 -1" SFVec3f [initializeOnly]
  47. // >
  48. // <!-- ShapeChildContentModel -->
  49. // "ShapeChildContentModel is the child-node content model corresponding to X3DShapeNode. ShapeChildContentModel can contain a single Appearance node and a
  50. // single geometry node, in any order.
  51. // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model."
  52. // </Shape>
  53. // A Shape node is unlit if either of the following is true:
  54. // The shape's appearance field is nullptr (default).
  55. // The material field in the Appearance node is nullptr (default).
  56. // NOTE Geometry nodes that represent lines or points do not support lighting.
  57. void X3DImporter::ParseNode_Shape_Shape()
  58. {
  59. std::string use, def;
  60. CX3DImporter_NodeElement* ne( nullptr );
  61. MACRO_ATTRREAD_LOOPBEG;
  62. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  63. MACRO_ATTRREAD_LOOPEND;
  64. // if "USE" defined then find already defined element.
  65. if(!use.empty())
  66. {
  67. MACRO_USE_CHECKANDAPPLY(def, use, ENET_Shape, ne);
  68. }
  69. else
  70. {
  71. // create and if needed - define new geometry object.
  72. ne = new CX3DImporter_NodeElement_Shape(NodeElement_Cur);
  73. if(!def.empty()) ne->ID = def;
  74. // check for child nodes
  75. if(!mReader->isEmptyElement())
  76. {
  77. ParseHelper_Node_Enter(ne);
  78. MACRO_NODECHECK_LOOPBEGIN("Shape");
  79. // check for appearance node
  80. if(XML_CheckNode_NameEqual("Appearance")) { ParseNode_Shape_Appearance(); continue; }
  81. // check for X3DGeometryNodes
  82. if(XML_CheckNode_NameEqual("Arc2D")) { ParseNode_Geometry2D_Arc2D(); continue; }
  83. if(XML_CheckNode_NameEqual("ArcClose2D")) { ParseNode_Geometry2D_ArcClose2D(); continue; }
  84. if(XML_CheckNode_NameEqual("Circle2D")) { ParseNode_Geometry2D_Circle2D(); continue; }
  85. if(XML_CheckNode_NameEqual("Disk2D")) { ParseNode_Geometry2D_Disk2D(); continue; }
  86. if(XML_CheckNode_NameEqual("Polyline2D")) { ParseNode_Geometry2D_Polyline2D(); continue; }
  87. if(XML_CheckNode_NameEqual("Polypoint2D")) { ParseNode_Geometry2D_Polypoint2D(); continue; }
  88. if(XML_CheckNode_NameEqual("Rectangle2D")) { ParseNode_Geometry2D_Rectangle2D(); continue; }
  89. if(XML_CheckNode_NameEqual("TriangleSet2D")) { ParseNode_Geometry2D_TriangleSet2D(); continue; }
  90. if(XML_CheckNode_NameEqual("Box")) { ParseNode_Geometry3D_Box(); continue; }
  91. if(XML_CheckNode_NameEqual("Cone")) { ParseNode_Geometry3D_Cone(); continue; }
  92. if(XML_CheckNode_NameEqual("Cylinder")) { ParseNode_Geometry3D_Cylinder(); continue; }
  93. if(XML_CheckNode_NameEqual("ElevationGrid")) { ParseNode_Geometry3D_ElevationGrid(); continue; }
  94. if(XML_CheckNode_NameEqual("Extrusion")) { ParseNode_Geometry3D_Extrusion(); continue; }
  95. if(XML_CheckNode_NameEqual("IndexedFaceSet")) { ParseNode_Geometry3D_IndexedFaceSet(); continue; }
  96. if(XML_CheckNode_NameEqual("Sphere")) { ParseNode_Geometry3D_Sphere(); continue; }
  97. if(XML_CheckNode_NameEqual("IndexedLineSet")) { ParseNode_Rendering_IndexedLineSet(); continue; }
  98. if(XML_CheckNode_NameEqual("LineSet")) { ParseNode_Rendering_LineSet(); continue; }
  99. if(XML_CheckNode_NameEqual("PointSet")) { ParseNode_Rendering_PointSet(); continue; }
  100. if(XML_CheckNode_NameEqual("IndexedTriangleFanSet")) { ParseNode_Rendering_IndexedTriangleFanSet(); continue; }
  101. if(XML_CheckNode_NameEqual("IndexedTriangleSet")) { ParseNode_Rendering_IndexedTriangleSet(); continue; }
  102. if(XML_CheckNode_NameEqual("IndexedTriangleStripSet")) { ParseNode_Rendering_IndexedTriangleStripSet(); continue; }
  103. if(XML_CheckNode_NameEqual("TriangleFanSet")) { ParseNode_Rendering_TriangleFanSet(); continue; }
  104. if(XML_CheckNode_NameEqual("TriangleSet")) { ParseNode_Rendering_TriangleSet(); continue; }
  105. if(XML_CheckNode_NameEqual("TriangleStripSet")) { ParseNode_Rendering_TriangleStripSet(); continue; }
  106. // check for X3DMetadataObject
  107. if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("Shape");
  108. MACRO_NODECHECK_LOOPEND("Shape");
  109. ParseHelper_Node_Exit();
  110. }// if(!mReader->isEmptyElement())
  111. else
  112. {
  113. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  114. }
  115. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  116. }// if(!use.empty()) else
  117. }
  118. // <Appearance
  119. // DEF="" ID
  120. // USE="" IDREF
  121. // >
  122. // <!-- AppearanceChildContentModel -->
  123. // "Child-node content model corresponding to X3DAppearanceChildNode. Appearance can contain FillProperties, LineProperties, Material, any Texture node and
  124. // any TextureTransform node, in any order. No more than one instance of these nodes is allowed. Appearance may also contain multiple shaders (ComposedShader,
  125. // PackagedShader, ProgramShader).
  126. // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model."
  127. // </Appearance>
  128. void X3DImporter::ParseNode_Shape_Appearance()
  129. {
  130. std::string use, def;
  131. CX3DImporter_NodeElement* ne( nullptr );
  132. MACRO_ATTRREAD_LOOPBEG;
  133. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  134. MACRO_ATTRREAD_LOOPEND;
  135. // if "USE" defined then find already defined element.
  136. if(!use.empty())
  137. {
  138. MACRO_USE_CHECKANDAPPLY(def, use, ENET_Appearance, ne);
  139. }
  140. else
  141. {
  142. // create and if needed - define new geometry object.
  143. ne = new CX3DImporter_NodeElement_Appearance(NodeElement_Cur);
  144. if(!def.empty()) ne->ID = def;
  145. // check for child nodes
  146. if(!mReader->isEmptyElement())
  147. {
  148. ParseHelper_Node_Enter(ne);
  149. MACRO_NODECHECK_LOOPBEGIN("Appearance");
  150. if(XML_CheckNode_NameEqual("Material")) { ParseNode_Shape_Material(); continue; }
  151. if(XML_CheckNode_NameEqual("ImageTexture")) { ParseNode_Texturing_ImageTexture(); continue; }
  152. if(XML_CheckNode_NameEqual("TextureTransform")) { ParseNode_Texturing_TextureTransform(); continue; }
  153. // check for X3DMetadataObject
  154. if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("Appearance");
  155. MACRO_NODECHECK_LOOPEND("Appearance");
  156. ParseHelper_Node_Exit();
  157. }// if(!mReader->isEmptyElement())
  158. else
  159. {
  160. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  161. }
  162. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  163. }// if(!use.empty()) else
  164. }
  165. // <Material
  166. // DEF="" ID
  167. // USE="" IDREF
  168. // ambientIntensity="0.2" SFFloat [inputOutput]
  169. // diffuseColor="0.8 0.8 0.8" SFColor [inputOutput]
  170. // emissiveColor="0 0 0" SFColor [inputOutput]
  171. // shininess="0.2" SFFloat [inputOutput]
  172. // specularColor="0 0 0" SFColor [inputOutput]
  173. // transparency="0" SFFloat [inputOutput]
  174. // />
  175. void X3DImporter::ParseNode_Shape_Material()
  176. {
  177. std::string use, def;
  178. float ambientIntensity = 0.2f;
  179. float shininess = 0.2f;
  180. float transparency = 0;
  181. aiColor3D diffuseColor(0.8f, 0.8f, 0.8f);
  182. aiColor3D emissiveColor(0, 0, 0);
  183. aiColor3D specularColor(0, 0, 0);
  184. CX3DImporter_NodeElement* ne( nullptr );
  185. MACRO_ATTRREAD_LOOPBEG;
  186. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  187. MACRO_ATTRREAD_CHECK_RET("ambientIntensity", ambientIntensity, XML_ReadNode_GetAttrVal_AsFloat);
  188. MACRO_ATTRREAD_CHECK_RET("shininess", shininess, XML_ReadNode_GetAttrVal_AsFloat);
  189. MACRO_ATTRREAD_CHECK_RET("transparency", transparency, XML_ReadNode_GetAttrVal_AsFloat);
  190. MACRO_ATTRREAD_CHECK_REF("diffuseColor", diffuseColor, XML_ReadNode_GetAttrVal_AsCol3f);
  191. MACRO_ATTRREAD_CHECK_REF("emissiveColor", emissiveColor, XML_ReadNode_GetAttrVal_AsCol3f);
  192. MACRO_ATTRREAD_CHECK_REF("specularColor", specularColor, XML_ReadNode_GetAttrVal_AsCol3f);
  193. MACRO_ATTRREAD_LOOPEND;
  194. // if "USE" defined then find already defined element.
  195. if(!use.empty())
  196. {
  197. MACRO_USE_CHECKANDAPPLY(def, use, ENET_Material, ne);
  198. }
  199. else
  200. {
  201. // create and if needed - define new geometry object.
  202. ne = new CX3DImporter_NodeElement_Material(NodeElement_Cur);
  203. if(!def.empty()) ne->ID = def;
  204. ((CX3DImporter_NodeElement_Material*)ne)->AmbientIntensity = ambientIntensity;
  205. ((CX3DImporter_NodeElement_Material*)ne)->Shininess = shininess;
  206. ((CX3DImporter_NodeElement_Material*)ne)->Transparency = transparency;
  207. ((CX3DImporter_NodeElement_Material*)ne)->DiffuseColor = diffuseColor;
  208. ((CX3DImporter_NodeElement_Material*)ne)->EmissiveColor = emissiveColor;
  209. ((CX3DImporter_NodeElement_Material*)ne)->SpecularColor = specularColor;
  210. // check for child nodes
  211. if(!mReader->isEmptyElement())
  212. ParseNode_Metadata(ne, "Material");
  213. else
  214. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  215. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  216. }// if(!use.empty()) else
  217. }
  218. }// namespace Assimp
  219. #endif // !ASSIMP_BUILD_NO_X3D_IMPORTER