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 ;
+
+}
+
+
+