2019-11-23 20:27:39 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (C) 2013 Henry van Merode. All rights reserved.
|
|
|
|
Copyright (c) 2015-2016 Chukong Technologies Inc.
|
|
|
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
http://www.cocos2d-x.org
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifndef __CC_PU_PARTICLE_MESH_SURFACE_EMITTER_H__
|
|
|
|
#define __CC_PU_PARTICLE_MESH_SURFACE_EMITTER_H__
|
|
|
|
|
|
|
|
#include "extensions/Particle3D/PU/CCPUEmitter.h"
|
|
|
|
|
|
|
|
NS_CC_BEGIN
|
|
|
|
|
|
|
|
/** Definition of a Triangle
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
2019-11-23 20:27:39 +08:00
|
|
|
class PUTriangle
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/** The struct is used to return both the position and the normal
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
2019-11-23 20:27:39 +08:00
|
|
|
struct PositionAndNormal
|
|
|
|
{
|
|
|
|
Vec3 position;
|
|
|
|
Vec3 normal;
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Public attributes **/
|
|
|
|
float squareSurface;
|
2021-12-25 10:04:45 +08:00
|
|
|
Vec3 surfaceNormal; // Normal of triangle v1-v2-v3
|
|
|
|
Vec3 v1; // Vertex v1
|
|
|
|
Vec3 v2; // Vertex v2
|
|
|
|
Vec3 v3; // Vertex v3
|
|
|
|
Vec3 vn1; // Normal of vertex v1
|
|
|
|
Vec3 vn2; // Normal of vertex v2
|
|
|
|
Vec3 vn3; // Normal of vertex v3
|
|
|
|
Vec3 en1; // Normal of edge v1-v2
|
|
|
|
Vec3 en2; // Normal of edge v2-v3
|
|
|
|
Vec3 en3; // Normal of edge v3-v1
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
/** Constructor **/
|
|
|
|
PUTriangle(){};
|
|
|
|
|
|
|
|
/** Calculate the (square) surface of the triangle **/
|
2021-12-25 10:04:45 +08:00
|
|
|
void calculateSquareSurface();
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
/** Calculate the surface normal of the triangle **/
|
2021-12-25 10:04:45 +08:00
|
|
|
void calculateSurfaceNormal();
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
/** Calculate the edge normals of the 3 edges **/
|
2021-12-25 10:04:45 +08:00
|
|
|
void calculateEdgeNormals();
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
/** Determine a random position on this triangle **/
|
2021-12-25 10:04:45 +08:00
|
|
|
const Vec3 getRandomTrianglePosition();
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
/** Determine a random position including its normal on a one of the edges **/
|
2021-12-25 10:04:45 +08:00
|
|
|
const PositionAndNormal getRandomEdgePositionAndNormal();
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
/** Determine a random vertex including its normal of this triangle **/
|
2021-12-25 10:04:45 +08:00
|
|
|
const PositionAndNormal getRandomVertexAndNormal();
|
2019-11-23 20:27:39 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/** Comparer used for sorting vector in ascending order
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
2019-11-23 20:27:39 +08:00
|
|
|
struct PUSortAscending
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
bool operator()(const PUTriangle& a, const PUTriangle& b) { return a.squareSurface < b.squareSurface; }
|
2019-11-23 20:27:39 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/** Comparer used for sorting vector in descending order
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
2019-11-23 20:27:39 +08:00
|
|
|
struct PUSortDescending
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
bool operator()(const PUTriangle& a, const PUTriangle& b) { return a.squareSurface > b.squareSurface; }
|
2019-11-23 20:27:39 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/** Define a template class for a vector of triangles.
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
2019-11-23 20:27:39 +08:00
|
|
|
typedef std::vector<PUTriangle> Triangles;
|
|
|
|
|
|
|
|
/** Class that constructs mesh information of a given mesh name
|
|
|
|
@remarks
|
|
|
|
*/
|
|
|
|
class MeshInfo
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/** Defining several methods to emit particles on the mesh surface
|
|
|
|
@remarks
|
|
|
|
Sometimes the difference is not always visible, for example if the mesh contains triangles with more or
|
|
|
|
less the same size. Only in case a mesh contains both small and large triangles the difference between
|
|
|
|
the various distribution methods is more obvious.
|
|
|
|
*/
|
|
|
|
enum MeshSurfaceDistribution
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
|
|
|
MSD_HOMOGENEOUS, // Distribute particles homogeneous (random) on the mesh surface
|
|
|
|
MSD_HETEROGENEOUS_1, // Distribute more particles on the smaller faces
|
|
|
|
MSD_HETEROGENEOUS_2, // Same as above, but now more particles are emitting from the larger faces
|
|
|
|
MSD_VERTEX, // Particles only emit from the vertices
|
|
|
|
MSD_EDGE // Particles emit random on the edges
|
2019-11-23 20:27:39 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/** Constructor **/
|
2021-12-31 12:12:40 +08:00
|
|
|
MeshInfo(std::string_view meshName,
|
2021-12-25 10:04:45 +08:00
|
|
|
const MeshSurfaceDistribution distribution = MSD_HOMOGENEOUS,
|
|
|
|
const Quaternion& orientation = Quaternion(),
|
|
|
|
const Vec3& scale = Vec3::ZERO);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
/** Destructor **/
|
2021-12-25 10:04:45 +08:00
|
|
|
~MeshInfo();
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
/** Generate a random number. The high argument determines that numbers are
|
2019-11-23 20:27:39 +08:00
|
|
|
returned between [0..high] **/
|
2021-12-25 10:04:45 +08:00
|
|
|
float getGaussianRandom(float high, float cutoff = 4);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
///** Retrieve vertex info **/
|
2021-12-25 10:04:45 +08:00
|
|
|
// void getMeshInformation(Ogre::MeshPtr mesh,
|
2019-11-23 20:27:39 +08:00
|
|
|
// const Vec3& position = Vec3::ZERO,
|
|
|
|
// const Quaternion& orient = Quaternion(),
|
|
|
|
// const Vec3& scale = Vec3::ONE);
|
|
|
|
|
|
|
|
/** Get a triangle based on the index. */
|
2021-12-25 10:04:45 +08:00
|
|
|
const PUTriangle& getTriangle(size_t triangleIndex);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
/** Get a random triangle (index) from the mesh. */
|
|
|
|
size_t getRandomTriangleIndex();
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
/** Get triangle number */
|
|
|
|
size_t getTriangleCount() const { return _triangles.size(); }
|
|
|
|
|
|
|
|
/** Returns both a random point on a given triangle and its normal vector.
|
|
|
|
How the random point and the normal are determined depends on the distribution type.
|
|
|
|
**/
|
2021-12-25 10:04:45 +08:00
|
|
|
const PUTriangle::PositionAndNormal getRandomPositionAndNormal(const size_t triangleIndex);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
protected:
|
|
|
|
Triangles _triangles;
|
|
|
|
MeshSurfaceDistribution mDistribution;
|
|
|
|
};
|
|
|
|
|
|
|
|
/** The MeshSurfaceEmitter is a ParticleEmitter that emits particles on the surface of a mesh.
|
|
|
|
@remarks
|
|
|
|
There are several ways of emitting it on the surface, from the vertices, edges and faces of a mesh.
|
|
|
|
It is also possible to define whether more particles emit on larger faces.
|
|
|
|
*/
|
|
|
|
|
2020-10-07 00:15:11 +08:00
|
|
|
class CC_EX_DLL PUMeshSurfaceEmitter : public PUEmitter
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
// Constants
|
|
|
|
static const Vec3 DEFAULT_SCALE;
|
|
|
|
static const MeshInfo::MeshSurfaceDistribution DEFAULT_DISTRIBUTION;
|
|
|
|
|
|
|
|
static PUMeshSurfaceEmitter* create();
|
|
|
|
|
|
|
|
/** Returns the mesh name.
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
2021-12-31 12:12:40 +08:00
|
|
|
std::string_view getMeshName() const;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
/** Sets the mesh name.
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
2021-12-31 12:12:40 +08:00
|
|
|
void setMeshName(std::string_view meshName, bool doBuild = true);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
/** Returns true if normals are used for the particle direction.
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
|
|
|
bool useNormals() const;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
/** Set indication whether normals are used for the particle direction.
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
|
|
|
void setUseNormals(bool useNormals);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
/** Returns the type op distribution.
|
|
|
|
@remarks
|
|
|
|
There are several ways to emit particles on the surface of a mesh. This attribute indicates
|
|
|
|
the type of distribution on the surface.
|
|
|
|
*/
|
|
|
|
MeshInfo::MeshSurfaceDistribution getDistribution() const;
|
|
|
|
|
|
|
|
/** Set the type of particle distribution on the surface of a mesh.
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
2019-11-23 20:27:39 +08:00
|
|
|
void setDistribution(MeshInfo::MeshSurfaceDistribution distribution);
|
|
|
|
|
|
|
|
/** Returns the scale of the mesh.
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
|
|
|
const Vec3& getScale() const;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
/** Set the scale of the mesh.
|
|
|
|
@remarks
|
|
|
|
This options makes it possible to scale the mesh independently from the particle system scale as a whole.
|
|
|
|
*/
|
2021-12-25 10:04:45 +08:00
|
|
|
void setScale(const Vec3& scale);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
/** Build all the data needed to generate the particles.
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
2019-11-23 20:27:39 +08:00
|
|
|
void build();
|
|
|
|
|
|
|
|
/** Build the data if the mesh name has been set.
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
2019-11-23 20:27:39 +08:00
|
|
|
virtual void prepare() override;
|
|
|
|
|
|
|
|
/** Reverse it.
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
2019-11-23 20:27:39 +08:00
|
|
|
virtual void unPrepare() override;
|
|
|
|
|
|
|
|
/** Determine a particle position on the mesh surface.
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
2019-11-23 20:27:39 +08:00
|
|
|
virtual void initParticlePosition(PUParticle3D* particle) override;
|
|
|
|
|
|
|
|
/** See ParticleEmitter.
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
2019-11-23 20:27:39 +08:00
|
|
|
virtual unsigned short calculateRequestedParticles(float timeElapsed) override;
|
|
|
|
|
|
|
|
/** Determine the particle direction.
|
2021-12-25 10:04:45 +08:00
|
|
|
*/
|
2019-11-23 20:27:39 +08:00
|
|
|
virtual void initParticleDirection(PUParticle3D* particle) override;
|
|
|
|
|
|
|
|
virtual PUMeshSurfaceEmitter* clone() override;
|
2021-12-25 10:04:45 +08:00
|
|
|
virtual void copyAttributesTo(PUEmitter* emitter) override;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
CC_CONSTRUCTOR_ACCESS : PUMeshSurfaceEmitter();
|
2019-11-23 20:27:39 +08:00
|
|
|
virtual ~PUMeshSurfaceEmitter();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
std::string _meshName;
|
|
|
|
Quaternion _orientation;
|
|
|
|
Vec3 _scale;
|
|
|
|
MeshInfo::MeshSurfaceDistribution _distribution;
|
|
|
|
MeshInfo* _meshInfo;
|
|
|
|
size_t _triangleIndex;
|
|
|
|
bool _directionSet;
|
|
|
|
};
|
|
|
|
|
|
|
|
NS_CC_END
|
|
|
|
|
|
|
|
#endif
|