IMeshManipulator.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. // Copyright (C) 2002-2012 Nikolaus Gebhardt
  2. // This file is part of the "Irrlicht Engine".
  3. // For conditions of distribution and use, see copyright notice in irrlicht.h
  4. #ifndef __I_MESH_MANIPULATOR_H_INCLUDED__
  5. #define __I_MESH_MANIPULATOR_H_INCLUDED__
  6. #include "IReferenceCounted.h"
  7. #include "vector3d.h"
  8. #include "aabbox3d.h"
  9. #include "matrix4.h"
  10. #include "IAnimatedMesh.h"
  11. #include "IMeshBuffer.h"
  12. #include "SVertexManipulator.h"
  13. namespace irr
  14. {
  15. namespace scene
  16. {
  17. struct SMesh;
  18. //! An interface for easy manipulation of meshes.
  19. /** Scale, set alpha value, flip surfaces, and so on. This exists for
  20. fixing problems with wrong imported or exported meshes quickly after
  21. loading. It is not intended for doing mesh modifications and/or
  22. animations during runtime.
  23. */
  24. class IMeshManipulator : public virtual IReferenceCounted
  25. {
  26. public:
  27. //! Flips the direction of surfaces.
  28. /** Changes backfacing triangles to frontfacing
  29. triangles and vice versa.
  30. \param mesh Mesh on which the operation is performed. */
  31. virtual void flipSurfaces(IMesh* mesh) const = 0;
  32. //! Sets the alpha vertex color value of the whole mesh to a new value.
  33. /** \param mesh Mesh on which the operation is performed.
  34. \param alpha New alpha value. Must be a value between 0 and 255. */
  35. void setVertexColorAlpha(IMesh* mesh, s32 alpha) const
  36. {
  37. apply(scene::SVertexColorSetAlphaManipulator(alpha), mesh);
  38. }
  39. //! Sets the alpha vertex color value of the whole mesh to a new value.
  40. /** \param buffer Meshbuffer on which the operation is performed.
  41. \param alpha New alpha value. Must be a value between 0 and 255. */
  42. void setVertexColorAlpha(IMeshBuffer* buffer, s32 alpha) const
  43. {
  44. apply(scene::SVertexColorSetAlphaManipulator(alpha), buffer);
  45. }
  46. //! Sets the colors of all vertices to one color
  47. /** \param mesh Mesh on which the operation is performed.
  48. \param color New color. */
  49. void setVertexColors(IMesh* mesh, video::SColor color) const
  50. {
  51. apply(scene::SVertexColorSetManipulator(color), mesh);
  52. }
  53. //! Sets the colors of all vertices to one color
  54. /** \param buffer Meshbuffer on which the operation is performed.
  55. \param color New color. */
  56. void setVertexColors(IMeshBuffer* buffer, video::SColor color) const
  57. {
  58. apply(scene::SVertexColorSetManipulator(color), buffer);
  59. }
  60. //! Recalculates all normals of the mesh.
  61. /** \param mesh: Mesh on which the operation is performed.
  62. \param smooth: If the normals shall be smoothed.
  63. \param angleWeighted: If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision. */
  64. virtual void recalculateNormals(IMesh* mesh, bool smooth = false,
  65. bool angleWeighted = false) const=0;
  66. //! Recalculates all normals of the mesh buffer.
  67. /** \param buffer: Mesh buffer on which the operation is performed.
  68. \param smooth: If the normals shall be smoothed.
  69. \param angleWeighted: If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision. */
  70. virtual void recalculateNormals(IMeshBuffer* buffer,
  71. bool smooth = false, bool angleWeighted = false) const=0;
  72. //! Recalculates tangents, requires a tangent mesh
  73. /** \param mesh Mesh on which the operation is performed.
  74. \param recalculateNormals If the normals shall be recalculated, otherwise original normals of the mesh are used unchanged.
  75. \param smooth If the normals shall be smoothed.
  76. \param angleWeighted If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision.
  77. */
  78. virtual void recalculateTangents(IMesh* mesh,
  79. bool recalculateNormals=false, bool smooth=false,
  80. bool angleWeighted=false) const=0;
  81. //! Recalculates tangents, requires a tangent mesh buffer
  82. /** \param buffer Meshbuffer on which the operation is performed.
  83. \param recalculateNormals If the normals shall be recalculated, otherwise original normals of the buffer are used unchanged.
  84. \param smooth If the normals shall be smoothed.
  85. \param angleWeighted If the normals shall be smoothed in relation to their angles. More expensive, but also higher precision.
  86. */
  87. virtual void recalculateTangents(IMeshBuffer* buffer,
  88. bool recalculateNormals=false, bool smooth=false,
  89. bool angleWeighted=false) const=0;
  90. //! Scales the actual mesh, not a scene node.
  91. /** \param mesh Mesh on which the operation is performed.
  92. \param factor Scale factor for each axis. */
  93. void scale(IMesh* mesh, const core::vector3df& factor) const
  94. {
  95. apply(SVertexPositionScaleManipulator(factor), mesh, true);
  96. }
  97. //! Scales the actual meshbuffer, not a scene node.
  98. /** \param buffer Meshbuffer on which the operation is performed.
  99. \param factor Scale factor for each axis. */
  100. void scale(IMeshBuffer* buffer, const core::vector3df& factor) const
  101. {
  102. apply(SVertexPositionScaleManipulator(factor), buffer, true);
  103. }
  104. //! Scales the actual mesh, not a scene node.
  105. /** \deprecated Use scale() instead. This method may be removed by Irrlicht 1.9
  106. \param mesh Mesh on which the operation is performed.
  107. \param factor Scale factor for each axis. */
  108. _IRR_DEPRECATED_ void scaleMesh(IMesh* mesh, const core::vector3df& factor) const {return scale(mesh,factor);}
  109. //! Scale the texture coords of a mesh.
  110. /** \param mesh Mesh on which the operation is performed.
  111. \param factor Vector which defines the scale for each axis.
  112. \param level Number of texture coord, starting from 1. Support for level 2 exists for LightMap buffers. */
  113. void scaleTCoords(scene::IMesh* mesh, const core::vector2df& factor, u32 level=1) const
  114. {
  115. apply(SVertexTCoordsScaleManipulator(factor, level), mesh);
  116. }
  117. //! Scale the texture coords of a meshbuffer.
  118. /** \param buffer Meshbuffer on which the operation is performed.
  119. \param factor Vector which defines the scale for each axis.
  120. \param level Number of texture coord, starting from 1. Support for level 2 exists for LightMap buffers. */
  121. void scaleTCoords(scene::IMeshBuffer* buffer, const core::vector2df& factor, u32 level=1) const
  122. {
  123. apply(SVertexTCoordsScaleManipulator(factor, level), buffer);
  124. }
  125. //! Applies a transformation to a mesh
  126. /** \param mesh Mesh on which the operation is performed.
  127. \param m transformation matrix. */
  128. void transform(IMesh* mesh, const core::matrix4& m) const
  129. {
  130. apply(SVertexPositionTransformManipulator(m), mesh, true);
  131. }
  132. //! Applies a transformation to a meshbuffer
  133. /** \param buffer Meshbuffer on which the operation is performed.
  134. \param m transformation matrix. */
  135. void transform(IMeshBuffer* buffer, const core::matrix4& m) const
  136. {
  137. apply(SVertexPositionTransformManipulator(m), buffer, true);
  138. }
  139. //! Applies a transformation to a mesh
  140. /** \deprecated Use transform() instead. This method may be removed by Irrlicht 1.9
  141. \param mesh Mesh on which the operation is performed.
  142. \param m transformation matrix. */
  143. _IRR_DEPRECATED_ virtual void transformMesh(IMesh* mesh, const core::matrix4& m) const {return transform(mesh,m);}
  144. //! Creates a planar texture mapping on the mesh
  145. /** \param mesh: Mesh on which the operation is performed.
  146. \param resolution: resolution of the planar mapping. This is
  147. the value specifying which is the relation between world space
  148. and texture coordinate space. */
  149. virtual void makePlanarTextureMapping(IMesh* mesh, f32 resolution=0.001f) const=0;
  150. //! Creates a planar texture mapping on the meshbuffer
  151. /** \param meshbuffer: Buffer on which the operation is performed.
  152. \param resolution: resolution of the planar mapping. This is
  153. the value specifying which is the relation between world space
  154. and texture coordinate space. */
  155. virtual void makePlanarTextureMapping(scene::IMeshBuffer* meshbuffer, f32 resolution=0.001f) const=0;
  156. //! Creates a planar texture mapping on the buffer
  157. /** This method is currently implemented towards the LWO planar mapping. A more general biasing might be required.
  158. \param mesh Mesh on which the operation is performed.
  159. \param resolutionS Resolution of the planar mapping in horizontal direction. This is the ratio between object space and texture space.
  160. \param resolutionT Resolution of the planar mapping in vertical direction. This is the ratio between object space and texture space.
  161. \param axis The axis along which the texture is projected. The allowed values are 0 (X), 1(Y), and 2(Z).
  162. \param offset Vector added to the vertex positions (in object coordinates).
  163. */
  164. virtual void makePlanarTextureMapping(scene::IMesh* mesh,
  165. f32 resolutionS, f32 resolutionT,
  166. u8 axis, const core::vector3df& offset) const=0;
  167. //! Creates a planar texture mapping on the meshbuffer
  168. /** This method is currently implemented towards the LWO planar mapping. A more general biasing might be required.
  169. \param buffer Buffer on which the operation is performed.
  170. \param resolutionS Resolution of the planar mapping in horizontal direction. This is the ratio between object space and texture space.
  171. \param resolutionT Resolution of the planar mapping in vertical direction. This is the ratio between object space and texture space.
  172. \param axis The axis along which the texture is projected. The allowed values are 0 (X), 1(Y), and 2(Z).
  173. \param offset Vector added to the vertex positions (in object coordinates).
  174. */
  175. virtual void makePlanarTextureMapping(scene::IMeshBuffer* buffer,
  176. f32 resolutionS, f32 resolutionT,
  177. u8 axis, const core::vector3df& offset) const=0;
  178. //! Clones a static IMesh into a modifiable SMesh.
  179. /** All meshbuffers in the returned SMesh
  180. are of type SMeshBuffer or SMeshBufferLightMap.
  181. \param mesh Mesh to copy.
  182. \return Cloned mesh. If you no longer need the
  183. cloned mesh, you should call SMesh::drop(). See
  184. IReferenceCounted::drop() for more information. */
  185. virtual SMesh* createMeshCopy(IMesh* mesh) const = 0;
  186. //! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices.
  187. /** This is useful if you want to draw tangent space normal
  188. mapped geometry because it calculates the tangent and binormal
  189. data which is needed there.
  190. \param mesh Input mesh
  191. \param recalculateNormals The normals are recalculated if set,
  192. otherwise the original ones are kept. Note that keeping the
  193. normals may introduce inaccurate tangents if the normals are
  194. very different to those calculated from the faces.
  195. \param smooth The normals/tangents are smoothed across the
  196. meshbuffer's faces if this flag is set.
  197. \param angleWeighted Improved smoothing calculation used
  198. \param recalculateTangents Whether are actually calculated, or just the mesh with proper type is created.
  199. \return Mesh consisting only of S3DVertexTangents vertices. If
  200. you no longer need the cloned mesh, you should call
  201. IMesh::drop(). See IReferenceCounted::drop() for more
  202. information. */
  203. virtual IMesh* createMeshWithTangents(IMesh* mesh,
  204. bool recalculateNormals=false, bool smooth=false,
  205. bool angleWeighted=false, bool recalculateTangents=true) const=0;
  206. //! Creates a copy of the mesh, which will only consist of S3DVertex2TCoord vertices.
  207. /** \param mesh Input mesh
  208. \return Mesh consisting only of S3DVertex2TCoord vertices. If
  209. you no longer need the cloned mesh, you should call
  210. IMesh::drop(). See IReferenceCounted::drop() for more
  211. information. */
  212. virtual IMesh* createMeshWith2TCoords(IMesh* mesh) const = 0;
  213. //! Creates a copy of the mesh, which will only consist of S3DVertex vertices.
  214. /** \param mesh Input mesh
  215. \return Mesh consisting only of S3DVertex vertices. If
  216. you no longer need the cloned mesh, you should call
  217. IMesh::drop(). See IReferenceCounted::drop() for more
  218. information. */
  219. virtual IMesh* createMeshWith1TCoords(IMesh* mesh) const = 0;
  220. //! Creates a copy of a mesh with all vertices unwelded
  221. /** \param mesh Input mesh
  222. \return Mesh consisting only of unique faces. All vertices
  223. which were previously shared are now duplicated. If you no
  224. longer need the cloned mesh, you should call IMesh::drop(). See
  225. IReferenceCounted::drop() for more information. */
  226. virtual IMesh* createMeshUniquePrimitives(IMesh* mesh) const = 0;
  227. //! Creates a copy of a mesh with vertices welded
  228. /** \param mesh Input mesh
  229. \param tolerance The threshold for vertex comparisons.
  230. \return Mesh without redundant vertices. If you no longer need
  231. the cloned mesh, you should call IMesh::drop(). See
  232. IReferenceCounted::drop() for more information. */
  233. virtual IMesh* createMeshWelded(IMesh* mesh, f32 tolerance=core::ROUNDING_ERROR_f32) const = 0;
  234. //! Get amount of polygons in mesh.
  235. /** \param mesh Input mesh
  236. \return Number of polygons in mesh. */
  237. virtual s32 getPolyCount(IMesh* mesh) const = 0;
  238. //! Get amount of polygons in mesh.
  239. /** \param mesh Input mesh
  240. \return Number of polygons in mesh. */
  241. virtual s32 getPolyCount(IAnimatedMesh* mesh) const = 0;
  242. //! Create a new AnimatedMesh and adds the mesh to it
  243. /** \param mesh Input mesh
  244. \param type The type of the animated mesh to create.
  245. \return Newly created animated mesh with mesh as its only
  246. content. When you don't need the animated mesh anymore, you
  247. should call IAnimatedMesh::drop(). See
  248. IReferenceCounted::drop() for more information. */
  249. virtual IAnimatedMesh * createAnimatedMesh(IMesh* mesh,
  250. scene::E_ANIMATED_MESH_TYPE type = scene::EAMT_UNKNOWN) const = 0;
  251. //! Vertex cache optimization according to the Forsyth paper
  252. /** More information can be found at
  253. http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html
  254. The function is thread-safe (read: you can optimize several
  255. meshes in different threads).
  256. \param mesh Source mesh for the operation.
  257. \return A new mesh optimized for the vertex cache. */
  258. virtual IMesh* createForsythOptimizedMesh(const IMesh *mesh) const = 0;
  259. //! Apply a manipulator on the Meshbuffer
  260. /** \param func A functor defining the mesh manipulation.
  261. \param buffer The Meshbuffer to apply the manipulator to.
  262. \param boundingBoxUpdate Specifies if the bounding box should be updated during manipulation.
  263. \return True if the functor was successfully applied, else false. */
  264. template <typename Functor>
  265. bool apply(const Functor& func, IMeshBuffer* buffer, bool boundingBoxUpdate=false) const
  266. {
  267. return apply_(func, buffer, boundingBoxUpdate, func);
  268. }
  269. //! Apply a manipulator on the Mesh
  270. /** \param func A functor defining the mesh manipulation.
  271. \param mesh The Mesh to apply the manipulator to.
  272. \param boundingBoxUpdate Specifies if the bounding box should be updated during manipulation.
  273. \return True if the functor was successfully applied, else false. */
  274. template <typename Functor>
  275. bool apply(const Functor& func, IMesh* mesh, bool boundingBoxUpdate=false) const
  276. {
  277. if (!mesh)
  278. return true;
  279. bool result = true;
  280. core::aabbox3df bufferbox;
  281. for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
  282. {
  283. result &= apply(func, mesh->getMeshBuffer(i), boundingBoxUpdate);
  284. if (boundingBoxUpdate)
  285. {
  286. if (0==i)
  287. bufferbox.reset(mesh->getMeshBuffer(i)->getBoundingBox());
  288. else
  289. bufferbox.addInternalBox(mesh->getMeshBuffer(i)->getBoundingBox());
  290. }
  291. }
  292. if (boundingBoxUpdate)
  293. mesh->setBoundingBox(bufferbox);
  294. return result;
  295. }
  296. protected:
  297. //! Apply a manipulator based on the type of the functor
  298. /** \param func A functor defining the mesh manipulation.
  299. \param buffer The Meshbuffer to apply the manipulator to.
  300. \param boundingBoxUpdate Specifies if the bounding box should be updated during manipulation.
  301. \param typeTest Unused parameter, which handles the proper call selection based on the type of the Functor which is passed in two times.
  302. \return True if the functor was successfully applied, else false. */
  303. template <typename Functor>
  304. bool apply_(const Functor& func, IMeshBuffer* buffer, bool boundingBoxUpdate, const IVertexManipulator& typeTest) const
  305. {
  306. if (!buffer)
  307. return true;
  308. core::aabbox3df bufferbox;
  309. for (u32 i=0; i<buffer->getVertexCount(); ++i)
  310. {
  311. switch (buffer->getVertexType())
  312. {
  313. case video::EVT_STANDARD:
  314. {
  315. video::S3DVertex* verts = (video::S3DVertex*)buffer->getVertices();
  316. func(verts[i]);
  317. }
  318. break;
  319. case video::EVT_2TCOORDS:
  320. {
  321. video::S3DVertex2TCoords* verts = (video::S3DVertex2TCoords*)buffer->getVertices();
  322. func(verts[i]);
  323. }
  324. break;
  325. case video::EVT_TANGENTS:
  326. {
  327. video::S3DVertexTangents* verts = (video::S3DVertexTangents*)buffer->getVertices();
  328. func(verts[i]);
  329. }
  330. break;
  331. }
  332. if (boundingBoxUpdate)
  333. {
  334. if (0==i)
  335. bufferbox.reset(buffer->getPosition(0));
  336. else
  337. bufferbox.addInternalPoint(buffer->getPosition(i));
  338. }
  339. }
  340. if (boundingBoxUpdate)
  341. buffer->setBoundingBox(bufferbox);
  342. return true;
  343. }
  344. };
  345. } // end namespace scene
  346. } // end namespace irr
  347. #endif