Mercurial > hg > opencollidoscope
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 |