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