CCPUMeshSurfaceEmitter.h 8.3 KB

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