comparison CollidoscopeApp/src/ParticleController.cpp @ 0:02467299402e

First import CollidoscopeApp for Raspberry Pi JackDevice Teensy code for Collidoscope
author Fiore Martin <f.martin@qmul.ac.uk>
date Thu, 30 Jun 2016 14:50:06 +0200
parents
children ab6db404403a
comparison
equal deleted inserted replaced
-1:000000000000 0:02467299402e
1 #include "ParticleController.h"
2 #include "cinder/Rand.h"
3
4 #include <type_traits>
5
6 using namespace ci;
7 using std::list;
8
9 ParticleController::ParticleController() :
10 mNumParticles( 0 )
11
12 {
13 mParticles.assign( kMaxParticles, Particle() );
14 mParticlePositions.assign( kMaxParticles, vec2( -1, -1 ) );
15
16 mParticleVbo = gl::Vbo::create( GL_ARRAY_BUFFER, mParticlePositions, GL_DYNAMIC_DRAW );
17
18 geom::BufferLayout particleLayout;
19 particleLayout.append( geom::Attrib::POSITION, 2, sizeof( vec2 ), 0 );
20
21 auto mesh = gl::VboMesh::create( mParticlePositions.size(), GL_POINTS, { { particleLayout, mParticleVbo } } );
22
23 #if ! defined( CINDER_GL_ES )
24 auto glsl = gl::GlslProg::create( gl::GlslProg::Format()
25 .vertex( CI_GLSL( 150,
26 uniform mat4 ciModelViewProjection;
27 in vec4 ciPosition;
28
29 void main( void ) {
30 gl_Position = ciModelViewProjection * ciPosition;
31 gl_PointSize = 1.0;
32 }
33 ) )
34 .fragment( CI_GLSL( 150,
35 out vec4 oColor;
36
37 void main( void ) {
38 oColor = vec4( 1.0f, 1.0f, 1.0f, 1.0f );
39 }
40 ) )
41 );
42
43 mParticleBatch = gl::Batch::create( mesh, glsl );
44
45 #else
46 auto glsl = gl::GlslProg::create( gl::GlslProg::Format()
47 .vertex( CI_GLSL( 100,
48 uniform mat4 ciModelViewProjection;
49 attribute vec4 ciPosition;
50
51 void main( void ) {
52 gl_Position = ciModelViewProjection * ciPosition;
53 gl_PointSize = 1.0;
54 }
55 ) )
56 .fragment( CI_GLSL( 100,
57 precision highp float;
58
59 void main( void ) {
60 gl_FragColor = vec4( 1, 1, 1, 1 );
61 }
62 ) )
63 );
64
65 mParticleBatch = gl::Batch::create( mesh, glsl );
66 #endif
67
68
69 }
70
71 void ParticleController::updateParticles()
72 {
73 for ( size_t i = 0; i < mNumParticles; i++ ){
74
75 Particle &particle = mParticles[i];
76 vec2 &pos = mParticlePositions[i];
77
78 particle.mAge++;
79
80
81 if ( (!particle.mFlyOver && particle.mAge > particle.mLifespan)
82 || (particle.mFlyOver && particle.mAge >= 300) ){
83 // dispose particle
84 mParticles[i] = mParticles[mNumParticles - 1];
85 mParticlePositions[i] = mParticlePositions[mNumParticles - 1];
86 mParticlePositions[mNumParticles - 1].x = -1.0f;
87 mParticlePositions[mNumParticles - 1].y = -1.0f;
88 mNumParticles--;
89 continue;
90 }
91
92 pos += particle.mVel;
93 if ( ci::distance( pos, particle.mCloudCenter ) > particle.mCloudSize && !particle.mFlyOver ){
94 particle.mVel = rotate<float>( particle.mVel, 5 );
95 }
96 }
97
98 void *gpuMem = mParticleVbo->mapReplace();
99 memcpy( gpuMem, mParticlePositions.data(), mParticlePositions.size() * sizeof( vec2 ) );
100 mParticleVbo->unmap();
101 }
102
103 void ParticleController::addParticles(int amount, const vec2 &initialLocation, const float cloudSize)
104 {
105 int reduction = ci::lmap<int>(mNumParticles, 0, kMaxParticles, 0, kMaxParticleAdd);
106 amount -= reduction;
107
108 if ( mNumParticles + amount > kMaxParticles ){
109 //return;
110 amount = kMaxParticles - mNumParticles;
111 }
112
113 if( amount <= 0 )
114 return;
115
116 for( size_t i = 0; i < amount; i++ ){
117 // init new particle
118 Particle &particle = mParticles[mNumParticles + i];
119 vec2 &pos = mParticlePositions[mNumParticles + i];
120
121 pos = initialLocation + Rand::randVec2() * 5.0f; // find a location nearby the initial location
122 particle.mCloudCenter = pos;
123 particle.mVel = Rand::randVec2() * Rand::randFloat( 1.0f, 5.0f );
124 particle.mCloudSize = cloudSize;
125 particle.mAge = 0;
126 particle.mLifespan = Rand::randInt( 30, 60 );
127 particle.mFlyOver = (Rand::randInt( 500 ) == 0);
128
129 }
130
131 mNumParticles += amount ;
132
133 }
134
135
136