CCPUMeshSurfaceEmitter.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /****************************************************************************
  2. Copyright (C) 2013 Henry van Merode. All rights reserved.
  3. Copyright (c) 2015-2017 Chukong Technologies Inc.
  4. http://www.cocos2d-x.org
  5. Permission is hereby granted, free of charge, to any person obtaining a copy
  6. of this software and associated documentation files (the "Software"), to deal
  7. in the Software without restriction, including without limitation the rights
  8. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. copies of the Software, and to permit persons to whom the Software is
  10. furnished to do so, subject to the following conditions:
  11. The above copyright notice and this permission notice shall be included in
  12. all copies or substantial portions of the Software.
  13. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. THE SOFTWARE.
  20. ****************************************************************************/
  21. #ifndef __CC_PU_PARTICLE_MESH_SURFACE_EMITTER_H__
  22. #define __CC_PU_PARTICLE_MESH_SURFACE_EMITTER_H__
  23. #include "extensions/Particle3D/PU/CCPUEmitter.h"
  24. NS_CC_BEGIN
  25. /** Definition of a Triangle
  26. */
  27. class PUTriangle
  28. {
  29. public:
  30. /** The struct is used to return both the position and the normal
  31. */
  32. struct PositionAndNormal
  33. {
  34. Vec3 position;
  35. Vec3 normal;
  36. };
  37. /** Public attributes **/
  38. float squareSurface;
  39. Vec3 surfaceNormal; // Normal of triangle v1-v2-v3
  40. Vec3 v1; // Vertex v1
  41. Vec3 v2; // Vertex v2
  42. Vec3 v3; // Vertex v3
  43. Vec3 vn1; // Normal of vertex v1
  44. Vec3 vn2; // Normal of vertex v2
  45. Vec3 vn3; // Normal of vertex v3
  46. Vec3 en1; // Normal of edge v1-v2
  47. Vec3 en2; // Normal of edge v2-v3
  48. Vec3 en3; // Normal of edge v3-v1
  49. /** Constructor **/
  50. PUTriangle(void){};
  51. /** Calculate the (square) surface of the triangle **/
  52. void calculateSquareSurface (void);
  53. /** Calculate the surface normal of the triangle **/
  54. void calculateSurfaceNormal (void);
  55. /** Calculate the edge normals of the 3 edges **/
  56. void calculateEdgeNormals (void);
  57. /** Determine a random position on this triangle **/
  58. const Vec3 getRandomTrianglePosition (void);
  59. /** Determine a random position including its normal on a one of the edges **/
  60. const PositionAndNormal getRandomEdgePositionAndNormal (void);
  61. /** Determine a random vertex including its normal of this triangle **/
  62. const PositionAndNormal getRandomVertexAndNormal (void);
  63. };
  64. /** Comparer used for sorting vector in ascending order
  65. */
  66. struct PUSortAscending
  67. {
  68. bool operator() (const PUTriangle& a, const PUTriangle& b)
  69. {
  70. return a.squareSurface < b.squareSurface;
  71. }
  72. };
  73. /** Comparer used for sorting vector in descending order
  74. */
  75. struct PUSortDescending
  76. {
  77. bool operator() (const PUTriangle& a, const PUTriangle& b)
  78. {
  79. return a.squareSurface > b.squareSurface;
  80. }
  81. };
  82. /** Define a template class for a vector of triangles.
  83. */
  84. typedef std::vector<PUTriangle> Triangles;
  85. /** Class that constructs mesh information of a given mesh name
  86. @remarks
  87. */
  88. class MeshInfo
  89. {
  90. public:
  91. /** Defining several methods to emit particles on the mesh surface
  92. @remarks
  93. Sometimes the difference is not always visible, for example if the mesh contains triangles with more or
  94. less the same size. Only in case a mesh contains both small and large triangles the difference between
  95. the various distribution methods is more obvious.
  96. */
  97. enum MeshSurfaceDistribution
  98. {
  99. MSD_HOMOGENEOUS, // Distribute particles homogeneous (random) on the mesh surface
  100. MSD_HETEROGENEOUS_1, // Distribute more particles on the smaller faces
  101. MSD_HETEROGENEOUS_2, // Same as above, but now more particles are emitting from the larger faces
  102. MSD_VERTEX, // Particles only emit from the vertices
  103. MSD_EDGE // Particles emit random on the edges
  104. };
  105. /** Constructor **/
  106. MeshInfo (const std::string& meshName,
  107. const MeshSurfaceDistribution distribution = MSD_HOMOGENEOUS,
  108. const Quaternion& orientation = Quaternion(),
  109. const Vec3& scale = Vec3::ZERO);
  110. /** Destructor **/
  111. ~MeshInfo (void);
  112. /** Generate a random number. The high argument determines that numbers are
  113. returned between [0..high] **/
  114. float getGaussianRandom (float high, float cutoff = 4);
  115. ///** Retrieve vertex info **/
  116. //void getMeshInformation(Ogre::MeshPtr mesh,
  117. // const Vec3& position = Vec3::ZERO,
  118. // const Quaternion& orient = Quaternion(),
  119. // const Vec3& scale = Vec3::ONE);
  120. /** Get a triangle based on the index. */
  121. const PUTriangle& getTriangle (size_t triangleIndex);
  122. /** Get a random triangle (index) from the mesh. */
  123. size_t getRandomTriangleIndex();
  124. /** Get triangle number */
  125. size_t getTriangleCount() const { return _triangles.size(); }
  126. /** Returns both a random point on a given triangle and its normal vector.
  127. How the random point and the normal are determined depends on the distribution type.
  128. **/
  129. const PUTriangle::PositionAndNormal getRandomPositionAndNormal (const size_t triangleIndex);
  130. protected:
  131. Triangles _triangles;
  132. MeshSurfaceDistribution mDistribution;
  133. };
  134. /** The MeshSurfaceEmitter is a ParticleEmitter that emits particles on the surface of a mesh.
  135. @remarks
  136. There are several ways of emitting it on the surface, from the vertices, edges and faces of a mesh.
  137. It is also possible to define whether more particles emit on larger faces.
  138. */
  139. class CC_DLL PUMeshSurfaceEmitter : public PUEmitter
  140. {
  141. public:
  142. // Constants
  143. static const Vec3 DEFAULT_SCALE;
  144. static const MeshInfo::MeshSurfaceDistribution DEFAULT_DISTRIBUTION;
  145. static PUMeshSurfaceEmitter* create();
  146. /** Returns the mesh name.
  147. */
  148. const std::string& getMeshName(void) const;
  149. /** Sets the mesh name.
  150. */
  151. void setMeshName(const std::string& meshName, bool doBuild = true);
  152. /** Returns true if normals are used for the particle direction.
  153. */
  154. bool useNormals (void) const;
  155. /** Set indication whether normals are used for the particle direction.
  156. */
  157. void setUseNormals (bool useNormals);
  158. /** Returns the type op distribution.
  159. @remarks
  160. There are several ways to emit particles on the surface of a mesh. This attribute indicates
  161. the type of distribution on the surface.
  162. */
  163. MeshInfo::MeshSurfaceDistribution getDistribution() const;
  164. /** Set the type of particle distribution on the surface of a mesh.
  165. */
  166. void setDistribution(MeshInfo::MeshSurfaceDistribution distribution);
  167. /** Returns the scale of the mesh.
  168. */
  169. const Vec3& getScale (void) const;
  170. /** Set the scale of the mesh.
  171. @remarks
  172. This options makes it possible to scale the mesh independently from the particle system scale as a whole.
  173. */
  174. void setScale (const Vec3& scale);
  175. /** Build all the data needed to generate the particles.
  176. */
  177. void build(void);
  178. /** Build the data if the mesh name has been set.
  179. */
  180. virtual void prepare() override;
  181. /** Reverse it.
  182. */
  183. virtual void unPrepare() override;
  184. /** Determine a particle position on the mesh surface.
  185. */
  186. virtual void initParticlePosition(PUParticle3D* particle) override;
  187. /** See ParticleEmitter.
  188. */
  189. virtual unsigned short calculateRequestedParticles(float timeElapsed) override;
  190. /** Determine the particle direction.
  191. */
  192. virtual void initParticleDirection(PUParticle3D* particle) override;
  193. virtual PUMeshSurfaceEmitter* clone() override;
  194. virtual void copyAttributesTo (PUEmitter* emitter) override;
  195. CC_CONSTRUCTOR_ACCESS:
  196. PUMeshSurfaceEmitter(void);
  197. virtual ~PUMeshSurfaceEmitter(void);
  198. protected:
  199. std::string _meshName;
  200. Quaternion _orientation;
  201. Vec3 _scale;
  202. MeshInfo::MeshSurfaceDistribution _distribution;
  203. MeshInfo* _meshInfo;
  204. size_t _triangleIndex;
  205. bool _directionSet;
  206. };
  207. NS_CC_END
  208. #endif