annotate CollidoscopeApp/src/Wave.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 7fb593d53361
rev   line source
f@0 1 #include "Wave.h"
f@0 2 #include "DrawInfo.h"
f@0 3
f@0 4
f@0 5 using namespace ci;
f@0 6
f@0 7 Wave::Wave( size_t numChunks, Color selectionColor ):
f@0 8 mNumChunks( numChunks ),
f@0 9 mSelection( this, selectionColor ),
f@0 10 mColor(Color(0.5f, 0.5f, 0.5f)),
f@0 11 mFilterCoeff( 1.0f )
f@0 12 {
f@0 13 mChunks.reserve( numChunks );
f@0 14
f@0 15 for ( size_t i = 0; i < numChunks; i++ ){
f@0 16 mChunks.emplace_back( i );
f@0 17 }
f@0 18
f@0 19 auto lambert = gl::ShaderDef().color();
f@0 20 gl::GlslProgRef shader = gl::getStockShader( lambert );
f@0 21 mChunkBatch = gl::Batch::create( geom::Rect( ci::Rectf( 0, 0, Chunk::kWidth, 1 ) ), shader );
f@0 22 }
f@0 23
f@0 24 void Wave::reset( bool onlyChunks )
f@0 25 {
f@0 26 for (size_t i = 0; i < getSize(); i++){
f@0 27 mChunks[i].reset();
f@0 28 }
f@0 29
f@0 30 if (onlyChunks)
f@0 31 return;
f@0 32
f@0 33 mSelection.setToNull();
f@0 34 }
f@0 35
f@0 36
f@0 37 void Wave::setChunk(size_t index, float bottom, float top)
f@0 38 {
f@0 39 Chunk &c = mChunks[index];
f@0 40 c.setTop(top);
f@0 41 c.setBottom(bottom);
f@0 42 }
f@0 43
f@0 44 inline const Chunk & Wave::getChunk(size_t index)
f@0 45 {
f@0 46 return mChunks[index];
f@0 47 }
f@0 48
f@0 49 void Wave::update( double secondsPerChunk, const DrawInfo& di ) {
f@0 50 typedef std::map<int, Cursor>::iterator MapItr;
f@0 51
f@0 52
f@0 53 // update the cursor positions
f@0 54 double now = ci::app::getElapsedSeconds();
f@0 55 for (MapItr itr = mCursors.begin(); itr != mCursors.end(); ++itr){
f@0 56 if (mSelection.isNull()){
f@0 57 itr->second.pos = Cursor::kNoPosition;
f@0 58 }
f@0 59
f@0 60 if ( itr->second.pos == Cursor::kNoPosition )
f@0 61 continue;
f@0 62
f@0 63
f@0 64 double elapsed = now - itr->second.lastUpdate;
f@0 65
f@0 66 itr->second.pos = mSelection.getStart() + int( elapsed / secondsPerChunk );
f@0 67
f@0 68 /* check we don't go too far off */
f@0 69 if (itr->second.pos > mSelection.getEnd()){
f@0 70 itr->second.pos = Cursor::kNoPosition;
f@0 71 }
f@0 72 }
f@0 73
f@0 74 // update chunks for animation
f@0 75 for ( auto &chunk : mChunks ){
f@0 76 chunk.update( di );
f@0 77 }
f@0 78
f@0 79 #ifdef USE_PARTICLES
f@0 80 mParticleController.updateParticles();
f@0 81 #endif
f@0 82
f@0 83 }
f@0 84
f@0 85 void Wave::draw( const DrawInfo& di ){
f@0 86
f@0 87
f@0 88 /* ########### draw the particles ########## */
f@0 89 #ifdef USE_PARTICLES
f@0 90 mParticleController.draw();
f@0 91 #endif
f@0 92
f@0 93 /* ########### draw the wave ########## */
f@0 94 /* scale the wave to fit the window */
f@0 95 gl::pushModelView();
f@0 96
f@0 97
f@0 98 const float wavePixelLen = ( mNumChunks * ( 2 + Chunk::kWidth ) );
f@0 99 /* scale the x-axis for the wave to fit the window */
f@0 100 gl::scale( ((float)di.getWindowWidth() ) / wavePixelLen , 1.0f);
f@0 101 /* draw the chunks */
f@0 102 if (mSelection.isNull()){
f@0 103 /* no selection: all chunks the same color */
f@0 104 gl::color(mColor);
f@0 105 for (size_t i = 0; i < getSize(); i++){
f@0 106 mChunks[i].draw( di, mChunkBatch );
f@0 107 }
f@0 108 }
f@0 109 else{
f@0 110 // Selection not null
f@0 111 gl::color(this->mColor);
f@0 112
f@0 113 // update the array with cursor positions
f@0 114 mCursorsPos.clear();
f@0 115 for ( auto cursor : mCursors ){
f@0 116 mCursorsPos.push_back( cursor.second.pos );
f@0 117 }
f@0 118
f@0 119 gl::enableAlphaBlending();
f@0 120
f@0 121 const float selectionAlpha = 0.5f + mFilterCoeff * 0.5f;
f@0 122
f@0 123
f@0 124 for (size_t i = 0; i < getSize(); i++){
f@0 125 /* when in selection use selection color */
f@0 126
f@0 127 if (i == mSelection.getStart()){
f@0 128 /* draw the selection bar with a transparent selection color */
f@0 129 gl::color(mSelection.getColor().r, mSelection.getColor().g, mSelection.getColor().b, 0.5f);
f@0 130 mChunks[i].drawBar( di, mChunkBatch );
f@0 131
f@0 132 /* set the color to the selection */
f@0 133 gl::color(mSelection.getColor().r, mSelection.getColor().g, mSelection.getColor().b, selectionAlpha);
f@0 134 }
f@0 135
f@0 136 // check if one of the cursors is positioned in this chunk
f@0 137 if (std::find(mCursorsPos.begin(), mCursorsPos.end(),i) != mCursorsPos.end() ){
f@0 138 gl::color(CURSOR_CLR);
f@0 139 mChunks[i].draw( di, mChunkBatch );
f@0 140 gl::color(mSelection.getColor().r, mSelection.getColor().g, mSelection.getColor().b, selectionAlpha);
f@0 141 }
f@0 142 else{
f@0 143 /* just draw with current color */
f@0 144 mChunks[i].draw( di, mChunkBatch );
f@0 145 }
f@0 146
f@0 147 /* exit selection: go back to wave color */
f@0 148 if (i == mSelection.getEnd()){
f@0 149 /* draw the selection bar with a transparent selection color */
f@0 150 gl::color(mSelection.getColor().r, mSelection.getColor().g, mSelection.getColor().b, 0.5f);
f@0 151 mChunks[i].drawBar( di, mChunkBatch );
f@0 152 /* set the colo to the wave */
f@0 153 gl::color(this->mColor);
f@0 154 }
f@0 155 }
f@0 156 gl::disableAlphaBlending();
f@0 157 }
f@0 158
f@0 159
f@0 160 gl::popModelView();
f@0 161
f@0 162 }
f@0 163
f@0 164
f@0 165
f@0 166 //**************** Selection ***************//
f@0 167
f@0 168 Wave::Selection::Selection(Wave * w, Color color) :
f@0 169 mWave( w ),
f@0 170 mSelectionStart( 0 ),
f@0 171 mSelectionEnd( 0 ),
f@0 172 mColor( color ),
f@0 173 mParticleSpread( 1 )
f@0 174 {}
f@0 175
f@0 176
f@0 177 void Wave::Selection::setStart(size_t start) {
f@0 178
f@0 179 /* deselect the previous */
f@0 180 mWave->mChunks[mSelectionStart].setAsSelectionStart( false );
f@0 181 /* select the next */
f@0 182 mWave->mChunks[start].setAsSelectionStart( true );
f@0 183
f@0 184 mNull = false;
f@0 185
f@0 186 size_t size = getSize();
f@0 187
f@0 188 mSelectionStart = start;
f@0 189 mSelectionEnd = start + size - 1;
f@0 190 if ( mSelectionEnd > mWave->getSize() - 1 )
f@0 191 mSelectionEnd = mWave->getSize() - 1;
f@0 192
f@0 193 }
f@0 194
f@0 195 void Wave::Selection::setSize(size_t size) {
f@0 196
f@0 197 if ( size <= 0 ){
f@0 198 mNull = true;
f@0 199 return;
f@0 200 }
f@0 201
f@0 202 size -= 1;
f@0 203
f@0 204 // check boundaries: size cannot bring the selection end beyond the end of the wave
f@0 205 if ( mSelectionStart+size >= mWave->mNumChunks ){
f@0 206 size = mWave->mNumChunks - mSelectionStart - 1;
f@0 207 }
f@0 208
f@0 209 /* deselect the previous */
f@0 210 mWave->mChunks[mSelectionEnd].setAsSelectionEnd( false );
f@0 211
f@0 212 mSelectionEnd = mSelectionStart + size;
f@0 213 /* select the next */
f@0 214 mWave->mChunks[mSelectionEnd].setAsSelectionEnd( true );
f@0 215
f@0 216 mNull = false;
f@0 217 }
f@0 218
f@0 219
f@0 220 const cinder::Color Wave::CURSOR_CLR = Color(1.f, 1.f, 1.f);
f@0 221
f@0 222