Mercurial > hg > opencollidoscope
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CollidoscopeApp/src/ParticleController.cpp Thu Jun 30 14:50:06 2016 +0200 @@ -0,0 +1,136 @@ +#include "ParticleController.h" +#include "cinder/Rand.h" + +#include <type_traits> + +using namespace ci; +using std::list; + +ParticleController::ParticleController() : +mNumParticles( 0 ) + +{ + mParticles.assign( kMaxParticles, Particle() ); + mParticlePositions.assign( kMaxParticles, vec2( -1, -1 ) ); + + mParticleVbo = gl::Vbo::create( GL_ARRAY_BUFFER, mParticlePositions, GL_DYNAMIC_DRAW ); + + geom::BufferLayout particleLayout; + particleLayout.append( geom::Attrib::POSITION, 2, sizeof( vec2 ), 0 ); + + auto mesh = gl::VboMesh::create( mParticlePositions.size(), GL_POINTS, { { particleLayout, mParticleVbo } } ); + +#if ! defined( CINDER_GL_ES ) + auto glsl = gl::GlslProg::create( gl::GlslProg::Format() + .vertex( CI_GLSL( 150, + uniform mat4 ciModelViewProjection; + in vec4 ciPosition; + + void main( void ) { + gl_Position = ciModelViewProjection * ciPosition; + gl_PointSize = 1.0; + } + ) ) + .fragment( CI_GLSL( 150, + out vec4 oColor; + + void main( void ) { + oColor = vec4( 1.0f, 1.0f, 1.0f, 1.0f ); + } + ) ) + ); + + mParticleBatch = gl::Batch::create( mesh, glsl ); + +#else + auto glsl = gl::GlslProg::create( gl::GlslProg::Format() + .vertex( CI_GLSL( 100, + uniform mat4 ciModelViewProjection; + attribute vec4 ciPosition; + + void main( void ) { + gl_Position = ciModelViewProjection * ciPosition; + gl_PointSize = 1.0; + } + ) ) + .fragment( CI_GLSL( 100, + precision highp float; + + void main( void ) { + gl_FragColor = vec4( 1, 1, 1, 1 ); + } + ) ) + ); + + mParticleBatch = gl::Batch::create( mesh, glsl ); +#endif + + +} + +void ParticleController::updateParticles() +{ + for ( size_t i = 0; i < mNumParticles; i++ ){ + + Particle &particle = mParticles[i]; + vec2 &pos = mParticlePositions[i]; + + particle.mAge++; + + + if ( (!particle.mFlyOver && particle.mAge > particle.mLifespan) + || (particle.mFlyOver && particle.mAge >= 300) ){ + // dispose particle + mParticles[i] = mParticles[mNumParticles - 1]; + mParticlePositions[i] = mParticlePositions[mNumParticles - 1]; + mParticlePositions[mNumParticles - 1].x = -1.0f; + mParticlePositions[mNumParticles - 1].y = -1.0f; + mNumParticles--; + continue; + } + + pos += particle.mVel; + if ( ci::distance( pos, particle.mCloudCenter ) > particle.mCloudSize && !particle.mFlyOver ){ + particle.mVel = rotate<float>( particle.mVel, 5 ); + } + } + + void *gpuMem = mParticleVbo->mapReplace(); + memcpy( gpuMem, mParticlePositions.data(), mParticlePositions.size() * sizeof( vec2 ) ); + mParticleVbo->unmap(); +} + +void ParticleController::addParticles(int amount, const vec2 &initialLocation, const float cloudSize) +{ + int reduction = ci::lmap<int>(mNumParticles, 0, kMaxParticles, 0, kMaxParticleAdd); + amount -= reduction; + + if ( mNumParticles + amount > kMaxParticles ){ + //return; + amount = kMaxParticles - mNumParticles; + } + + if( amount <= 0 ) + return; + + for( size_t i = 0; i < amount; i++ ){ + // init new particle + Particle &particle = mParticles[mNumParticles + i]; + vec2 &pos = mParticlePositions[mNumParticles + i]; + + pos = initialLocation + Rand::randVec2() * 5.0f; // find a location nearby the initial location + particle.mCloudCenter = pos; + particle.mVel = Rand::randVec2() * Rand::randFloat( 1.0f, 5.0f ); + particle.mCloudSize = cloudSize; + particle.mAge = 0; + particle.mLifespan = Rand::randInt( 30, 60 ); + particle.mFlyOver = (Rand::randInt( 500 ) == 0); + + } + + mNumParticles += amount ; + +} + + +