IMeshManipulator.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  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. \param normalsUpdate When 0 - don't update normals.
  129. When 1 - update normals with inverse transposed of the transformation matrix
  130. */
  131. void transform(IMesh* mesh, const core::matrix4& m, u32 normalsUpdate = 0) const
  132. {
  133. apply(SVertexPositionTransformManipulator(m), mesh, true);
  134. if ( normalsUpdate == 1 )
  135. {
  136. core::matrix4 invT;
  137. if ( m.getInverse(invT) )
  138. {
  139. invT = invT.getTransposed();
  140. apply(SVertexNormalTransformManipulator(invT), mesh, false);
  141. }
  142. }
  143. }
  144. //! Applies a transformation to a meshbuffer
  145. /** \param buffer Meshbuffer on which the operation is performed.
  146. \param m transformation matrix.
  147. \param normalsUpdate When 0 - don't update normals.
  148. When 1 - update normals with inverse transposed of the transformation matrix
  149. */
  150. void transform(IMeshBuffer* buffer, const core::matrix4& m, u32 normalsUpdate = 0) const
  151. {
  152. apply(SVertexPositionTransformManipulator(m), buffer, true);
  153. if ( normalsUpdate == 1 )
  154. {
  155. core::matrix4 invT;
  156. if ( m.getInverse(invT) )
  157. {
  158. invT = invT.getTransposed();
  159. apply(SVertexNormalTransformManipulator(invT), buffer, false);
  160. }
  161. }
  162. }
  163. //! Applies a transformation to a mesh
  164. /** \deprecated Use transform() instead. This method may be removed by Irrlicht 1.9
  165. \param mesh Mesh on which the operation is performed.
  166. \param m transformation matrix. */
  167. _IRR_DEPRECATED_ virtual void transformMesh(IMesh* mesh, const core::matrix4& m) const {return transform(mesh,m);}
  168. //! Creates a planar texture mapping on the mesh
  169. /** \param mesh: Mesh on which the operation is performed.
  170. \param resolution: resolution of the planar mapping. This is
  171. the value specifying which is the relation between world space
  172. and texture coordinate space. */
  173. virtual void makePlanarTextureMapping(IMesh* mesh, f32 resolution=0.001f) const=0;
  174. //! Creates a planar texture mapping on the meshbuffer
  175. /** \param meshbuffer: Buffer on which the operation is performed.
  176. \param resolution: resolution of the planar mapping. This is
  177. the value specifying which is the relation between world space
  178. and texture coordinate space. */
  179. virtual void makePlanarTextureMapping(scene::IMeshBuffer* meshbuffer, f32 resolution=0.001f) const=0;
  180. //! Creates a planar texture mapping on the buffer
  181. /** This method is currently implemented towards the LWO planar mapping. A more general biasing might be required.
  182. \param mesh Mesh on which the operation is performed.
  183. \param resolutionS Resolution of the planar mapping in horizontal direction. This is the ratio between object space and texture space.
  184. \param resolutionT Resolution of the planar mapping in vertical direction. This is the ratio between object space and texture space.
  185. \param axis The axis along which the texture is projected. The allowed values are 0 (X), 1(Y), and 2(Z).
  186. \param offset Vector added to the vertex positions (in object coordinates).
  187. */
  188. virtual void makePlanarTextureMapping(scene::IMesh* mesh,
  189. f32 resolutionS, f32 resolutionT,
  190. u8 axis, const core::vector3df& offset) const=0;
  191. //! Creates a planar texture mapping on the meshbuffer
  192. /** This method is currently implemented towards the LWO planar mapping. A more general biasing might be required.
  193. \param buffer Buffer on which the operation is performed.
  194. \param resolutionS Resolution of the planar mapping in horizontal direction. This is the ratio between object space and texture space.
  195. \param resolutionT Resolution of the planar mapping in vertical direction. This is the ratio between object space and texture space.
  196. \param axis The axis along which the texture is projected. The allowed values are 0 (X), 1(Y), and 2(Z).
  197. \param offset Vector added to the vertex positions (in object coordinates).
  198. */
  199. virtual void makePlanarTextureMapping(scene::IMeshBuffer* buffer,
  200. f32 resolutionS, f32 resolutionT,
  201. u8 axis, const core::vector3df& offset) const=0;
  202. //! Clones a static IMesh into a modifiable SMesh.
  203. /** All meshbuffers in the returned SMesh
  204. are of type SMeshBuffer or SMeshBufferLightMap.
  205. \param mesh Mesh to copy.
  206. \return Cloned mesh. If you no longer need the
  207. cloned mesh, you should call SMesh::drop(). See
  208. IReferenceCounted::drop() for more information. */
  209. virtual SMesh* createMeshCopy(IMesh* mesh) const = 0;
  210. //! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices.
  211. /** This is useful if you want to draw tangent space normal
  212. mapped geometry because it calculates the tangent and binormal
  213. data which is needed there.
  214. \param mesh Input mesh
  215. \param recalculateNormals The normals are recalculated if set,
  216. otherwise the original ones are kept. Note that keeping the
  217. normals may introduce inaccurate tangents if the normals are
  218. very different to those calculated from the faces.
  219. \param smooth The normals/tangents are smoothed across the
  220. meshbuffer's faces if this flag is set.
  221. \param angleWeighted Improved smoothing calculation used
  222. \param recalculateTangents Whether are actually calculated, or just the mesh with proper type is created.
  223. \return Mesh consisting only of S3DVertexTangents vertices. If
  224. you no longer need the cloned mesh, you should call
  225. IMesh::drop(). See IReferenceCounted::drop() for more
  226. information. */
  227. virtual IMesh* createMeshWithTangents(IMesh* mesh,
  228. bool recalculateNormals=false, bool smooth=false,
  229. bool angleWeighted=false, bool recalculateTangents=true) const=0;
  230. //! Creates a copy of the mesh, which will only consist of S3DVertex2TCoord vertices.
  231. /** \param mesh Input mesh
  232. \return Mesh consisting only of S3DVertex2TCoord vertices. If
  233. you no longer need the cloned mesh, you should call
  234. IMesh::drop(). See IReferenceCounted::drop() for more
  235. information. */
  236. virtual IMesh* createMeshWith2TCoords(IMesh* mesh) const = 0;
  237. //! Creates a copy of the mesh, which will only consist of S3DVertex vertices.
  238. /** \param mesh Input mesh
  239. \return Mesh consisting only of S3DVertex vertices. If
  240. you no longer need the cloned mesh, you should call
  241. IMesh::drop(). See IReferenceCounted::drop() for more
  242. information. */
  243. virtual IMesh* createMeshWith1TCoords(IMesh* mesh) const = 0;
  244. //! Creates a copy of a mesh with all vertices unwelded
  245. /** \param mesh Input mesh
  246. \return Mesh consisting only of unique faces. All vertices
  247. which were previously shared are now duplicated. If you no
  248. longer need the cloned mesh, you should call IMesh::drop(). See
  249. IReferenceCounted::drop() for more information. */
  250. virtual IMesh* createMeshUniquePrimitives(IMesh* mesh) const = 0;
  251. //! Creates a copy of a mesh with vertices welded
  252. /** \param mesh Input mesh
  253. \param tolerance The threshold for vertex comparisons.
  254. \return Mesh without redundant vertices. If you no longer need
  255. the cloned mesh, you should call IMesh::drop(). See
  256. IReferenceCounted::drop() for more information. */
  257. virtual IMesh* createMeshWelded(IMesh* mesh, f32 tolerance=core::ROUNDING_ERROR_f32) const = 0;
  258. //! Get amount of polygons in mesh.
  259. /** \param mesh Input mesh
  260. \return Number of polygons in mesh. */
  261. virtual s32 getPolyCount(IMesh* mesh) const = 0;
  262. //! Get amount of polygons in mesh.
  263. /** \param mesh Input mesh
  264. \return Number of polygons in mesh. */
  265. virtual s32 getPolyCount(IAnimatedMesh* mesh) const = 0;
  266. //! Create a new AnimatedMesh and adds the mesh to it
  267. /** \param mesh Input mesh
  268. \param type The type of the animated mesh to create.
  269. \return Newly created animated mesh with mesh as its only
  270. content. When you don't need the animated mesh anymore, you
  271. should call IAnimatedMesh::drop(). See
  272. IReferenceCounted::drop() for more information. */
  273. virtual IAnimatedMesh * createAnimatedMesh(IMesh* mesh,
  274. scene::E_ANIMATED_MESH_TYPE type = scene::EAMT_UNKNOWN) const = 0;
  275. //! Vertex cache optimization according to the Forsyth paper
  276. /** More information can be found at
  277. http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html
  278. The function is thread-safe (read: you can optimize several
  279. meshes in different threads).
  280. \param mesh Source mesh for the operation.
  281. \return A new mesh optimized for the vertex cache. */
  282. virtual IMesh* createForsythOptimizedMesh(const IMesh *mesh) const = 0;
  283. //! Optimize the mesh with an algorithm tuned for heightmaps.
  284. /**
  285. This differs from usual simplification methods in two ways:
  286. - it's intended to be lossless
  287. - it has special care for the borders, which are useful with heightmap tiles
  288. This function is thread-safe. Remember to weld afterwards - this
  289. function only moves vertices, it does not weld.
  290. \param mesh Mesh to operate on.
  291. */
  292. virtual void heightmapOptimizeMesh(IMesh * const mesh, const f32 tolerance = core::ROUNDING_ERROR_f32) const = 0;
  293. //! Optimize the meshbuffer with an algorithm tuned for heightmaps.
  294. /**
  295. This differs from usual simplification methods in two ways:
  296. - it's intended to be lossless
  297. - it has special care for the borders, which are useful with heightmap tiles
  298. This function is thread-safe. Remember to weld afterward - this
  299. function only moves vertices, it does not weld.
  300. \param mb Meshbuffer to operate on.
  301. */
  302. virtual void heightmapOptimizeMesh(IMeshBuffer * const mb, const f32 tolerance = core::ROUNDING_ERROR_f32) const = 0;
  303. //! Apply a manipulator on the Meshbuffer
  304. /** \param func A functor defining the mesh manipulation.
  305. \param buffer The Meshbuffer to apply the manipulator to.
  306. \param boundingBoxUpdate Specifies if the bounding box should be updated during manipulation.
  307. \return True if the functor was successfully applied, else false. */
  308. template <typename Functor>
  309. bool apply(const Functor& func, IMeshBuffer* buffer, bool boundingBoxUpdate=false) const
  310. {
  311. return apply_(func, buffer, boundingBoxUpdate, func);
  312. }
  313. //! Apply a manipulator on the Mesh
  314. /** \param func A functor defining the mesh manipulation.
  315. \param mesh The Mesh to apply the manipulator to.
  316. \param boundingBoxUpdate Specifies if the bounding box should be updated during manipulation.
  317. \return True if the functor was successfully applied, else false. */
  318. template <typename Functor>
  319. bool apply(const Functor& func, IMesh* mesh, bool boundingBoxUpdate=false) const
  320. {
  321. if (!mesh)
  322. return true;
  323. bool result = true;
  324. core::aabbox3df bufferbox;
  325. for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
  326. {
  327. result &= apply(func, mesh->getMeshBuffer(i), boundingBoxUpdate);
  328. if (boundingBoxUpdate)
  329. {
  330. if (0==i)
  331. bufferbox.reset(mesh->getMeshBuffer(i)->getBoundingBox());
  332. else
  333. bufferbox.addInternalBox(mesh->getMeshBuffer(i)->getBoundingBox());
  334. }
  335. }
  336. if (boundingBoxUpdate)
  337. mesh->setBoundingBox(bufferbox);
  338. return result;
  339. }
  340. protected:
  341. //! Apply a manipulator based on the type of the functor
  342. /** \param func A functor defining the mesh manipulation.
  343. \param buffer The Meshbuffer to apply the manipulator to.
  344. \param boundingBoxUpdate Specifies if the bounding box should be updated during manipulation.
  345. \param typeTest Unused parameter, which handles the proper call selection based on the type of the Functor which is passed in two times.
  346. \return True if the functor was successfully applied, else false. */
  347. template <typename Functor>
  348. bool apply_(const Functor& func, IMeshBuffer* buffer, bool boundingBoxUpdate, const IVertexManipulator& typeTest) const
  349. {
  350. if (!buffer)
  351. return true;
  352. core::aabbox3df bufferbox;
  353. for (u32 i=0; i<buffer->getVertexCount(); ++i)
  354. {
  355. switch (buffer->getVertexType())
  356. {
  357. case video::EVT_STANDARD:
  358. {
  359. video::S3DVertex* verts = (video::S3DVertex*)buffer->getVertices();
  360. func(verts[i]);
  361. }
  362. break;
  363. case video::EVT_2TCOORDS:
  364. {
  365. video::S3DVertex2TCoords* verts = (video::S3DVertex2TCoords*)buffer->getVertices();
  366. func(verts[i]);
  367. }
  368. break;
  369. case video::EVT_TANGENTS:
  370. {
  371. video::S3DVertexTangents* verts = (video::S3DVertexTangents*)buffer->getVertices();
  372. func(verts[i]);
  373. }
  374. break;
  375. }
  376. if (boundingBoxUpdate)
  377. {
  378. if (0==i)
  379. bufferbox.reset(buffer->getPosition(0));
  380. else
  381. bufferbox.addInternalPoint(buffer->getPosition(i));
  382. }
  383. }
  384. if (boundingBoxUpdate)
  385. buffer->setBoundingBox(bufferbox);
  386. return true;
  387. }
  388. };
  389. } // end namespace scene
  390. } // end namespace irr
  391. #endif