aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/graphics/particles/particle_emitter.cpp
blob: 56dfb232754694aa98403d5aecc20cd52c9c5349 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <time.h>

#include "../../math/random.h"

#include "particle_emitter.h"
#include "particle_system.h"

using namespace JinEngine::Math;

namespace JinEngine
{
	namespace Graphics
	{
		namespace Particles
		{

			static const uint8 ACCURACY_4 = 4;
			static const uint8 ACCURACY_5 = 5;
			static const uint8 ACCURACY_6 = 6;

			// Particle emitter 
			static RandomGenerator rng(0xEA44944);

			ParticleEmitter::ParticleEmitter(ParticleSystem& ps)
				: mPS(ps)
				, mDef(ps.mDef.emitterDef)
				, mPDef(ps.mDef.particleDef)
				, mTime(0)
			{
			}

			void ParticleEmitter::update(float dt)
			{
				mTime += dt; 
				for (;mTime >= mInterval; mTime -= mInterval)
				{
					emit();
					// Random rate.
					if (mDef.emitRateDef.enableRandom)
						mInterval = rng.randf(mDef.emitRateDef.rate.random.floor, mDef.emitRateDef.rate.random.ceil, ACCURACY_5);
					else
						mInterval = mDef.emitRateDef.rate.rate;
				}
			}

			void ParticleEmitter::emit()
			{
				Particle* p = mPS.claim();
				if (p == nullptr)
					return;
				p->reset();
				p->def = &mPDef;
				// Init position.
				if (mDef.positionDef.enableRandom)
				{
					float x = rng.randf(mDef.positionDef.position.random.floor.x(), mDef.positionDef.position.random.ceil.x(), ACCURACY_4);
					float y = rng.randf(mDef.positionDef.position.random.floor.y(), mDef.positionDef.position.random.ceil.y(), ACCURACY_4);
					x += mPS.mPosition.x();
					y += mPS.mPosition.y();
					p->transform.setPosition(x, y);
				}
				else
				{
					p->transform.setPosition(mDef.positionDef.position.position + mPS.mPosition);
				}
				// Init speed.
				float r = 0;
				if (mDef.directionDef.enableRandom)
					r = rng.randf(mDef.directionDef.direction.random.floor, mDef.directionDef.direction.random.ceil, ACCURACY_4);
				else
					r = mDef.directionDef.direction.direction;
				float f = 0;
				if (mDef.forceDef.enableRandom)
					f = rng.randf(mDef.forceDef.force.random.floor, mDef.forceDef.force.random.ceil, ACCURACY_4);
				else
					f = mDef.forceDef.force.force;
				p->velocity.set(f*cos(r), f*sin(r));
				if (f != 0) p->updateFlags |= Particle::UPDATE_POSITION;
				// Init life time.
				if (mPDef.lifeTimeDef.enableRandom)
					p->lifeTime = rng.randf(mPDef.lifeTimeDef.life.random.floor, mPDef.lifeTimeDef.life.random.ceil, ACCURACY_4);
				else
					p->lifeTime = mPDef.lifeTimeDef.life.life;
				// Init linear accelaration.
				p->linearAcceleration = mPDef.linearAccelarationDef.linearAccelaration;
				if(!p->linearAcceleration.isZero())
					p->updateFlags |= (Particle::UPDATE_VELOCITY | Particle::UPDATE_POSITION);
				// Init angular accelaration.
				p->radialAcceleration = mPDef.radialAccelarationDef.radialAccelaration;
				// Init Angular speed.
				if (mPDef.angularSpeedDef.enableRandom)
					p->angularSpeed = rng.randf(mPDef.angularSpeedDef.angularSpeed.random.floor, mPDef.angularSpeedDef.angularSpeed.random.ceil, ACCURACY_4);
				else
					p->angularSpeed = mPDef.angularSpeedDef.angularSpeed.angularSpeed;
				if (p->angularSpeed != 0)
					p->updateFlags |= Particle::UPDATE_ROTATION;
				// Scale over time.
				if (mPDef.scaleDef.overTime.enable)
					p->updateFlags |= Particle::UPDATE_SCALE;
				else
					p->transform.setScale(mPDef.scaleDef.scale, mPDef.scaleDef.scale);
				// Color over time.
				if (mPDef.colorDef.overTime.enable)
					p->updateFlags |= Particle::UPDATE_COLOR;
				else
					p->color = mPDef.colorDef.color;
				// Sprite
				if (mPDef.spritesDef.mode != SpriteMode::SINGLE)
				{
					p->updateFlags |= Particle::UPDATE_SPRITE;
					if (mPDef.spritesDef.mode == SpriteMode::RANDOM)
						p->spriteIndex = rng.rand(0, mPDef.spritesDef.sprites.size() - 1);
				}
			}

		}
	}
}