X3DImporter_Shape.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /// \file X3DImporter_Shape.cpp
  2. /// \brief Parsing data from nodes of "Shape" set of X3D.
  3. /// \date 2015-2016
  4. /// \author [email protected]
  5. #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
  6. #include "X3DImporter.hpp"
  7. #include "X3DImporter_Macro.hpp"
  8. namespace Assimp
  9. {
  10. // <Shape
  11. // DEF="" ID
  12. // USE="" IDREF
  13. // bboxCenter="0 0 0" SFVec3f [initializeOnly]
  14. // bboxSize="-1 -1 -1" SFVec3f [initializeOnly]
  15. // >
  16. // <!-- ShapeChildContentModel -->
  17. // "ShapeChildContentModel is the child-node content model corresponding to X3DShapeNode. ShapeChildContentModel can contain a single Appearance node and a
  18. // single geometry node, in any order.
  19. // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model."
  20. // </Shape>
  21. // A Shape node is unlit if either of the following is true:
  22. // The shape's appearance field is NULL (default).
  23. // The material field in the Appearance node is NULL (default).
  24. // NOTE Geometry nodes that represent lines or points do not support lighting.
  25. void X3DImporter::ParseNode_Shape_Shape()
  26. {
  27. std::string use, def;
  28. CX3DImporter_NodeElement* ne;
  29. MACRO_ATTRREAD_LOOPBEG;
  30. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  31. MACRO_ATTRREAD_LOOPEND;
  32. // if "USE" defined then find already defined element.
  33. if(!use.empty())
  34. {
  35. MACRO_USE_CHECKANDAPPLY(def, use, ENET_Shape, ne);
  36. }
  37. else
  38. {
  39. // create and if needed - define new geometry object.
  40. ne = new CX3DImporter_NodeElement_Shape(NodeElement_Cur);
  41. if(!def.empty()) ne->ID = def;
  42. // check for child nodes
  43. if(!mReader->isEmptyElement())
  44. {
  45. ParseHelper_Node_Enter(ne);
  46. MACRO_NODECHECK_LOOPBEGIN("Shape");
  47. // check for appearance node
  48. if(XML_CheckNode_NameEqual("Appearance")) { ParseNode_Shape_Appearance(); continue; }
  49. // check for X3DGeometryNodes
  50. if(XML_CheckNode_NameEqual("Arc2D")) { ParseNode_Geometry2D_Arc2D(); continue; }
  51. if(XML_CheckNode_NameEqual("ArcClose2D")) { ParseNode_Geometry2D_ArcClose2D(); continue; }
  52. if(XML_CheckNode_NameEqual("Circle2D")) { ParseNode_Geometry2D_Circle2D(); continue; }
  53. if(XML_CheckNode_NameEqual("Disk2D")) { ParseNode_Geometry2D_Disk2D(); continue; }
  54. if(XML_CheckNode_NameEqual("Polyline2D")) { ParseNode_Geometry2D_Polyline2D(); continue; }
  55. if(XML_CheckNode_NameEqual("Polypoint2D")) { ParseNode_Geometry2D_Polypoint2D(); continue; }
  56. if(XML_CheckNode_NameEqual("Rectangle2D")) { ParseNode_Geometry2D_Rectangle2D(); continue; }
  57. if(XML_CheckNode_NameEqual("TriangleSet2D")) { ParseNode_Geometry2D_TriangleSet2D(); continue; }
  58. if(XML_CheckNode_NameEqual("Box")) { ParseNode_Geometry3D_Box(); continue; }
  59. if(XML_CheckNode_NameEqual("Cone")) { ParseNode_Geometry3D_Cone(); continue; }
  60. if(XML_CheckNode_NameEqual("Cylinder")) { ParseNode_Geometry3D_Cylinder(); continue; }
  61. if(XML_CheckNode_NameEqual("ElevationGrid")) { ParseNode_Geometry3D_ElevationGrid(); continue; }
  62. if(XML_CheckNode_NameEqual("Extrusion")) { ParseNode_Geometry3D_Extrusion(); continue; }
  63. if(XML_CheckNode_NameEqual("IndexedFaceSet")) { ParseNode_Geometry3D_IndexedFaceSet(); continue; }
  64. if(XML_CheckNode_NameEqual("Sphere")) { ParseNode_Geometry3D_Sphere(); continue; }
  65. if(XML_CheckNode_NameEqual("IndexedLineSet")) { ParseNode_Rendering_IndexedLineSet(); continue; }
  66. if(XML_CheckNode_NameEqual("LineSet")) { ParseNode_Rendering_LineSet(); continue; }
  67. if(XML_CheckNode_NameEqual("PointSet")) { ParseNode_Rendering_PointSet(); continue; }
  68. if(XML_CheckNode_NameEqual("IndexedTriangleFanSet")) { ParseNode_Rendering_IndexedTriangleFanSet(); continue; }
  69. if(XML_CheckNode_NameEqual("IndexedTriangleSet")) { ParseNode_Rendering_IndexedTriangleSet(); continue; }
  70. if(XML_CheckNode_NameEqual("IndexedTriangleStripSet")) { ParseNode_Rendering_IndexedTriangleStripSet(); continue; }
  71. if(XML_CheckNode_NameEqual("TriangleFanSet")) { ParseNode_Rendering_TriangleFanSet(); continue; }
  72. if(XML_CheckNode_NameEqual("TriangleSet")) { ParseNode_Rendering_TriangleSet(); continue; }
  73. if(XML_CheckNode_NameEqual("TriangleStripSet")) { ParseNode_Rendering_TriangleStripSet(); continue; }
  74. // check for X3DMetadataObject
  75. if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("Shape");
  76. MACRO_NODECHECK_LOOPEND("Shape");
  77. ParseHelper_Node_Exit();
  78. }// if(!mReader->isEmptyElement())
  79. else
  80. {
  81. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  82. }
  83. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  84. }// if(!use.empty()) else
  85. }
  86. // <Appearance
  87. // DEF="" ID
  88. // USE="" IDREF
  89. // >
  90. // <!-- AppearanceChildContentModel -->
  91. // "Child-node content model corresponding to X3DAppearanceChildNode. Appearance can contain FillProperties, LineProperties, Material, any Texture node and
  92. // any TextureTransform node, in any order. No more than one instance of these nodes is allowed. Appearance may also contain multiple shaders (ComposedShader,
  93. // PackagedShader, ProgramShader).
  94. // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model."
  95. // </Appearance>
  96. void X3DImporter::ParseNode_Shape_Appearance()
  97. {
  98. std::string use, def;
  99. CX3DImporter_NodeElement* ne;
  100. MACRO_ATTRREAD_LOOPBEG;
  101. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  102. MACRO_ATTRREAD_LOOPEND;
  103. // if "USE" defined then find already defined element.
  104. if(!use.empty())
  105. {
  106. MACRO_USE_CHECKANDAPPLY(def, use, ENET_Appearance, ne);
  107. }
  108. else
  109. {
  110. // create and if needed - define new geometry object.
  111. ne = new CX3DImporter_NodeElement_Appearance(NodeElement_Cur);
  112. if(!def.empty()) ne->ID = def;
  113. // check for child nodes
  114. if(!mReader->isEmptyElement())
  115. {
  116. ParseHelper_Node_Enter(ne);
  117. MACRO_NODECHECK_LOOPBEGIN("Appearance");
  118. if(XML_CheckNode_NameEqual("Material")) { ParseNode_Shape_Material(); continue; }
  119. if(XML_CheckNode_NameEqual("ImageTexture")) { ParseNode_Texturing_ImageTexture(); continue; }
  120. if(XML_CheckNode_NameEqual("TextureTransform")) { ParseNode_Texturing_TextureTransform(); continue; }
  121. // check for X3DMetadataObject
  122. if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("Appearance");
  123. MACRO_NODECHECK_LOOPEND("Appearance");
  124. ParseHelper_Node_Exit();
  125. }// if(!mReader->isEmptyElement())
  126. else
  127. {
  128. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  129. }
  130. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  131. }// if(!use.empty()) else
  132. }
  133. // <Material
  134. // DEF="" ID
  135. // USE="" IDREF
  136. // ambientIntensity="0.2" SFFloat [inputOutput]
  137. // diffuseColor="0.8 0.8 0.8" SFColor [inputOutput]
  138. // emissiveColor="0 0 0" SFColor [inputOutput]
  139. // shininess="0.2" SFFloat [inputOutput]
  140. // specularColor="0 0 0" SFColor [inputOutput]
  141. // transparency="0" SFFloat [inputOutput]
  142. // />
  143. void X3DImporter::ParseNode_Shape_Material()
  144. {
  145. std::string use, def;
  146. float ambientIntensity = 0.2f;
  147. float shininess = 0.2f;
  148. float transparency = 0;
  149. aiColor3D diffuseColor(0.8f, 0.8f, 0.8f);
  150. aiColor3D emissiveColor(0, 0, 0);
  151. aiColor3D specularColor(0, 0, 0);
  152. CX3DImporter_NodeElement* ne;
  153. MACRO_ATTRREAD_LOOPBEG;
  154. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  155. MACRO_ATTRREAD_CHECK_RET("ambientIntensity", ambientIntensity, XML_ReadNode_GetAttrVal_AsFloat);
  156. MACRO_ATTRREAD_CHECK_RET("shininess", shininess, XML_ReadNode_GetAttrVal_AsFloat);
  157. MACRO_ATTRREAD_CHECK_RET("transparency", transparency, XML_ReadNode_GetAttrVal_AsFloat);
  158. MACRO_ATTRREAD_CHECK_REF("diffuseColor", diffuseColor, XML_ReadNode_GetAttrVal_AsCol3f);
  159. MACRO_ATTRREAD_CHECK_REF("emissiveColor", emissiveColor, XML_ReadNode_GetAttrVal_AsCol3f);
  160. MACRO_ATTRREAD_CHECK_REF("specularColor", specularColor, XML_ReadNode_GetAttrVal_AsCol3f);
  161. MACRO_ATTRREAD_LOOPEND;
  162. // if "USE" defined then find already defined element.
  163. if(!use.empty())
  164. {
  165. MACRO_USE_CHECKANDAPPLY(def, use, ENET_Material, ne);
  166. }
  167. else
  168. {
  169. // create and if needed - define new geometry object.
  170. ne = new CX3DImporter_NodeElement_Material(NodeElement_Cur);
  171. if(!def.empty()) ne->ID = def;
  172. ((CX3DImporter_NodeElement_Material*)ne)->AmbientIntensity = ambientIntensity;
  173. ((CX3DImporter_NodeElement_Material*)ne)->Shininess = shininess;
  174. ((CX3DImporter_NodeElement_Material*)ne)->Transparency = transparency;
  175. ((CX3DImporter_NodeElement_Material*)ne)->DiffuseColor = diffuseColor;
  176. ((CX3DImporter_NodeElement_Material*)ne)->EmissiveColor = emissiveColor;
  177. ((CX3DImporter_NodeElement_Material*)ne)->SpecularColor = specularColor;
  178. // check for child nodes
  179. if(!mReader->isEmptyElement())
  180. ParseNode_Metadata(ne, "Material");
  181. else
  182. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  183. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  184. }// if(!use.empty()) else
  185. }
  186. }// namespace Assimp
  187. #endif // !ASSIMP_BUILD_NO_X3D_IMPORTER