225 lines
4.3 KiB
C++
225 lines
4.3 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#ifndef __NEMITTER__
|
|
#define __NEMITTER__
|
|
|
|
|
|
#include "core/item.h"
|
|
#include "core/renderable.h"
|
|
#include "geometry/curve.h"
|
|
#include "sort/sort.h"
|
|
|
|
|
|
namespace GS {
|
|
namespace Core {
|
|
|
|
/*!
|
|
@short Particle class.
|
|
@author Emmanuel Julien (ejulien@gsworks.fr)
|
|
*/
|
|
struct Particle
|
|
{
|
|
Time time;
|
|
|
|
Vector4 position,
|
|
velocity;
|
|
|
|
float size;
|
|
float angle;
|
|
Color color;
|
|
|
|
/*!
|
|
@name Parameter scaler.
|
|
@{
|
|
*/
|
|
float opacity_scale,
|
|
size_scale;
|
|
/// @}
|
|
|
|
/// Is the particle alive.
|
|
bool IsAlive() const { return time.toSec() < 0 ? false : true; }
|
|
|
|
Particle()
|
|
{ opacity_scale = 1; }
|
|
};
|
|
|
|
/*
|
|
@short Particle model.
|
|
Models the particle attributes over its lifetime.
|
|
@author Emmanuel Julien (ejulien@gsworks.fr)
|
|
*/
|
|
struct ParticleModel : public SharedObject
|
|
{
|
|
struct RenderData
|
|
{
|
|
Render::sMaterial material;
|
|
};
|
|
|
|
String name;
|
|
String material;
|
|
|
|
Time time_to_live; ///< Time to live.
|
|
float damping; ///< Particle velocity damping.
|
|
Vector4 gravity; ///< Particle gravity.
|
|
|
|
Curve angle_curve,
|
|
size_curve;
|
|
|
|
Curve red_curve,
|
|
green_curve,
|
|
blue_curve,
|
|
opacity_curve;
|
|
|
|
AutoPtr <RenderData> render_data;
|
|
|
|
/// Setup render data.
|
|
void RenderSetup(ResourceFactories * = 0);
|
|
|
|
/*!
|
|
@short Set template color.
|
|
This function does not clear the color and opacity curves.
|
|
It only set their default value member, curves with keys will animate
|
|
as usual.
|
|
*/
|
|
void SetColor(const Color &);
|
|
/// Add color curve point.
|
|
void AddColorPoint(const Time &t, const Color &);
|
|
|
|
/*!
|
|
@name Serialization.
|
|
@{
|
|
*/
|
|
bool FromMetaTag(NML::Tag &);
|
|
NML::Tag *AsMetaTag() const;
|
|
/// @}
|
|
|
|
ParticleModel();
|
|
};
|
|
|
|
typedef SharedPtr <ParticleModel> sParticleModel;
|
|
|
|
/*!
|
|
@short Emitter class.
|
|
Note: Emitters emit particle along the Z axis.
|
|
@author Emmanuel Julien (ejulien@gsworks.fr)
|
|
*/
|
|
class Emitter : public Item, public Renderable
|
|
{
|
|
public:
|
|
|
|
struct RenderData
|
|
{
|
|
sParticleModel particle_model;
|
|
};
|
|
|
|
enum Model
|
|
{
|
|
Model_Spray = 0
|
|
};
|
|
|
|
/*!
|
|
@name Emitter model.
|
|
@{
|
|
*/
|
|
protected:
|
|
|
|
Model model;
|
|
|
|
public:
|
|
|
|
/*!
|
|
@name Renderable interface.
|
|
@{
|
|
*/
|
|
/// Compute the renderable minmax.
|
|
virtual void ComputeRenderableMinMax(MinMax &mm) { ComputeMinMax(mm); }
|
|
/// Get the renderable primitive list for this renderable.
|
|
virtual uint GetRenderablePrimitiveList(const Camera &view, const Camera &default_view, Stack <Render::Primitive *> &list, Renderable::Context context = Renderable::Context_Default, bool cull = true);
|
|
/// @}
|
|
|
|
uint pool_size; ///< Particle pool size.
|
|
float birth_rate; ///< Rate in particle/second.
|
|
float birth_speed_min,
|
|
birth_speed_max; ///< Speed in m.s.
|
|
float spray_angle;
|
|
|
|
/*!
|
|
@name Model scale.
|
|
@{
|
|
*/
|
|
float birth_rate_scale,
|
|
birth_opacity_scale,
|
|
birth_speed_scale,
|
|
birth_size_scale;
|
|
/// @}
|
|
|
|
String particle_model;
|
|
|
|
/// Model particle.
|
|
void ModelParticle(Particle &, const Item &, const Time &emitter_time);
|
|
|
|
/// Get emitter model.
|
|
Model GetModel() const { return model; }
|
|
/// Set as spray emitter.
|
|
void SetSprayModel(float angle = Units::Deg(45.f));
|
|
/// @}
|
|
|
|
AutoPtr <RenderData> render_data;
|
|
|
|
protected:
|
|
|
|
Array <Particle> particle_pool;
|
|
|
|
uint alive_count;
|
|
bool is_seen;
|
|
|
|
Time time;
|
|
Time birth_time;
|
|
|
|
Array <Sort <float, uint>::Entry> sort_array;
|
|
|
|
public:
|
|
|
|
void RenderSetup(ResourceFactories * = 0);
|
|
|
|
bool Setup();
|
|
void Update(const Time &dt);
|
|
void Free();
|
|
|
|
void ComputeMinMax(MinMax &) const;
|
|
|
|
/// Sort emitter particles against a given view matrix.
|
|
void Sort(const Matrix4 &view_matrix);
|
|
/*!
|
|
@short Get alive particle count.
|
|
@note The emitter must have been sorted beforehand.
|
|
@see Sort().
|
|
*/
|
|
uint GetParticleCount() const { return alive_count; }
|
|
/*
|
|
@short Get alive particle.
|
|
@note Particles are returned back to front.
|
|
*/
|
|
Particle *GetParticle(uint n) const { return n < particle_pool.GetCount() ? &particle_pool[sort_array[alive_count - 1 - n].o] : 0; }
|
|
|
|
/*!
|
|
@name Serialization.
|
|
@{
|
|
*/
|
|
bool FromMetaTag(NML::Tag &);
|
|
NML::Tag *AsMetaTag() const;
|
|
/// @}
|
|
|
|
Emitter();
|
|
};
|
|
|
|
} // Core
|
|
} // GS
|
|
|
|
|
|
#endif // __NEMITTER__
|