Eigene Dateien/FlowVis/src/VFlowData.cpp

Go to the documentation of this file.
00001 #include "VFlowData.h"
00002 #include "glew.h"
00003 #include <time.h>
00004 #include <deque>
00005 
00006 
00007 #define MINNUMBER 5.0f
00008 #define MAXNUMBER 100.0f
00009 #define MAXSTEPS 4 * 4096
00010 
00011 VFlowData::VFlowData() : 
00012 mVertexVbo( 0 ), 
00013 mIndexVbo( 0 ),
00014 mGlyphIndexVbo( 0 ), 
00015 mTexturesGenerated( false ), 
00016 mStreamlinesDt( 0.5f ),
00017 mStreamlinesTestSeparation( 0.2f ),
00018 mStreamlinesSeedSeparation( 0.5f ),
00019 mStreamlinesSteps( 0.5f ),      
00020 mEuler( 1.0f )  ,
00021 mNumStreamlines( 0 ),
00022 mTapering( false ),
00023 mTaperingScale( 0.5f ),
00024 mActiveTimeStep( 0 ),
00025 mIconScale( 0.5f ),
00026 mTailLength( 0.5f ),
00027 mStrGlyphes(false)
00028 {
00029 
00030         maxDataValues.push_back( 0.0f );
00031         minDataValues.push_back( 0.0f );
00032         mSeedPlacing = LEFT;
00033 }
00034 
00035 VFlowData::~VFlowData()
00036 {
00037         clear();
00038 }
00039 
00040 VFlowData::VFlowData( std::string m_FileName ) : mVertexVbo( 0 ), mIndexVbo( 0 )
00041 {
00042         loadData( m_FileName );
00043         mSeedPlacing = LEFT;
00044 }
00045 
00046 bool VFlowData::loadData( std::string m_FileName )
00047 {
00048         maxDataValues.clear();
00049         minDataValues.clear();
00050         maxDataValues.push_back( 0.0f );
00051         minDataValues.push_back( 0.0f );
00052 
00053         int pointpos = ( int )m_FileName.find_last_of('.');
00054         
00055         std::string gridpath = m_FileName.substr( 0, pointpos ) + ".gri";
00056 
00057         if( !readGrid( gridpath ) )
00058         {
00059                 return false;
00060         }
00061 
00062         std::cout << "loading "  << mHeader.mNT << " timesteps" << std::endl;
00063         
00064         for( int i = 0; i < mHeader.mNF; ++i )
00065         {
00066                 maxDataValues.push_back( 0.0f );
00067                 minDataValues.push_back( 0.0f );
00068         }
00069 
00070         for( int i = 0; i < mHeader.mNT; ++i )
00071         {
00072                 std::string datfile;
00073 
00074                 if( mHeader.mNT > 1 )
00075                 {
00076                         std::string fullnumber;
00077                         int tmp = 100000 + i;
00078                         std::stringstream ss;
00079                         ss << tmp;
00080                         std::string tmpstr;
00081                         tmpstr = ss.str();
00082                         fullnumber = tmpstr.substr( 1,5 );
00083                         datfile = m_FileName.substr( 0, pointpos ) + "." + fullnumber + ".dat";
00084                 }
00085                 else
00086                 {
00087                         datfile = m_FileName.substr( 0, pointpos ) + ".dat";
00088                 }
00089 
00090                 if( !readDat( datfile ) )
00091                 {
00092                         return false;
00093                 }
00094                 std::cout << "\rtimestep " << i << " loaded!";
00095         }
00096 
00097         std::cout << std::endl;
00098 
00099         generateVBO();
00100 
00101         return true;
00102 }
00103 
00104 bool VFlowData::loadData( std::string m_FileName, std::string m_DatFilename)
00105 {
00106         maxDataValues.clear();
00107         minDataValues.clear();
00108         maxDataValues.push_back( 0.0f );
00109         minDataValues.push_back( 0.0f );
00110 
00111         int pointpos = ( int )m_FileName.find_last_of('.');
00112 
00113         std::string gridpath = m_FileName.substr( 0, pointpos ) + ".gri";
00114 
00115         if( !readGrid( gridpath ) )
00116         {
00117                 return false;
00118         }
00119 
00120         std::cout << "loading 1 timesteps" << std::endl;
00121 
00122         for( int i = 0; i < mHeader.mNF; ++i )
00123         {
00124                 maxDataValues.push_back( 0.0f );
00125                 minDataValues.push_back( 0.0f );
00126         }
00127 
00128                 std::string datfile;
00129         mHeader.mNT = 1;
00130 
00131 
00132         if( !readDat( m_DatFilename ) )
00133         {
00134                 return false;
00135         }
00136         std::cout << "\rtimestep 1 loaded!";
00137 
00138 
00139         std::cout << std::endl;
00140 
00141         generateVBO();
00142 
00143         return true;
00144 }
00145 
00146 
00147 bool VFlowData::readGrid( std::string m_FileName )
00148 {
00149 
00150         FILE * gridfile;
00151         
00152         fopen_s( &gridfile, m_FileName.c_str(), "rb" );
00153 
00154         if( !gridfile )
00155         {
00156                 return false;
00157         }
00158 
00159         char buf[40];
00160         fread( buf, sizeof(char),40, gridfile );
00161         
00162         sscanf_s( buf,"SN4DB %d %d %d %d %d %f",&mHeader.mSX,&mHeader.mSY,&mHeader.mSZ,&mHeader.mNF,&mHeader.mNT,&mHeader.mDT );
00163         
00164         if( mHeader.mSZ > 1 )
00165         {
00166                 return false;
00167         }
00168 
00169         std::vector<float> input;
00170         int numValues = mHeader.mSX * mHeader.mSY * 3;
00171 
00172         input.resize( numValues );
00173 
00174         unsigned int rb = (unsigned int)fread( reinterpret_cast<char*>( &input[0] ), sizeof( float ), numValues, gridfile );
00175 
00176         int eo = feof(gridfile);
00177         int er = ferror(gridfile);
00178 
00179         
00180 
00181         for( int i = 0; i < numValues; i +=3 )
00182         {
00183                 VVector tmp( -input[i], -input[i + 1], input[i + 2]);
00184 
00185                 mVertexGrid.push_back( tmp );
00186         }
00187 
00188         mMinPos = mVertexGrid.front();
00189         mMaxPos = mVertexGrid.back();
00190 
00191         bool switchx = false;
00192         bool switchy = false;
00193 
00194         if((mMinPos.getX() > mMaxPos.getX()))
00195         {
00196                 float tmp = mMinPos.getX();
00197                 mMinPos.setX(mMaxPos.getX());
00198                 mMaxPos.setX(tmp);
00199                 switchx = true;
00200         }
00201         if((mMinPos.getY() > mMaxPos.getY()))
00202         {
00203                 float tmp = mMinPos.getY();
00204                 mMinPos.setY(mMaxPos.getY());
00205                 mMaxPos.setY(tmp);
00206                 switchy = true;
00207         }
00208         mExtends = mMaxPos - mMinPos;
00209         mCenterPos = mMinPos + mExtends/ 2.0f;
00210 
00211         float minxdistance = ( switchx ) ? abs( mVertexGrid[1].getX() - mVertexGrid[0].getX() ) : abs( mVertexGrid[0].getX() - mVertexGrid[1].getX() );
00212         float minydistance = ( switchy ) ? abs( mVertexGrid[mHeader.mSX].getY() - mVertexGrid[0].getY() ) : abs( mVertexGrid[0].getY() - mVertexGrid[mHeader.mSX].getY() );
00213 
00214         for( int i = 0; i < ( mHeader.mSX * ( mHeader.mSY - 1)  ); ++i )
00215         {
00216                 if( (i != 0 ) && ((i + 1) % (mHeader.mSX)) == 0 )
00217                 {
00218                         continue;
00219                 }
00220                 //QUAD Version
00221                 /*mIndexGrid.push_back( i );
00222                 mIndexGrid.push_back( i + mHeader.mSX );
00223                 mIndexGrid.push_back( i + mHeader.mSX + 1 );
00224                 mIndexGrid.push_back( i + 1 );*/
00225                 
00226                 //Triangle 1
00227                 mIndexGrid.push_back( i );
00228                 mIndexGrid.push_back( i + mHeader.mSX );
00229                 mIndexGrid.push_back( i + 1 );
00230 
00231                 //Triangle 2
00232                 mIndexGrid.push_back( i + mHeader.mSX );
00233                 mIndexGrid.push_back( i + mHeader.mSX + 1 );
00234                 mIndexGrid.push_back( i + 1 );
00235 
00236                 float tmpxdistance = ( switchx ) ? abs( mVertexGrid[i+1].getX() - mVertexGrid[i].getX() ) : abs( mVertexGrid[i].getX() - mVertexGrid[i+1].getX() );
00237                 float tmpydistance = ( switchy ) ? abs( mVertexGrid[i+mHeader.mSX].getY() - mVertexGrid[i].getY() ) : abs( mVertexGrid[i].getY() - mVertexGrid[i+mHeader.mSX].getY() );
00238 
00239                 if(tmpxdistance < minxdistance) minxdistance = tmpxdistance;
00240                 if(tmpydistance < minydistance) minydistance = tmpydistance;
00241         }
00242 
00243         mMinDistance = VVector(minxdistance, minydistance, 0.0f);
00244 
00245         mReverseX = switchx;
00246         mReverseY = switchy;
00247 
00248         fclose(gridfile);       
00249 
00250         mVertexToTexture.clearMatrix();
00251 
00252         VVector scale(/*((mReverseX)?(-1.0f) : (1.0f)) * */-2.0f / mExtends.getX(), /*((mReverseY)?(-1.0f) : (1.0f)) * */2.0f / mExtends.getY(), 1.0f );
00253 
00254         mVertexToTexture.scale(scale);
00255         mVertexToTexture.translate(-mCenterPos);
00256 
00257         mTextureToVertex = mVertexToTexture.getInverse();
00258 
00259         return true;
00260 }
00261 
00262 bool VFlowData::readDat( std::string m_FileName )
00263 {
00264         FILE * datfile;
00265 
00266         fopen_s( &datfile, m_FileName.c_str(), "rb" );
00267 
00268         if( !datfile )
00269         {
00270                 return false;
00271         }
00272 
00273         std::vector<float> input;
00274         input.resize( ( 3 + mHeader.mNF ) * mHeader.mSX * mHeader.mSY );
00275         
00276         fread( reinterpret_cast<char*>( &input[0] ), sizeof( float ), ( 3 + mHeader.mNF ) * mHeader.mSX * mHeader.mSY, datfile );
00277 
00278         fclose(datfile);
00279 
00280         vTimeStep newStep;
00281         int numTriplets = 1;
00282         double d = ( ( float ) mHeader.mNF / 3.0f );
00283         int numAddTriplet = ( int ) ( d < 0 ? d - 0.5 : d + 0.5 );
00284         numTriplets += numAddTriplet;
00285         
00286         mNumTriplets = (float)numTriplets;
00287 
00288         /*std::vector<float> tmp;
00289         tmp.resize(input.size());
00290         int linefloats = ( mHeader.mSX * ( 3 + mHeader.mNF ) );
00291         for( int i = 0; i < mHeader.mSY; ++i )
00292         {
00293                 int index = i;
00294                 int reverseIndex = mHeader.mSY - i - 1; 
00295                 for ( int j = 0; j < linefloats; ++j )
00296                 {
00297                         tmp[reverseIndex * linefloats + j] = input[index * linefloats + j];
00298                 }
00299         }
00300 
00301         input = tmp;
00302         */
00303 
00304         newStep.mTimeData.resize( numTriplets );
00305 
00306         for ( int i = 0; i < ( 3 + mHeader.mNF ) * mHeader.mSX * mHeader.mSY; i += ( 3 + mHeader.mNF ) )
00307         {
00308                 //int signx = ( input[ i + 1 ] < 0.0 ) ? 0.0 : 1.0;
00309                 VVector velocity( -input[i], -input[i + 1], input[i + 2] );
00310                 newStep.mTimeData[0].mSet.push_back( velocity );
00311 
00312                 float magnitude = sqrt( velocity.getX() * velocity.getX() + velocity.getY() * velocity.getY() + velocity.getZ() * velocity.getZ() );
00313                 //magnitude = velocity.getY();
00314 
00315                 if( maxDataValues[ 0 ] < magnitude )
00316                 {
00317                         maxDataValues[ 0 ] = magnitude;
00318                 }
00319 
00320                 if( minDataValues[ 0 ] > magnitude )
00321                 {
00322                         minDataValues[ 0 ] = magnitude;
00323                 }
00324 
00325 
00326                 for ( int j = 0; j < numAddTriplet; ++j )
00327                 {
00328                         VVector addData;
00329                         if ( j == numAddTriplet - 1)
00330                         {
00331                                 if ( (mHeader.mNF - j * 3) == 1)
00332                                 {
00333                                         addData = VVector( input[i + (3 * (j + 1))], 0.0f, 0.0f );
00334                                 }
00335                                 else if ( (mHeader.mNF - j * 3) == 2)
00336                                 {
00337                                         addData = VVector( input[i + (3 * (j + 1))], input[i + (3 * (j + 1) + 1)], 0.0f );
00338                                 }
00339                                 else if ( (mHeader.mNF - j * 3) == 3)
00340                                 {
00341                                         addData = VVector( input[i + (3 * (j + 1))], input[i + (3 * (j + 1) + 1)], input[i + (3 * (j + 1) + 2)] );
00342                                 }
00343                         }
00344                         else
00345                         {
00346                                 addData = VVector( input[i + (3 * (j + 1))], input[i + (3 * (j + 1) + 1)], input[i + (3 * (j + 1) + 2)] );
00347                         }
00348 
00349                         newStep.mTimeData[ j + 1 ].mSet.push_back( addData );
00350 
00351                         if ( j == 0  )
00352                         {
00353 /*pressure*/    
00354                                 
00355                                 float datavalue1 = addData.getX();
00356 
00357                                 if( maxDataValues[ 1 ] < datavalue1 )
00358                                 {
00359                                         maxDataValues[ 1 ] = datavalue1;
00360                                 }
00361 
00362                                 if( minDataValues[ 1 ] > datavalue1 )
00363                                 {
00364                                         minDataValues[ 1 ] = datavalue1;
00365                                 }
00366                         
00367 /*vorticity,humidity*/ 
00368                                 if ( mHeader.mNF > 1 )
00369                                 {
00370                         
00371                                         float datavalue2 = addData.getY();
00372 
00373                                         if( maxDataValues[ 2 ] < datavalue2 )
00374                                         {
00375                                                 maxDataValues[ 2 ] = datavalue2;
00376                                         }
00377 
00378                                         if( minDataValues[ 2 ] > datavalue2 )
00379                                         {
00380                                                 minDataValues[ 2 ] = datavalue2;
00381                                         }
00382 
00383                                 }
00384                         }
00385                 }
00386         }
00387 
00388         mTimeSteps.push_back(newStep);
00389         return true;
00390 }
00391 
00392 void VFlowData::draw(int m_TimeStep /* = 0  */)
00393 {
00394         activateVBO(m_TimeStep);
00395         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexVbo);
00396         //glPolygonMode(GL_FRONT, GL_LINE);
00397         glDrawElements(GL_TRIANGLES, (int) mIndexGrid.size(), GL_UNSIGNED_INT, 0);
00398         deactivateVBO();
00399 }
00400 
00401 void VFlowData::drawPoints(int m_TimeStep /* = 0  */)
00402 {
00403         activateVBO(m_TimeStep);
00404         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGlyphIndexVbo);
00405         //glPolygonMode(GL_FRONT, GL_LINE);
00406         glDrawElements(GL_POINTS, (int) mGlyphIndexGrid.size(), GL_UNSIGNED_INT, 0);
00407         deactivateVBO();
00408 }
00409 
00410 void VFlowData::drawStreamLines( VVector  *col )
00411 {
00412         //on default white
00413         glColor4f( col->getX(), col->getY(), col->getZ(), 1.0f );
00414 
00415         for ( int i = 0; i < mNumStreamlines; i ++ )
00416         {
00417                 //glColor4f( (float)i / (float)mNumStreamlines , ( (float)mNumStreamlines - (float)i ) / (float)mNumStreamlines, 0.0f, 1.0f );
00418                 streamlines[ i ].draw( mTapering, mTaperingScale, mStrGlyphes );
00419         }
00420         
00421 }
00422 
00423 void VFlowData::drawIcons()
00424 {
00425         for( int i = 0; i < (int)mIcons.size(); ++i )
00426         {
00427                 mIcons[i].draw();
00428         }
00429 }
00430 
00431 void VFlowData::addIconPoint( float x, float y )
00432 {
00433         // convert x and y from worlds space to texture space, if out, discard it
00434 
00435         float dataextent_x, dataextent_y;
00436         float minx, miny;
00437 
00438         dataextent_x = mExtends.getX();
00439         dataextent_y = mExtends.getY();
00440         minx = mMinPos.getX();
00441         miny = mMinPos.getY();
00442 
00443 
00444         VVector newpos_tex = VVector();
00445         newpos_tex.setX( ( x - minx ) / dataextent_x );
00446         newpos_tex.setY( ( y - miny ) / dataextent_y );
00447 
00448         if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
00449                 ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
00450         {
00451                 //the point is out of data
00452                 return;
00453         }
00454         else
00455         {
00456 
00457                 //TODO
00458                 float data[ 4 ];
00459                 data[ 0 ] = dataextent_x;
00460                 data[ 1 ] = dataextent_y;
00461                 data[ 2 ] = minx;
00462                 data[ 3 ] = miny;
00463 
00464                 mIcons.push_back( VIcon(newpos_tex, data ));
00465                 mIcons.back().computeIcon( &mTimeSteps[0], mActiveTimeStep );
00466         }
00467 }
00468 
00469 void VFlowData::drawTextureTest( int m_TimeStep /* = 0  */ )
00470 {
00471         if( m_TimeStep > ( ( int )mTimeSteps.size(  ) - 1) )
00472         {
00473                 m_TimeStep = ( ( int )mTimeSteps.size(  ) - 1 );
00474         }
00475         mTimeSteps[m_TimeStep].mFrameBufferObject->renderToLowerLeftQuad();
00476 }
00477 
00478 void VFlowData::generateGlyphIndices( int m_NumX, int m_NumY )
00479 {
00480         mGlyphIndexGrid.clear();
00481 
00482         float glyphspacex = mExtends.getX() / (float)( m_NumX + 1 );
00483         float glyphspacey = mExtends.getY() / (float)( m_NumY + 1 );
00484 
00485         float curX = mVertexGrid[0].getX();
00486         float curY = mVertexGrid[0].getY();
00487 
00488         if((mVertexGrid[0].getY()) == (mVertexGrid[mHeader.mSX].getY()))
00489         {
00490                 for( int i = 0; i < mHeader.mSX; ++i )
00491                 {
00492                         float distancex = ( mReverseX ) ? ( curX - mVertexGrid[i * mHeader.mSY].getX() ) : ( mVertexGrid[i * mHeader.mSY].getX() - curX );
00493                         if(distancex < glyphspacex)
00494                         {
00495                                 continue;
00496                         }
00497                         else
00498                         {
00499                                 for( int j = 0; j < mHeader.mSY - 1; ++j )
00500                                 {
00501                                         float distancey = ( mReverseY ) ? ( curY - mVertexGrid[i * mHeader.mSY + j].getY() ) : ( mVertexGrid[i * mHeader.mSY + j].getY() - curY );
00502                                         if(distancey < glyphspacey)
00503                                         {
00504                                                 continue;
00505                                         }
00506                                         else
00507                                         {
00508                                                 mGlyphIndexGrid.push_back( i * mHeader.mSY + j );
00509                                                 curY = mVertexGrid[i * mHeader.mSY + j].getY();
00510                                         }
00511                                 }
00512                                 curX = mVertexGrid[i * mHeader.mSY].getX();
00513                                 curY = mVertexGrid[0].getY();
00514                         }
00515                 }
00516         }
00517         else
00518         {
00519                 for( int i = 0; i < mHeader.mSY; ++i )
00520                 {
00521                         float distancey = ( mReverseY ) ? ( curY - mVertexGrid[i * mHeader.mSX].getY() ) : ( mVertexGrid[i * mHeader.mSX].getY() - curY );
00522                         if(distancey < glyphspacey)
00523                         {
00524                                 continue;
00525                         }
00526                         else
00527                         {
00528                                 for( int j = 0; j < mHeader.mSX - 1; ++j )
00529                                 {
00530                                         float distancex = ( mReverseX ) ? ( curX - mVertexGrid[i * mHeader.mSX + j].getX() ) : ( mVertexGrid[i * mHeader.mSX + j].getX() - curX );
00531                                         if(distancex < glyphspacex)
00532                                         {
00533                                                 continue;
00534                                         }
00535                                         else
00536                                         {
00537                                                 mGlyphIndexGrid.push_back( i * mHeader.mSX + j );
00538                                                 curX = mVertexGrid[i * mHeader.mSX + j].getX();
00539                                         }
00540                                 }
00541                                 curY = mVertexGrid[i * mHeader.mSX].getY();
00542                                 curX = mVertexGrid[0].getX();
00543                         }
00544                 }
00545         }
00546 
00547         if(mGlyphIndexVbo == 0)
00548         {
00549                 glGenBuffersARB( 1, &(mGlyphIndexVbo) );
00550         }
00551         else
00552         {
00553                 glDeleteBuffers( 1, &(mGlyphIndexVbo) );
00554                 glGenBuffersARB( 1, &(mGlyphIndexVbo) );
00555         }
00556 
00557         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, mGlyphIndexVbo );
00558         glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(int) * (int)mGlyphIndexGrid.size(), &(mGlyphIndexGrid[0]), GL_STATIC_DRAW_ARB );
00559         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, 0 );
00560 
00561 }
00562 
00563 void VFlowData::generateTextures()
00564 {
00565         if(!mRenderTextureProgram)
00566         {
00567                 mRenderTextureProgram = new VProgram(VVertexShader("shader/texture_vertex.glsl"), VFragmentShader("shader/texture_fragment.glsl"));
00568         }
00569 
00570         mRenderTextureProgram->bind();
00571 
00572         glUniformMatrix4fv(mRenderTextureProgram->getUniformLocation("mVertexToTexture"),1,false, &mVertexToTexture[0]);
00573 
00574         std::cout << "generating " << (int)mTimeSteps.size() << " textures!" << std::endl;
00575 
00576         for ( int i = 0; i < (int)mTimeSteps.size(); ++i )
00577         {
00578                 if(!mTimeSteps[i].mFrameBufferObject)
00579                 {
00580                         mTimeSteps[i].mFrameBufferObject = new VFramebufferObject(1024, 1024, GL_RGBA16F_ARB);
00581                         mTimeSteps[i].mFrameBufferObject->init();
00582                 }
00583 
00584                 mTimeSteps[i].mFrameBufferObject->bind();
00585 
00586                 this->draw(i);          
00587 
00588                 mTimeSteps[i].mFrameBufferObject->unbind();
00589 
00590                 GLenum glError = glGetError();
00591 
00592                 if (glError != GL_NO_ERROR)
00593                         std::cout << "Error rendering to TimeStep " << i << " " << gluErrorString(glError) << std::endl;
00594 
00595                 std::cout << "\rtexture " << i << " generated!";
00596         }
00597 
00598         std::cout << std::endl;
00599 
00600         mRenderTextureProgram->release();
00601 
00602         mTexturesGenerated = true;
00603 
00604 }
00605 
00607 //void VFlowData::addManualSeedpointWithDsepTest( float m_TimeStep, float m_MaxSteps  )
00608 //{
00609 //
00610 //      // convert x and y from worlds space to texture space, if out, discard it
00611 //
00612 //      float dataextent_x, dataextent_y;
00613 //      float minx, miny;
00614 //
00615 //      dataextent_x = mExtends.getX();
00616 //      dataextent_y = mExtends.getY();
00617 //      minx = mMinPos.getX();
00618 //      miny = mMinPos.getY();
00619 //
00620 //
00621 //      //VVector newpos_tex = VVector();
00622 //      //newpos_tex.setX( ( x - minx ) / dataextent_x );
00623 //      //newpos_tex.setY( ( y - miny ) / dataextent_y );
00624 //
00625 //      //if(           ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
00626 //      //      ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
00627 //      //{
00628 //      //      //the point is out of data
00629 //      //      return;
00630 //      //}
00631 //      //else
00632 //      //{
00633 //
00634 //      srand( time( NULL ) );
00635 //
00636 //      VVector start( minx + dataextent_x * 0.5f, miny + dataextent_y * 0.5f, 0.0f );
00637 //      mEvenlySeedpoints.push_back( start );
00638 //      drawEvenlySpacedStreamlines( m_TimeStep, m_MaxSteps );
00639 //
00640 //      for ( int i = 0; i < 20; i++ )
00641 //      {
00642 //      
00643 //              float r1 = (float)( rand() % (int)dataextent_x ) + minx + (float)( rand() % 10000 ) / 10000.0f;
00644 //              float r2 = (float)( rand() % (int)dataextent_y ) + miny + (float)( rand() % 10000 ) / 10000.0f;
00645 //
00646 //      
00647 //              //check
00648 //              int cardstr = mEvenlySeedpoints.size();
00649 //              bool streamline_allowed = false;
00650 //
00651 //              for( int i = 0; i < cardstr; i++)
00652 //              {
00653 //                      float dsepworld =  0.25f * mStreamlinesSeedSeparation * min( dataextent_x, dataextent_y );
00654 //                      streamline_allowed = streamlines[ i ].isPointAllowed( VVector( r1 , r2, 0.0f ), dsepworld );
00655 //
00656 //                      if( !streamline_allowed )
00657 //                      {
00658 //                              break;
00659 //                      }
00660 //                      
00661 //              }
00662 //
00663 //              mEvenlySeedpoints.push_back( VVector( r1 , r2, 0.0f ) );
00664 //              drawEvenlySpacedStreamlines( m_TimeStep, m_MaxSteps );
00665 //              
00666 //      
00667 //      }
00668 //              
00669 //      
00670 //
00671 //      //}
00672 //
00673 //}
00674 
00675 //x and y are in world space
00676 void VFlowData::addManualSeedpoint( float x, float y )
00677 {
00678 
00679         // convert x and y from worlds space to texture space, if out, discard it
00680 
00681         float dataextent_x, dataextent_y;
00682         float minx, miny;
00683 
00684         dataextent_x = mExtends.getX();
00685         dataextent_y = mExtends.getY();
00686         minx = mMinPos.getX();
00687         miny = mMinPos.getY();
00688 
00689 
00690         VVector newpos_tex = VVector();
00691         newpos_tex.setX( ( x - minx ) / dataextent_x );
00692         newpos_tex.setY( ( y - miny ) / dataextent_y );
00693 
00694         if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
00695                 ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
00696         {
00697                 //the point is out of data
00698                 return;
00699         }
00700         else
00701         {
00702                 
00703                 mManualSeedpoints.push_back( newpos_tex );
00704         }
00705 
00706 }
00707 
00708 
00709 //void VFlowData::drawEvenlySpacedStreamlines( float m_TimeStep, float m_MaxSteps  )
00710 //{
00711 //
00712 //      if( mNumStreamlines != 0 )
00713 //      {
00714 //              if ( streamlines )
00715 //              {
00716 //                      delete[] streamlines;
00717 //                      streamlines = NULL;
00718 //                      mNumStreamlines = 0;
00719 //              }
00720 //      }
00721 //      //float *pixeldata; // velocoty texture
00722 //      std::vector< float > pixeldata;
00723 //
00724 //      int texsize_x, texsize_y;
00725 //
00726 //      float dataextent_x, dataextent_y;
00727 //      float datacenter_x, datacenter_y;
00728 //      float minx, miny;
00729 //
00730 //      dataextent_x = mExtends.getX();
00731 //      dataextent_y = mExtends.getY();
00732 //      datacenter_x = mCenterPos.getX();
00733 //      datacenter_y = mCenterPos.getY();
00734 //      minx = mMinPos.getX();
00735 //      miny = mMinPos.getY();
00736 //
00737 //      //float keepratiox = ( dataextent_x > dataextent_y ) ? 1.0f  : dataextent_x / dataextent_y;
00738 //      //float keepratioy = ( dataextent_y > dataextent_x ) ? 1.0f  : dataextent_y / dataextent_x;
00739 //
00740 //      // generate seedpoints in texture coordinates
00741 //      float numbersteamlines = mEvenlySeedpoints.size();
00742 //
00743 //      pixeldata = mTimeSteps[m_TimeStep].getFullFBODataVector();
00744 //      texsize_x = mTimeSteps[m_TimeStep].mFrameBufferObject->getWidth();
00745 //      texsize_y = mTimeSteps[m_TimeStep].mFrameBufferObject->getHeight();
00746 //
00747 //      int size = (int)pixeldata.size();
00748 //
00749 //      
00750 //      // for all streamlines
00751 //      mNumStreamlines = numbersteamlines;
00752 //      streamlines = new VStreamLine[ (int)numbersteamlines + 1 ];
00753 //
00754 //      for ( int j = 0; j < numbersteamlines; j++ )
00755 //      {
00756 //
00757 //              std::vector< VVector > streamlinevertices;
00758 //              std::vector< float > vertexthickness;
00759 //              
00760 //              bool outofdata = false;
00761 //              bool dtestfail = false;
00762 //
00763 //              VVector start_world = VVector( mEvenlySeedpoints[ j ] );
00764 //
00765 //              float sactualpoint_x = ( start_world.getX() - minx ) / dataextent_x;
00766 //              float sactualpoint_y = ( start_world.getY() - miny ) / dataextent_y;
00767 //
00768 //              for ( int i = 0; i < MAXSTEPS * m_MaxSteps ; i++)
00769 //              {
00770 //                      if ( outofdata ) break;
00771 //                      if ( dtestfail ) break;
00772 //
00773 //                      // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
00774 //                      VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
00775 //                      int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
00776 //                      int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
00777 //                      int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
00778 //                      int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
00779 //
00780 //                      if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
00781 //                      {
00782 //                              // we have reached the border;
00783 //                              outofdata = true;
00784 //                              break;
00785 //                      }
00786 //                      //fetch velocity at the actual position in world coordinates
00787 //                      
00788 //                      //floorx floorz
00789 //                      float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
00790 //                      float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
00791 //                      float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
00792 //                                                              
00793 //                      //floorx ceil           
00794 //                      float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
00795 //                      float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
00796 //                      float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
00797 //                                                                                 
00798 //                      //floorx floorz                            
00799 //                      float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
00800 //                      float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
00801 //                      float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
00802 //                                                              
00803 //                      //floorx floorz         
00804 //                      float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
00805 //                      float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
00806 //                      float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
00807 //
00808 //                      float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
00809 //                      float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
00810 //                      float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
00811 //
00812 //                      float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
00813 //                      float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
00814 //                      float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
00815 //
00816 //                      float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
00817 //                      float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
00818 //                      float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
00819 //
00820 //                      VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
00821 //                      VVector interp_mult = VVector( interpolatedval );
00822 //                      interp_mult.setX( -interp_mult.getX(  ) );
00823 //                      interp_mult *=  0.5f * mStreamlinesDt;
00824 //
00825 //                      //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
00826 //                      VVector oldpos_world = VVector();
00827 //                      oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
00828 //                      oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
00829 //
00830 //                      VVector newpos_world = oldpos_world + interp_mult;
00831 //
00832 //                      VVector newpos_tex = VVector();
00833 //                      newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
00834 //                      newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
00835 //
00836 //                      if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
00837 //                              ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
00838 //                      {
00839 //                              outofdata = true;
00840 //                              break;
00841 //                      }
00842 //                              
00843 //                      sactualpoint_x = newpos_tex.getX();
00844 //                      sactualpoint_y = newpos_tex.getY();
00845 //
00846 //                      //convert to world space
00847 //                      newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
00848 //                      newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
00849 //
00850 //                      //dtest
00851 //                      int cardstr = mEvenlySeedpoints.size();
00852 //                      bool streamline_allowed = false;
00853 //                      for( int i = 0; i < cardstr - 1 ; i++)
00854 //                      {
00855 //                              float dsepworld =  0.25f * mStreamlinesTestSeparation * min( dataextent_x, dataextent_y );
00856 //                              
00857 //                              streamline_allowed = streamlines[ i ].isPointAllowed( VVector(  newpos_tex.getX() , newpos_tex.getY(), 0.0f ), dsepworld, mdistance );
00858 //
00859 //                              if( !streamline_allowed )
00860 //                              {
00861 //                                      dtestfail = true;
00862 //                                      break;
00863 //                              }
00864 //                      }
00865 //
00866 //                      if ( dtestfail ) break;
00867 //
00868 //                      streamlinevertices.push_back( newpos_tex );
00869 //                      vertexthickness.push_back( mdistance[ 0 ] );
00870 //
00871 //                      float epsilon = 0.0000001f;
00872 //                      VVector posdifference = VVector();
00873 //
00874 //                      if( streamlinevertices.size() > 1 )
00875 //                      {
00876 //                              VVector posdifference = streamlinevertices[ streamlinevertices.size() - 1 ] - streamlinevertices[ streamlinevertices.size() - 2 ];
00877 //                      }
00878 //
00879 //                      if ( posdifference.getMagnitude() < epsilon)
00880 //                      {
00881 //                              outofdata = true;
00882 //                              break;
00883 //                      }
00884 //
00885 //              }
00886 //
00887 //              if( !dtestfail )  // donot continue the streamline
00888 //
00889 //              {
00890 //                      //revert the streamline poitns vector and ocntinue in the opposite direction
00891 //                      if( !streamlinevertices.empty() ) 
00892 //                      {
00893 //                              std::vector< VVector > _streamlinesvertices;
00894 //                              for( int k = 0; k < streamlinevertices.size(); k++)
00895 //                              {
00896 //                                      _streamlinesvertices.push_back( streamlinevertices[ streamlinevertices.size() - k - 1 ] );
00897 //                                      
00898 //                              }
00899 //
00900 //                              streamlinevertices.clear();
00901 //                              streamlinevertices.swap( _streamlinesvertices );
00902 //                              _streamlinesvertices.clear();
00903 //                      }
00904 //                      
00905 //
00906 //                      sactualpoint_x = 1.0 - mEvenlySeedpoints[ j ].getX();
00907 //                      sactualpoint_y = mEvenlySeedpoints[ j ].getY();
00908 //
00909 //                      outofdata = false;
00910 //
00911 //                      //and go to the opposite direction
00912 //                      for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
00913 //                      {
00914 //                              if ( outofdata ) break;
00915 //                              if ( dtestfail ) break;
00916 //                              
00917 //                              // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
00918 //                              VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
00919 //                              int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
00920 //                              int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
00921 //                              int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
00922 //                              int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
00923 //
00924 //                              if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
00925 //                              {
00926 //                                      // we have reached the border;
00927 //                                      outofdata = true;
00928 //                                      break;
00929 //                              }
00930 //                              //fetch velocity at the actual position in world coordinates
00931 //                              
00932 //                              //floorx floorz
00933 //                              float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
00934 //                              float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
00935 //                              float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
00936 //                                                                      
00937 //                              //floorx ceil           
00938 //                              float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
00939 //                              float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
00940 //                              float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
00941 //                                                                                         
00942 //                              //floorx floorz                            
00943 //                              float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
00944 //                              float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
00945 //                              float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
00946 //                                                                      
00947 //                              //floorx floorz         
00948 //                              float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
00949 //                              float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
00950 //                              float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
00951 //
00952 //                              float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
00953 //                              float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
00954 //                              float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
00955 //
00956 //                              float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
00957 //                              float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
00958 //                              float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
00959 //
00960 //                              float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
00961 //                              float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
00962 //                              float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
00963 //
00964 //                              VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
00965 //                              VVector interp_mult = VVector( interpolatedval );
00966 //                              interp_mult.setX( -interp_mult.getX(  ) );
00967 //                              interp_mult *=  0.5f *mStreamlinesDt;
00968 //
00969 //                              //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
00970 //                              VVector oldpos_world = VVector();
00971 //                              oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
00972 //                              oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
00973 //
00974 //                              VVector newpos_world = oldpos_world - interp_mult;
00975 //
00976 //                              VVector newpos_tex = VVector();
00977 //                              newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
00978 //                              newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
00979 //
00980 //                              if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
00981 //                                      ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
00982 //                              {
00983 //                                      outofdata = true;
00984 //                                      break;
00985 //                              }
00986 //                                      
00987 //                              sactualpoint_x = newpos_tex.getX();
00988 //                              sactualpoint_y = newpos_tex.getY();
00989 //                              
00990 //                              //convert to world space
00991 //                              newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
00992 //                              newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
00993 //
00994 //                              //dtest
00995 //                              int cardstr = mEvenlySeedpoints.size();
00996 //                              bool streamline_allowed = false;
00997 //                              for( int i = 0; i < cardstr - 1; i++)
00998 //                              {
00999 //                                      float dsepworld =  0.25f * mStreamlinesTestSeparation * min( dataextent_x, dataextent_y );
01000 //                                      
01001 //                                      streamline_allowed = streamlines[ i ].isPointAllowed( VVector(  newpos_tex.getX() , newpos_tex.getY(), 0.0f ), dsepworld, mdistance );
01002 //
01003 //                                      if( !streamline_allowed )
01004 //                                      {
01005 //                                              dtestfail = true;
01006 //                                              break;
01007 //                                      }
01008 //                              }
01009 //
01010 //                              if ( dtestfail ) break;
01011 //
01012 //                              streamlinevertices.push_back( newpos_tex );
01013 //                              vertexthickness.push_back( mdistance[ 0 ] );
01014 //
01015 //                              float epsilon = 0.0000001f;
01016 //                              VVector posdifference = streamlinevertices[ streamlinevertices.size() - 1 ] - streamlinevertices[ streamlinevertices.size() - 2 ];
01017 //                              if ( posdifference.getMagnitude() < epsilon)
01018 //                              {
01019 //                                      outofdata = true;
01020 //                                      break;
01021 //                              }
01022 //
01023 //                      }
01024 //
01025 //              }
01026 //
01027 //              if( !streamlinevertices.empty() ) 
01028 //              {
01029 //                      streamlines[ j ] = VStreamLine( streamlinevertices ) ;
01030 //                      float dsepworld =  0.25f * mStreamlinesSeedSeparation * min( dataextent_x, dataextent_y );
01031 //                      float dtestworld =  0.25f * mStreamlinesTestSeparation * min( dataextent_x, dataextent_y );
01032 //                      streamlines[ j ].setSeparation( dsepworld, dtestworld );
01033 //              }
01034 //      }
01035 //      
01036 //      //delete pixeldata;
01037 //      pixeldata.clear();
01038 //}
01039 //
01040 
01041 
01042 void VFlowData::drawStreamlinesFromSeedpoints( float m_TimeStep, float m_MaxSteps  )
01043 {
01044         if( mNumStreamlines != 0 )
01045         {
01046                 if ( streamlines )
01047                 {
01048                         delete[] streamlines;
01049                         streamlines = NULL;
01050                         mNumStreamlines = 0;
01051                 }
01052         }
01053         //float *pixeldata; // velocoty texture
01054         std::vector< float > pixeldata;
01055 
01056         int texsize_x, texsize_y;
01057 
01058         float dataextent_x, dataextent_y;
01059         float datacenter_x, datacenter_y;
01060         float minx, miny;
01061 
01062         dataextent_x = mExtends.getX();
01063         dataextent_y = mExtends.getY();
01064         datacenter_x = mCenterPos.getX();
01065         datacenter_y = mCenterPos.getY();
01066         minx = mMinPos.getX();
01067         miny = mMinPos.getY();
01068 
01069         //float keepratiox = ( dataextent_x > dataextent_y ) ? 1.0f  : dataextent_x / dataextent_y;
01070         //float keepratioy = ( dataextent_y > dataextent_x ) ? 1.0f  : dataextent_y / dataextent_x;
01071 
01072         // generate seedpoints in texture coordinates
01073         float numbersteamlines = mManualSeedpoints.size();
01074 
01075         pixeldata = mTimeSteps[m_TimeStep].getFullFBODataVector();
01076         texsize_x = mTimeSteps[m_TimeStep].mFrameBufferObject->getWidth();
01077         texsize_y = mTimeSteps[m_TimeStep].mFrameBufferObject->getHeight();
01078 
01079         int size = (int)pixeldata.size();
01080 
01081         
01082         // for all streamlines
01083         mNumStreamlines = numbersteamlines;
01084         streamlines = new VStreamLine[ (int)numbersteamlines + 1 ];
01085 
01086         for ( int j = 0; j < numbersteamlines; j++ )
01087         {
01088 
01089                 std::vector< VVector > streamlinevertices;
01090                 
01091                 bool outofdata = false;
01092 
01093                 float sactualpoint_x = 1.0f - mManualSeedpoints[ j ].getX();
01094                 float sactualpoint_y = mManualSeedpoints[ j ].getY();
01095 
01096                 VVector start_tex = VVector();
01097                 start_tex.setX( sactualpoint_x  );
01098                 start_tex.setY( sactualpoint_y  );
01099 
01100                 VVector start_world = VVector( start_tex );
01101                 
01102                 //TODO:
01103                 //convert to world space
01104                 start_world.setX( -( start_world.getX() * dataextent_x ) + minx + dataextent_x);
01105                 start_world.setY( ( start_world.getY() * dataextent_y ) + miny );
01106                 streamlinevertices.push_back( start_world );
01107 
01108                 for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
01109                 {
01110                         if (outofdata ) break;
01111 
01112                         // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
01113                         VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
01114                         int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
01115                         int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
01116                         int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
01117                         int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
01118 
01119                         if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
01120                         {
01121                                 // we have reached the border;
01122                                 outofdata = true;
01123                                 break;
01124                         }
01125                         //fetch velocity at the actual position in world coordinates
01126                         
01127                         //floorx floorz
01128                         float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
01129                         float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
01130                         float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
01131                                                                 
01132                         //floorx ceil           
01133                         float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
01134                         float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
01135                         float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
01136                                                                                    
01137                         //floorx floorz                            
01138                         float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
01139                         float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
01140                         float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
01141                                                                 
01142                         //floorx floorz         
01143                         float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
01144                         float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
01145                         float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
01146 
01147                         float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
01148                         float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
01149                         float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
01150 
01151                         float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
01152                         float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
01153                         float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
01154 
01155                         float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
01156                         float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
01157                         float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
01158 
01159                         VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
01160                         VVector interp_mult = VVector( interpolatedval );
01161                         interp_mult.setX( -interp_mult.getX(  ) );
01162                         interp_mult *=  0.05f *mStreamlinesDt;
01163 
01164                         //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
01165                         VVector oldpos_world = VVector();
01166                         oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
01167                         oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
01168 
01169                         VVector newpos_world = oldpos_world + interp_mult;
01170 
01171                         VVector newpos_tex = VVector();
01172                         newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
01173                         newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
01174 
01175                         if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
01176                                 ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
01177                         {
01178                                 outofdata = true;
01179                                 break;
01180                         }
01181                                 
01182                         sactualpoint_x = newpos_tex.getX();
01183                         sactualpoint_y = newpos_tex.getY();
01184 
01185                         //TODO:
01186                         //convert to world space
01187                         newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
01188                         newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
01189                         streamlinevertices.push_back( newpos_tex );
01190 
01191                         float epsilon = 0.0000001f;
01192                         VVector posdifference = streamlinevertices[ streamlinevertices.size() - 1 ] - streamlinevertices[ streamlinevertices.size() - 2 ];
01193                         if ( posdifference.getMagnitude() < epsilon)
01194                         {
01195                                 outofdata = true;
01196                                 break;
01197                         }
01198 
01199                 }
01200 
01201                 //revert the streamline poitns vector and ocntinue in the opposite direction
01202                 if( !streamlinevertices.empty() ) 
01203                 {
01204                         std::vector< VVector > _streamlinesvertices;
01205                         for( int k = 0; k < streamlinevertices.size(); k++)
01206                         {
01207                                 _streamlinesvertices.push_back( streamlinevertices[ streamlinevertices.size() - k - 1 ] );
01208                                 
01209                         }
01210 
01211                         streamlinevertices.clear();
01212                         streamlinevertices.swap( _streamlinesvertices );
01213                         _streamlinesvertices.clear();
01214                 }
01215                 
01216 
01217                 sactualpoint_x = 1.0f - mManualSeedpoints[ j ].getX();
01218                 sactualpoint_y = mManualSeedpoints[ j ].getY();
01219 
01220                 outofdata = false;
01221 
01222                 //and go to the opposite direction
01223                 for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
01224                 {
01225                         if (outofdata ) break;
01226 
01227                         
01228                         // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
01229                         VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
01230                         int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
01231                         int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
01232                         int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
01233                         int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
01234 
01235                         if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
01236                         {
01237                                 // we have reached the border;
01238                                 outofdata = true;
01239                                 break;
01240                         }
01241                         //fetch velocity at the actual position in world coordinates
01242                         
01243                         //floorx floorz
01244                         float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
01245                         float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
01246                         float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
01247                                                                 
01248                         //floorx ceil           
01249                         float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
01250                         float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
01251                         float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
01252                                                                                    
01253                         //floorx floorz                            
01254                         float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
01255                         float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
01256                         float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
01257                                                                 
01258                         //floorx floorz         
01259                         float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
01260                         float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
01261                         float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
01262 
01263                         float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
01264                         float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
01265                         float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
01266 
01267                         float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
01268                         float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
01269                         float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
01270 
01271                         float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
01272                         float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
01273                         float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
01274 
01275                         VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
01276                         VVector interp_mult = VVector( interpolatedval );
01277                         interp_mult.setX( -interp_mult.getX(  ) );
01278                         interp_mult *=  0.05f *mStreamlinesDt;
01279 
01280                         //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
01281                         VVector oldpos_world = VVector();
01282                         oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
01283                         oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
01284 
01285                         VVector newpos_world = oldpos_world - interp_mult;
01286 
01287                         VVector newpos_tex = VVector();
01288                         newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
01289                         newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
01290 
01291                         if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
01292                                 ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
01293                         {
01294                                 outofdata = true;
01295                                 break;
01296                         }
01297                                 
01298                         sactualpoint_x = newpos_tex.getX();
01299                         sactualpoint_y = newpos_tex.getY();
01300 
01301                         //TODO:
01302                         //convert to world space
01303                         newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
01304                         newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
01305                         streamlinevertices.push_back( newpos_tex );
01306 
01307                         float epsilon = 0.0000001f;
01308                         VVector posdifference = streamlinevertices[ streamlinevertices.size() - 1 ] - streamlinevertices[ streamlinevertices.size() - 2 ];
01309                         if ( posdifference.getMagnitude() < epsilon)
01310                         {
01311                                 outofdata = true;
01312                                 break;
01313                         }
01314 
01315                 }
01316                 if( !streamlinevertices.empty() ) 
01317                 {
01318                         streamlines[ j ] = VStreamLine( streamlinevertices ) ;
01319                         streamlines[ j ].regenerateVBO();
01320                 }
01321         }
01322         
01323         //delete pixeldata;
01324         pixeldata.clear();
01325 
01326 }
01327 
01328 //declacrations
01329 
01330 #define _LEFT           0
01331 #define _TOP            1
01332 #define _RIGHT          2
01333 #define _BOTTOM         3
01334 #define _ALL            4
01335 #define _RANDOM         5
01336 #define _MANUAL         6
01337 #define _EVEN           7
01338 
01339 bool VFlowData::isIndexOfManualPlacingMethod( int val )
01340 {
01341         return ( val == _MANUAL );
01342 }
01343 
01344 bool VFlowData::isIndexOfEvenPlacingMethod( int val )
01345 {
01346         return ( val == _EVEN);
01347 }
01348 
01349 void VFlowData::setPlacingMethod( int mode )
01350 {
01351         
01352         mEvenlySeedpoints.clear();
01353         mManualSeedpoints.clear();
01354         
01355         if( mNumStreamlines != 0 )
01356         {
01357                 if ( streamlines )
01358                 {
01359                         delete[] streamlines;
01360                         streamlines = NULL;
01361                         mNumStreamlines = 0;
01362                 }
01363         }
01364 
01365         switch ( mode )
01366         {
01367                 case _LEFT:
01368                         {
01369                                 mSeedPlacing = LEFT;
01370                                 break;
01371                         }
01372                         
01373                 case _TOP:
01374                         {
01375                                 mSeedPlacing = TOP;
01376                                 break;
01377                         }
01378                         
01379                 case _RIGHT:
01380                         {
01381                                 mSeedPlacing = RIGHT;
01382                                 break;
01383                         }
01384                         
01385                 case _BOTTOM:
01386                         {
01387                                 mSeedPlacing = BOTTOM;
01388                                 break;
01389                         }
01390                 case _ALL:
01391                 {
01392                         mSeedPlacing = ALL;
01393                         break;
01394                 }
01395                         
01396                 case _RANDOM:
01397                         {
01398                                 mSeedPlacing = RANDOM;
01399                                 break;
01400                         }
01401                         
01402                 case _MANUAL:
01403                         {
01404                                 mSeedPlacing = MANUAL;
01405                                 break;
01406                         }
01407                         
01408                 case _EVEN:
01409                         {
01410                                 mSeedPlacing = EVEN;
01411                                 break;
01412                         }
01413         
01414         }
01415         
01416         
01417 }
01418 
01419 
01420 void VFlowData::loadStreamLines( std::string m_FileName )
01421 {
01422         if( mNumStreamlines != 0 )
01423         {
01424                 for(int i = 0; i < mNumStreamlines; ++i)
01425                 {
01426                         streamlines[i].clearVBO();
01427                 }
01428                 delete[] streamlines;
01429                 streamlines = NULL;
01430         }
01431 
01432         if(m_FileName == "")
01433         {
01434                 return;
01435         }
01436         FILE *fp = NULL;
01437 
01438         fopen_s(&fp,m_FileName.c_str(),"rb");
01439 
01440         if(!fp)
01441         {
01442                 return;
01443         }
01444         unsigned int numLines;
01445 
01446         fread(&numLines,sizeof(unsigned int),1,fp);
01447         mNumStreamlines = (int)numLines;
01448 
01449         streamlines = new VStreamLine[numLines];
01450         
01451         for (int i = 0; i < numLines; ++i )
01452         {
01453                 streamlines[ i ] = VStreamLine();
01454                 streamlines[ i ].loadStreamLine(fp);
01455         }
01456 
01457         fclose(fp);
01458 
01459 }
01460 
01461 void VFlowData::saveStreamLines( std::string m_FileName )
01462 {
01463         if(mNumStreamlines == 0)
01464         {
01465                 return;
01466         }
01467 
01468         if(m_FileName == "")
01469         {
01470                 return;
01471         }
01472         FILE *fp = NULL;
01473 
01474 
01475 
01476         fopen_s(&fp,m_FileName.c_str(),"wb");
01477 
01478         if(!fp)
01479         {
01480                 return;
01481         }
01482         unsigned int numLines = (unsigned int)mNumStreamlines;
01483 
01484         fwrite(reinterpret_cast<char*>(&numLines), sizeof(unsigned int), 1,fp);
01485 
01486         for( int i = 0; i< mNumStreamlines; ++i )
01487         {
01488                 streamlines[i].saveStreamLine(fp);
01489         }
01490         fclose(fp);
01491 }
01492 
01493 void VFlowData::computeIcons()
01494 {
01495         for( int i = 0; i < (int)mIcons.size(); ++i )
01496         {
01497                 mIcons[i].computeIcon( &mTimeSteps[0], mActiveTimeStep );
01498         }
01499 }
01500 
01501 bool VFlowData::getPointAt( VVector *next, std::vector<float> pixeldata, float px, float py, int texsize_x, int texsize_y)
01502 {
01503         return false;
01504 }
01505 
01506 void VFlowData::generateCPUStreamLinesLEFT( float m_MaxSteps, float m_StreamSeparation, int m_TimeStep /* = 0  */ )
01507 {
01508         if( mNumStreamlines != 0 )
01509         {
01510                 if ( streamlines )
01511                 {
01512                         delete[] streamlines;
01513                         streamlines = NULL;
01514                         mNumStreamlines = 0;
01515                 }
01516         }
01517         //float *pixeldata; // velocoty texture
01518         std::vector< float > pixeldata;
01519 
01520         int texsize_x, texsize_y;
01521 
01522         float dataextent_x, dataextent_y;
01523         float datacenter_x, datacenter_y;
01524         float minx, miny;
01525 
01526         dataextent_x = mExtends.getX();
01527         dataextent_y = mExtends.getY();
01528         datacenter_x = mCenterPos.getX();
01529         datacenter_y = mCenterPos.getY();
01530         minx = mMinPos.getX();
01531         miny = mMinPos.getY();
01532 
01533         float keepratiox = ( dataextent_x > dataextent_y ) ? 1.0f  : dataextent_x / dataextent_y;
01534         float keepratioy = ( dataextent_y > dataextent_x ) ? 1.0f  : dataextent_y / dataextent_x;
01535 
01536         // generate seedpoints in texture coordinates
01537         float numbersteamlines = MINNUMBER +  ( 1.0f - m_StreamSeparation ) * ( MAXNUMBER - MINNUMBER );
01538         float spacing = 1.0f / numbersteamlines ;
01539 
01540         pixeldata = mTimeSteps[m_TimeStep].getFullFBODataVector();
01541         texsize_x = mTimeSteps[m_TimeStep].mFrameBufferObject->getWidth();
01542         texsize_y = mTimeSteps[m_TimeStep].mFrameBufferObject->getHeight();
01543 
01544         int size = (int)pixeldata.size();
01545         
01546         // for all streamlines
01547         mNumStreamlines = (int)numbersteamlines;
01548         streamlines = new VStreamLine[ (int)mNumStreamlines + 1 ];
01549 
01550         for ( int j = 0; j <= mNumStreamlines; j++ )
01551         {
01552         
01553                 std::vector< VVector > streamlinevertices;
01554                 
01555                 bool outofdata = false;
01556 
01557                 float offset = (float)( j + 1 ) / ( (float)numbersteamlines + 1.0f );
01558 
01559                 // start left go to right
01560                 float sactualpoint_y = offset - 0.5f * ( 1.0f / texsize_x );
01561                 float sactualpoint_x = 0.0025f - 0.5f * ( 1.0f / texsize_x );
01562                 
01563                 VVector start_tex = VVector();
01564                 start_tex.setX( sactualpoint_x  );
01565                 start_tex.setY( sactualpoint_y  );
01566 
01567                 VVector start_world = VVector( start_tex );
01568                 
01569                 //TODO:
01570                 //convert to world space
01571                 start_world.setX( -( start_world.getX() * dataextent_x ) + minx + dataextent_x);
01572                 start_world.setY( ( start_world.getY() * dataextent_y ) + miny );
01573                 streamlinevertices.push_back( start_world );
01574 
01575                 for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
01576                 {
01577                         if (outofdata ) break;
01578 
01579 
01580                         // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
01581                         VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
01582                         int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
01583                         int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
01584                         int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
01585                         int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
01586 
01587                         if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
01588                         {
01589                                 // we have reached the border;
01590                                 outofdata = true;
01591                                 break;
01592                         }
01593                         //fetch velocity at the actual position in world coordinates
01594                         
01595                         //floorx floorz
01596                         float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
01597                         float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
01598                         float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
01599                                                                 
01600                         //floorx ceil           
01601                         float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
01602                         float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
01603                         float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
01604                                                                                    
01605                         //floorx floorz                            
01606                         float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
01607                         float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
01608                         float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
01609                                                                 
01610                         //floorx floorz         
01611                         float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
01612                         float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
01613                         float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
01614 
01615                         float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
01616                         float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
01617                         float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
01618 
01619                         float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
01620                         float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
01621                         float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
01622 
01623                         float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
01624                         float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
01625                         float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
01626 
01627                         VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
01628                         VVector interp_mult = VVector( interpolatedval );
01629                         interp_mult.setX( -interp_mult.getX(  ) );
01630                         interp_mult *=  0.05f *mStreamlinesDt;
01631 
01632                         //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
01633                         VVector oldpos_world = VVector();
01634                         oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
01635                         oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
01636 
01637                         VVector newpos_world = oldpos_world + interp_mult;
01638 
01639                         VVector newpos_tex = VVector();
01640                         newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
01641                         newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
01642 
01643                         if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
01644                                 ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
01645                         {
01646                                 outofdata = true;
01647                                 break;
01648                         }
01649                                 
01650                         sactualpoint_x = newpos_tex.getX();
01651                         sactualpoint_y = newpos_tex.getY();
01652 
01653                         //TODO:
01654                         //convert to world space
01655                         newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
01656                         newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
01657                         streamlinevertices.push_back( newpos_tex );
01658 
01659                         //if the streamline reached the sink
01660                         float epsilon = 0.0000001f;
01661                         VVector posdifference = streamlinevertices[ streamlinevertices.size() - 1 ] - streamlinevertices[ streamlinevertices.size() - 2 ];
01662                         if ( posdifference.getMagnitude() < epsilon)
01663                         {
01664                                 outofdata = true;
01665                                 break;
01666                         }
01667 
01668                 }
01669                 if( !streamlinevertices.empty() ) 
01670                 {
01671                         streamlines[ j ] = VStreamLine( streamlinevertices ) ;
01672                         streamlines[ j ].regenerateVBO();
01673                 }
01674         }
01675 
01676         
01677         //delete pixeldata;
01678         pixeldata.clear();
01679 
01680 }
01681 
01682 
01683 void VFlowData::generateCPUStreamLinesTOP( float m_MaxSteps, float m_StreamSeparation, int m_TimeStep /* = 0  */ )
01684 {
01685         if( mNumStreamlines != 0 )
01686         {
01687                 if ( streamlines )
01688                 {
01689                         delete[] streamlines;
01690                         streamlines = NULL;
01691                         mNumStreamlines = 0;
01692                 }
01693         }
01694         //float *pixeldata; // velocoty texture
01695         std::vector< float > pixeldata;
01696 
01697         int texsize_x, texsize_y;
01698 
01699         float dataextent_x, dataextent_y;
01700         float datacenter_x, datacenter_y;
01701         float minx, miny;
01702 
01703         dataextent_x = mExtends.getX();
01704         dataextent_y = mExtends.getY();
01705         datacenter_x = mCenterPos.getX();
01706         datacenter_y = mCenterPos.getY();
01707         minx = mMinPos.getX();
01708         miny = mMinPos.getY();
01709 
01710         float keepratiox = ( dataextent_x > dataextent_y ) ? 1.0f  : dataextent_x / dataextent_y;
01711         float keepratioy = ( dataextent_y > dataextent_x ) ? 1.0f  : dataextent_y / dataextent_x;
01712 
01713         // generate seedpoints in texture coordinates
01714         float numbersteamlines = MINNUMBER +  ( 1.0f - m_StreamSeparation ) * ( MAXNUMBER - MINNUMBER );
01715         float spacing = 1.0f / numbersteamlines ;
01716 
01717         pixeldata = mTimeSteps[m_TimeStep].getFullFBODataVector();
01718         texsize_x = mTimeSteps[m_TimeStep].mFrameBufferObject->getWidth();
01719         texsize_y = mTimeSteps[m_TimeStep].mFrameBufferObject->getHeight();
01720 
01721         int size = (int)pixeldata.size();
01722         
01723         // for all streamlines
01724         mNumStreamlines = (int)numbersteamlines;
01725         streamlines = new VStreamLine[ (int)mNumStreamlines + 1 ];
01726 
01727         for ( int j = 0; j <= mNumStreamlines; j++ )
01728         {
01729         
01730                 std::vector< VVector > streamlinevertices;
01731                 
01732                 bool outofdata = false;
01733 
01734                 float offset = (float)( j + 1 ) / ( (float)numbersteamlines + 1.0f );
01735 
01736                 //start top go the bottom
01737                 float sactualpoint_x = offset - 0.5f * ( 1.0f / texsize_x );
01738                 float sactualpoint_y = 1.0f - 0.5f * ( 1.0f / texsize_y );
01739                 
01740                 VVector start_tex = VVector();
01741                 start_tex.setX( sactualpoint_x  );
01742                 start_tex.setY( sactualpoint_y  );
01743 
01744                 VVector start_world = VVector( start_tex );
01745                 
01746                 //TODO:
01747                 //convert to world space
01748                 start_world.setX( -( start_world.getX() * dataextent_x ) + minx + dataextent_x);
01749                 start_world.setY( ( start_world.getY() * dataextent_y ) + miny );
01750                 streamlinevertices.push_back( start_world );
01751 
01752                 for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
01753                 {
01754                         if (outofdata ) break;
01755 
01756 
01757                         // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
01758                         VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
01759                         int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
01760                         int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
01761                         int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
01762                         int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
01763 
01764                         if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
01765                         {
01766                                 // we have reached the border;
01767                                 outofdata = true;
01768                                 break;
01769                         }
01770                         //fetch velocity at the actual position in world coordinates
01771                         
01772                         //floorx floorz
01773                         float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
01774                         float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
01775                         float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
01776                                                                 
01777                         //floorx ceil           
01778                         float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
01779                         float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
01780                         float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
01781                                                                                    
01782                         //floorx floorz                            
01783                         float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
01784                         float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
01785                         float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
01786                                                                 
01787                         //floorx floorz         
01788                         float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
01789                         float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
01790                         float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
01791 
01792                         float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
01793                         float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
01794                         float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
01795 
01796                         float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
01797                         float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
01798                         float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
01799 
01800                         float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
01801                         float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
01802                         float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
01803 
01804                         VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
01805                         VVector interp_mult = VVector( interpolatedval );
01806                         interp_mult.setX( -interp_mult.getX(  ) );
01807                         interp_mult *=  0.05f *mStreamlinesDt;
01808 
01809                         //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
01810                         VVector oldpos_world = VVector();
01811                         oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
01812                         oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
01813 
01814                         VVector newpos_world = oldpos_world + interp_mult;
01815 
01816                         VVector newpos_tex = VVector();
01817                         newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
01818                         newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
01819 
01820                         if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
01821                                 ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
01822                         {
01823                                 outofdata = true;
01824                                 break;
01825                         }
01826                                 
01827                         sactualpoint_x = newpos_tex.getX();
01828                         sactualpoint_y = newpos_tex.getY();
01829 
01830                         //TODO:
01831                         //convert to world space
01832                         newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
01833                         newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
01834                         streamlinevertices.push_back( newpos_tex );
01835 
01836                         //if the streamline reached the sink
01837                         float epsilon = 0.0000001f;
01838                         VVector posdifference = streamlinevertices[ streamlinevertices.size() - 1 ] - streamlinevertices[ streamlinevertices.size() - 2 ];
01839                         if ( posdifference.getMagnitude() < epsilon)
01840                         {
01841                                 outofdata = true;
01842                                 break;
01843                         }
01844 
01845                 }
01846                 if( !streamlinevertices.empty() ) 
01847                 {
01848                         streamlines[ j ] = VStreamLine( streamlinevertices ) ;
01849                         streamlines[ j ].regenerateVBO();
01850                 }
01851         }
01852 
01853         
01854         //delete pixeldata;
01855         pixeldata.clear();
01856 }
01857 
01858 void VFlowData::generateCPUStreamLinesRIGHT( float m_MaxSteps, float m_StreamSeparation, int m_TimeStep /* = 0  */ )
01859 {
01860         if( mNumStreamlines != 0 )
01861         {
01862                 if ( streamlines )
01863                 {
01864                         delete[] streamlines;
01865                         streamlines = NULL;
01866                         mNumStreamlines = 0;
01867                 }
01868         }
01869         //float *pixeldata; // velocoty texture
01870         std::vector< float > pixeldata;
01871 
01872         int texsize_x, texsize_y;
01873 
01874         float dataextent_x, dataextent_y;
01875         float datacenter_x, datacenter_y;
01876         float minx, miny;
01877 
01878         dataextent_x = mExtends.getX();
01879         dataextent_y = mExtends.getY();
01880         datacenter_x = mCenterPos.getX();
01881         datacenter_y = mCenterPos.getY();
01882         minx = mMinPos.getX();
01883         miny = mMinPos.getY();
01884 
01885         float keepratiox = ( dataextent_x > dataextent_y ) ? 1.0f  : dataextent_x / dataextent_y;
01886         float keepratioy = ( dataextent_y > dataextent_x ) ? 1.0f  : dataextent_y / dataextent_x;
01887 
01888         // generate seedpoints in texture coordinates
01889         float numbersteamlines = MINNUMBER +  ( 1.0f - m_StreamSeparation ) * ( MAXNUMBER - MINNUMBER );
01890         float spacing = 1.0f / numbersteamlines ;
01891 
01892         pixeldata = mTimeSteps[m_TimeStep].getFullFBODataVector();
01893         texsize_x = mTimeSteps[m_TimeStep].mFrameBufferObject->getWidth();
01894         texsize_y = mTimeSteps[m_TimeStep].mFrameBufferObject->getHeight();
01895 
01896         int size = (int)pixeldata.size();
01897         
01898         // for all streamlines
01899         mNumStreamlines = (int)numbersteamlines;
01900         streamlines = new VStreamLine[ (int)mNumStreamlines + 1 ];
01901 
01902         for ( int j = 0; j <= mNumStreamlines; j++ )
01903         {
01904         
01905                 std::vector< VVector > streamlinevertices;
01906                 
01907                 bool outofdata = false;
01908 
01909                 float offset = (float)( j + 1 ) / ( (float)numbersteamlines + 1.0f );
01910 
01911                 //start right go the left
01912                 float sactualpoint_y = offset - 0.5f * ( 1.0f / texsize_y );
01913                 float sactualpoint_x = 1.0f - 0.5f * ( 1.0f / texsize_x );
01914                 
01915                 VVector start_tex = VVector();
01916                 start_tex.setX( sactualpoint_x  );
01917                 start_tex.setY( sactualpoint_y  );
01918 
01919                 VVector start_world = VVector( start_tex );
01920                 
01921                 //TODO:
01922                 //convert to world space
01923                 start_world.setX( -( start_world.getX() * dataextent_x ) + minx + dataextent_x);
01924                 start_world.setY( ( start_world.getY() * dataextent_y ) + miny );
01925                 streamlinevertices.push_back( start_world );
01926 
01927                 for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
01928                 {
01929                         if (outofdata ) break;
01930 
01931                         // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
01932                         VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
01933                         int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
01934                         int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
01935                         int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
01936                         int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
01937 
01938                         if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
01939                         {
01940                                 // we have reached the border;
01941                                 outofdata = true;
01942                                 break;
01943                         }
01944                         //fetch velocity at the actual position in world coordinates
01945                         
01946                         //floorx floorz
01947                         float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
01948                         float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
01949                         float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
01950                                                                 
01951                         //floorx ceil           
01952                         float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
01953                         float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
01954                         float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
01955                                                                                    
01956                         //floorx floorz                            
01957                         float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
01958                         float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
01959                         float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
01960                                                                 
01961                         //floorx floorz         
01962                         float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
01963                         float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
01964                         float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
01965 
01966                         float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
01967                         float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
01968                         float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
01969 
01970                         float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
01971                         float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
01972                         float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
01973 
01974                         float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
01975                         float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
01976                         float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
01977 
01978                         VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
01979                         VVector interp_mult = VVector( interpolatedval );
01980                         interp_mult.setX( -interp_mult.getX(  ) );
01981                         interp_mult *=  0.05f *mStreamlinesDt;
01982 
01983                         //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
01984                         VVector oldpos_world = VVector();
01985                         oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
01986                         oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
01987 
01988                         VVector newpos_world = oldpos_world + interp_mult;
01989 
01990                         VVector newpos_tex = VVector();
01991                         newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
01992                         newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
01993 
01994                         if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
01995                                 ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
01996                         {
01997                                 outofdata = true;
01998                                 break;
01999                         }
02000                                 
02001                         sactualpoint_x = newpos_tex.getX();
02002                         sactualpoint_y = newpos_tex.getY();
02003 
02004                         //TODO:
02005                         //convert to world space
02006                         newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
02007                         newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
02008                         streamlinevertices.push_back( newpos_tex );
02009 
02010                         //if the streamline reached the sink
02011                         float epsilon = 0.0000001f;
02012                         VVector posdifference = streamlinevertices[ streamlinevertices.size() - 1 ] - streamlinevertices[ streamlinevertices.size() - 2 ];
02013                         if ( posdifference.getMagnitude() < epsilon)
02014                         {
02015                                 outofdata = true;
02016                                 break;
02017                         }
02018 
02019                 }
02020                 if( !streamlinevertices.empty() ) 
02021                 {
02022                         streamlines[ j ] = VStreamLine( streamlinevertices ) ;
02023                         streamlines[ j ].regenerateVBO();
02024                 }
02025         }
02026 
02027         
02028         //delete pixeldata;
02029         pixeldata.clear();
02030 }
02031 
02032 void VFlowData::generateCPUStreamLinesBOTTOM( float m_MaxSteps, float m_StreamSeparation, int m_TimeStep /* = 0  */ )
02033 {
02034         if( mNumStreamlines != 0 )
02035         {
02036                 if ( streamlines )
02037                 {
02038                         delete[] streamlines;
02039                         streamlines = NULL;
02040                         mNumStreamlines = 0;
02041                 }
02042         }
02043         //float *pixeldata; // velocoty texture
02044         std::vector< float > pixeldata;
02045 
02046         int texsize_x, texsize_y;
02047 
02048         float dataextent_x, dataextent_y;
02049         float datacenter_x, datacenter_y;
02050         float minx, miny;
02051 
02052         dataextent_x = mExtends.getX();
02053         dataextent_y = mExtends.getY();
02054         datacenter_x = mCenterPos.getX();
02055         datacenter_y = mCenterPos.getY();
02056         minx = mMinPos.getX();
02057         miny = mMinPos.getY();
02058 
02059         float keepratiox = ( dataextent_x > dataextent_y ) ? 1.0f  : dataextent_x / dataextent_y;
02060         float keepratioy = ( dataextent_y > dataextent_x ) ? 1.0f  : dataextent_y / dataextent_x;
02061 
02062         // generate seedpoints in texture coordinates
02063         float numbersteamlines = MINNUMBER +  ( 1.0f - m_StreamSeparation ) * ( MAXNUMBER - MINNUMBER );
02064         float spacing = 1.0f / numbersteamlines ;
02065 
02066         pixeldata = mTimeSteps[m_TimeStep].getFullFBODataVector();
02067         texsize_x = mTimeSteps[m_TimeStep].mFrameBufferObject->getWidth();
02068         texsize_y = mTimeSteps[m_TimeStep].mFrameBufferObject->getHeight();
02069 
02070         int size = (int)pixeldata.size();
02071         
02072         // for all streamlines
02073         mNumStreamlines = (int)numbersteamlines;
02074         streamlines = new VStreamLine[ (int)mNumStreamlines + 1 ];
02075 
02076         for ( int j = 0; j <= mNumStreamlines; j++ )
02077         {
02078         
02079                 std::vector< VVector > streamlinevertices;
02080                 
02081                 bool outofdata = false;
02082 
02083                 float offset = (float)( j + 1 ) / ( (float)numbersteamlines + 1.0f );
02084 
02085                 //start bottom go the top
02086                 float sactualpoint_x = offset - 0.5f * ( 1.0f / texsize_x );
02087                 float sactualpoint_y = 0.0025f - 0.5f * ( 1.0f / texsize_y );
02088 
02089                 
02090                 VVector start_tex = VVector();
02091                 start_tex.setX( sactualpoint_x  );
02092                 start_tex.setY( sactualpoint_y  );
02093 
02094                 VVector start_world = VVector( start_tex );
02095                 
02096                 //TODO:
02097                 //convert to world space
02098                 start_world.setX( -( start_world.getX() * dataextent_x ) + minx + dataextent_x);
02099                 start_world.setY( ( start_world.getY() * dataextent_y ) + miny );
02100                 streamlinevertices.push_back( start_world );
02101 
02102                 for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
02103                 {
02104                         if (outofdata ) break;
02105 
02106                         // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
02107                         VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
02108                         int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
02109                         int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
02110                         int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
02111                         int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
02112 
02113                         if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
02114                         {
02115                                 // we have reached the border;
02116                                 outofdata = true;
02117                                 break;
02118                         }
02119                         //fetch velocity at the actual position in world coordinates
02120                         
02121                         //floorx floorz
02122                         float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
02123                         float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
02124                         float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
02125                                                                 
02126                         //floorx ceil           
02127                         float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
02128                         float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
02129                         float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
02130                                                                                    
02131                         //floorx floorz                            
02132                         float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
02133                         float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
02134                         float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
02135                                                                 
02136                         //floorx floorz         
02137                         float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
02138                         float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
02139                         float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
02140 
02141                         float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
02142                         float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
02143                         float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
02144 
02145                         float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
02146                         float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
02147                         float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
02148 
02149                         float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
02150                         float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
02151                         float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
02152 
02153                         VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
02154                         VVector interp_mult = VVector( interpolatedval );
02155                         interp_mult.setX( -interp_mult.getX(  ) );
02156                         interp_mult *=  0.05f *mStreamlinesDt;
02157 
02158                         //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
02159                         VVector oldpos_world = VVector();
02160                         oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
02161                         oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
02162 
02163                         VVector newpos_world = oldpos_world + interp_mult;
02164 
02165                         VVector newpos_tex = VVector();
02166                         newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
02167                         newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
02168 
02169                         if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
02170                                 ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
02171                         {
02172                                 outofdata = true;
02173                                 break;
02174                         }
02175                                 
02176                         sactualpoint_x = newpos_tex.getX();
02177                         sactualpoint_y = newpos_tex.getY();
02178 
02179                         //TODO:
02180                         //convert to world space
02181                         newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
02182                         newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
02183                         streamlinevertices.push_back( newpos_tex );
02184 
02185                         //if the streamline reached the sink
02186                         float epsilon = 0.0000001f;
02187                         VVector posdifference = streamlinevertices[ streamlinevertices.size() - 1 ] - streamlinevertices[ streamlinevertices.size() - 2 ];
02188                         if ( posdifference.getMagnitude() < epsilon)
02189                         {
02190                                 outofdata = true;
02191                                 break;
02192                         }
02193 
02194                 }
02195                 if( !streamlinevertices.empty() ) 
02196                 {
02197                         streamlines[ j ] = VStreamLine( streamlinevertices ) ;
02198                         streamlines[ j ].regenerateVBO();
02199                 }
02200         }
02201 
02202         
02203         //delete pixeldata;
02204         pixeldata.clear();
02205 
02206 }
02207 
02208 void VFlowData::generateCPUStreamLinesALL( float m_MaxSteps, float m_StreamSeparation, int m_TimeStep /* = 0  */ )
02209 {
02210 
02211         if( mNumStreamlines != 0 )
02212         {
02213                 if ( streamlines )
02214                 {
02215                         delete[] streamlines;
02216                         streamlines = NULL;
02217                         mNumStreamlines = 0;
02218                 }
02219         }
02220         //float *pixeldata; // velocoty texture
02221         std::vector< float > pixeldata;
02222 
02223         int texsize_x, texsize_y;
02224 
02225         float dataextent_x, dataextent_y;
02226         float datacenter_x, datacenter_y;
02227         float minx, miny;
02228 
02229         dataextent_x = mExtends.getX();
02230         dataextent_y = mExtends.getY();
02231         datacenter_x = mCenterPos.getX();
02232         datacenter_y = mCenterPos.getY();
02233         minx = mMinPos.getX();
02234         miny = mMinPos.getY();
02235 
02236         float keepratiox = ( dataextent_x > dataextent_y ) ? 1.0f  : dataextent_x / dataextent_y;
02237         float keepratioy = ( dataextent_y > dataextent_x ) ? 1.0f  : dataextent_y / dataextent_x;
02238 
02239         // generate seedpoints in texture coordinates
02240         float qnumbersteamlines = MINNUMBER +  ( 1.0f - m_StreamSeparation ) * ( MAXNUMBER - MINNUMBER );
02241         float spacing = 1.0f / qnumbersteamlines ;
02242 
02243         pixeldata = mTimeSteps[m_TimeStep].getFullFBODataVector();
02244         texsize_x = mTimeSteps[m_TimeStep].mFrameBufferObject->getWidth();
02245         texsize_y = mTimeSteps[m_TimeStep].mFrameBufferObject->getHeight();
02246 
02247         int size = (int)pixeldata.size();
02248         
02249         // for all streamlines
02250         mNumStreamlines = 4 * (int)qnumbersteamlines;
02251         streamlines = new VStreamLine[ (int)mNumStreamlines + 4 ];
02252 
02253         //from bottom to top
02254         for ( int j = 0; j <= qnumbersteamlines; j++ )
02255         {
02256         
02257                 std::vector< VVector > streamlinevertices;
02258                 
02259                 bool outofdata = false;
02260 
02261                 float offset = (float)( j + 1 ) / ( (float)qnumbersteamlines + 1.0f );
02262 
02263                 //start bottom go the top
02264                 float sactualpoint_x = offset - 0.5f * ( 1.0f / texsize_x );
02265                 float sactualpoint_y = 0.0025f - 0.5f * ( 1.0f / texsize_y );
02266                 
02267                 VVector start_tex = VVector();
02268                 start_tex.setX( sactualpoint_x  );
02269                 start_tex.setY( sactualpoint_y  );
02270 
02271                 VVector start_world = VVector( start_tex );
02272                 
02273                 //TODO:
02274                 //convert to world space
02275                 start_world.setX( -( start_world.getX() * dataextent_x ) + minx + dataextent_x);
02276                 start_world.setY( ( start_world.getY() * dataextent_y ) + miny );
02277                 streamlinevertices.push_back( start_world );
02278 
02279                 for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
02280                 {
02281                         if (outofdata ) break;
02282 
02283 
02284                         // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
02285                         VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
02286                         int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
02287                         int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
02288                         int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
02289                         int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
02290 
02291                         if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
02292                         {
02293                                 // we have reached the border;
02294                                 outofdata = true;
02295                                 break;
02296                         }
02297                         //fetch velocity at the actual position in world coordinates
02298                         
02299                         //floorx floorz
02300                         float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
02301                         float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
02302                         float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
02303                                                                 
02304                         //floorx ceil           
02305                         float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
02306                         float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
02307                         float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
02308                                                                                    
02309                         //floorx floorz                            
02310                         float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
02311                         float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
02312                         float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
02313                                                                 
02314                         //floorx floorz         
02315                         float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
02316                         float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
02317                         float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
02318 
02319                         float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
02320                         float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
02321                         float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
02322 
02323                         float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
02324                         float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
02325                         float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
02326 
02327                         float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
02328                         float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
02329                         float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
02330 
02331                         VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
02332                         VVector interp_mult = VVector( interpolatedval );
02333                         interp_mult.setX( -interp_mult.getX(  ) );
02334                         interp_mult *=  0.05f *mStreamlinesDt;
02335 
02336                         //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
02337                         VVector oldpos_world = VVector();
02338                         oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
02339                         oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
02340 
02341                         VVector newpos_world = oldpos_world + interp_mult;
02342 
02343                         VVector newpos_tex = VVector();
02344                         newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
02345                         newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
02346 
02347                         if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
02348                                 ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
02349                         {
02350                                 outofdata = true;
02351                                 break;
02352                         }
02353                                 
02354                         sactualpoint_x = newpos_tex.getX();
02355                         sactualpoint_y = newpos_tex.getY();
02356 
02357                         //TODO:
02358                         //convert to world space
02359                         newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
02360                         newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
02361                         streamlinevertices.push_back( newpos_tex );
02362 
02363                         //if the streamline reached the sink
02364                         float epsilon = 0.0000001f;
02365                         VVector posdifference = streamlinevertices[ streamlinevertices.size() - 1 ] - streamlinevertices[ streamlinevertices.size() - 2 ];
02366                         if ( posdifference.getMagnitude() < epsilon)
02367                         {
02368                                 outofdata = true;
02369                                 break;
02370                         }
02371 
02372                 }
02373                 if( !streamlinevertices.empty() ) 
02374                 {
02375                         streamlines[ j ] = VStreamLine( streamlinevertices ) ;
02376                         streamlines[ j ].regenerateVBO();
02377                 }
02378         }
02379 
02380         //from left to right
02381         for ( int j = 0; j <= qnumbersteamlines; j++ )
02382         {
02383         
02384                 std::vector< VVector > streamlinevertices;
02385                 
02386                 bool outofdata = false;
02387 
02388                 float offset = (float)( j + 1 ) / ( (float)qnumbersteamlines + 1.0f );
02389 
02390                 // start left go to right
02391                 float sactualpoint_y = offset - 0.5f * ( 1.0f / texsize_x );
02392                 float sactualpoint_x = 0.0025f - 0.5f * ( 1.0f / texsize_x );
02393                 
02394                 VVector start_tex = VVector();
02395                 start_tex.setX( sactualpoint_x  );
02396                 start_tex.setY( sactualpoint_y  );
02397 
02398                 VVector start_world = VVector( start_tex );
02399                 
02400                 //TODO:
02401                 //convert to world space
02402                 start_world.setX( -( start_world.getX() * dataextent_x ) + minx + dataextent_x);
02403                 start_world.setY( ( start_world.getY() * dataextent_y ) + miny );
02404                 streamlinevertices.push_back( start_world );
02405 
02406                 for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
02407                 {
02408                         if (outofdata ) break;
02409 
02410                         // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
02411                         VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
02412                         int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
02413                         int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
02414                         int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
02415                         int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
02416 
02417                         if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
02418                         {
02419                                 // we have reached the border;
02420                                 outofdata = true;
02421                                 break;
02422                         }
02423                         //fetch velocity at the actual position in world coordinates
02424                         
02425                         //floorx floorz
02426                         float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
02427                         float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
02428                         float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
02429                                                                 
02430                         //floorx ceil           
02431                         float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
02432                         float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
02433                         float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
02434                                                                                    
02435                         //floorx floorz                            
02436                         float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
02437                         float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
02438                         float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
02439                                                                 
02440                         //floorx floorz         
02441                         float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
02442                         float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
02443                         float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
02444 
02445                         float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
02446                         float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
02447                         float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
02448 
02449                         float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
02450                         float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
02451                         float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
02452 
02453                         float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
02454                         float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
02455                         float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
02456 
02457                         VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
02458                         VVector interp_mult = VVector( interpolatedval );
02459                         interp_mult.setX( -interp_mult.getX(  ) );
02460                         interp_mult *=  0.05f *mStreamlinesDt;
02461 
02462                         //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
02463                         VVector oldpos_world = VVector();
02464                         oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
02465                         oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
02466 
02467                         VVector newpos_world = oldpos_world + interp_mult;
02468 
02469                         VVector newpos_tex = VVector();
02470                         newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
02471                         newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
02472 
02473                         if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
02474                                 ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
02475                         {
02476                                 outofdata = true;
02477                                 break;
02478                         }
02479                                 
02480                         sactualpoint_x = newpos_tex.getX();
02481                         sactualpoint_y = newpos_tex.getY();
02482 
02483                         //TODO:
02484                         //convert to world space
02485                         newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
02486                         newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
02487                         streamlinevertices.push_back( newpos_tex );
02488 
02489                         //if the streamline reached the sink
02490                         float epsilon = 0.0000001f;
02491                         VVector posdifference = streamlinevertices[ streamlinevertices.size() - 1 ] - streamlinevertices[ streamlinevertices.size() - 2 ];
02492                         if ( posdifference.getMagnitude() < epsilon)
02493                         {
02494                                 outofdata = true;
02495                                 break;
02496                         }
02497 
02498                 }
02499                 if( !streamlinevertices.empty() ) 
02500                 {
02501                         streamlines[ j + (int)qnumbersteamlines ] = VStreamLine( streamlinevertices ) ;
02502                         streamlines[ j + (int)qnumbersteamlines ].regenerateVBO();
02503                 }
02504         }
02505 
02506         //start top to bottom
02507         for ( int j = 0; j <= qnumbersteamlines; j++ )
02508         {
02509         
02510                 std::vector< VVector > streamlinevertices;
02511                 
02512                 bool outofdata = false;
02513 
02514                 float offset = (float)( j + 1 ) / ( (float)qnumbersteamlines + 1.0f );
02515 
02516                 //start top go the bottom
02517                 float sactualpoint_x = offset - 0.5f * ( 1.0f / texsize_x );
02518                 float sactualpoint_y = 1.0f - 0.5f * ( 1.0f / texsize_y );
02519                 
02520                 VVector start_tex = VVector();
02521                 start_tex.setX( sactualpoint_x  );
02522                 start_tex.setY( sactualpoint_y  );
02523 
02524                 VVector start_world = VVector( start_tex );
02525                 
02526                 //TODO:
02527                 //convert to world space
02528                 start_world.setX( -( start_world.getX() * dataextent_x ) + minx + dataextent_x);
02529                 start_world.setY( ( start_world.getY() * dataextent_y ) + miny );
02530                 streamlinevertices.push_back( start_world );
02531 
02532                 for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
02533                 {
02534                         if (outofdata ) break;
02535 
02536                         // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
02537                         VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
02538                         int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
02539                         int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
02540                         int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
02541                         int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
02542 
02543                         if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
02544                         {
02545                                 // we have reached the border;
02546                                 outofdata = true;
02547                                 break;
02548                         }
02549                         //fetch velocity at the actual position in world coordinates
02550                         
02551                         //floorx floorz
02552                         float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
02553                         float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
02554                         float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
02555                                                                 
02556                         //floorx ceil           
02557                         float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
02558                         float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
02559                         float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
02560                                                                                    
02561                         //floorx floorz                            
02562                         float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
02563                         float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
02564                         float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
02565                                                                 
02566                         //floorx floorz         
02567                         float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
02568                         float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
02569                         float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
02570 
02571                         float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
02572                         float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
02573                         float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
02574 
02575                         float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
02576                         float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
02577                         float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
02578 
02579                         float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
02580                         float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
02581                         float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
02582 
02583                         VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
02584                         VVector interp_mult = VVector( interpolatedval );
02585                         interp_mult.setX( -interp_mult.getX(  ) );
02586                         interp_mult *=  0.05f *mStreamlinesDt;
02587 
02588                         //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
02589                         VVector oldpos_world = VVector();
02590                         oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
02591                         oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
02592 
02593                         VVector newpos_world = oldpos_world + interp_mult;
02594 
02595                         VVector newpos_tex = VVector();
02596                         newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
02597                         newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
02598 
02599                         if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
02600                                 ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
02601                         {
02602                                 outofdata = true;
02603                                 break;
02604                         }
02605                                 
02606                         sactualpoint_x = newpos_tex.getX();
02607                         sactualpoint_y = newpos_tex.getY();
02608 
02609                         //TODO:
02610                         //convert to world space
02611                         newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
02612                         newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
02613                         streamlinevertices.push_back( newpos_tex );
02614 
02615                         //if the streamline reached the sink
02616                         float epsilon = 0.0000001f;
02617                         VVector posdifference = streamlinevertices[ streamlinevertices.size() - 1 ] - streamlinevertices[ streamlinevertices.size() - 2 ];
02618                         if ( posdifference.getMagnitude() < epsilon)
02619                         {
02620                                 outofdata = true;
02621                                 break;
02622                         }
02623 
02624                 }
02625                 if( !streamlinevertices.empty() ) 
02626                 {
02627                         streamlines[ j + 2 * (int)qnumbersteamlines ] = VStreamLine( streamlinevertices ) ;
02628                         streamlines[ j + 2 * (int)qnumbersteamlines ].regenerateVBO();
02629                 }
02630         }
02631         
02632         //start right go the left
02633         for ( int j = 0; j <= qnumbersteamlines; j++ )
02634         {
02635         
02636                 std::vector< VVector > streamlinevertices;
02637                 
02638                 bool outofdata = false;
02639 
02640                 float offset = (float)( j + 1 ) / ( (float)qnumbersteamlines + 1.0f );
02641 
02642                 //start right go the left
02643                 float sactualpoint_y = offset - 0.5f * ( 1.0f / texsize_y );
02644                 float sactualpoint_x = 1.0f - 0.5f * ( 1.0f / texsize_x );
02645                 
02646                 VVector start_tex = VVector();
02647                 start_tex.setX( sactualpoint_x  );
02648                 start_tex.setY( sactualpoint_y  );
02649 
02650                 VVector start_world = VVector( start_tex );
02651                 
02652                 //TODO:
02653                 //convert to world space
02654                 start_world.setX( -( start_world.getX() * dataextent_x ) + minx + dataextent_x);
02655                 start_world.setY( ( start_world.getY() * dataextent_y ) + miny );
02656                 streamlinevertices.push_back( start_world );
02657 
02658                 for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
02659                 {
02660                         if (outofdata ) break;
02661 
02662                         // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
02663                         VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
02664                         int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
02665                         int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
02666                         int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
02667                         int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
02668 
02669                         if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
02670                         {
02671                                 // we have reached the border;
02672                                 outofdata = true;
02673                                 break;
02674                         }
02675                         //fetch velocity at the actual position in world coordinates
02676                         
02677                         //floorx floorz
02678                         float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
02679                         float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
02680                         float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
02681                                                                 
02682                         //floorx ceil           
02683                         float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
02684                         float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
02685                         float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
02686                                                                                    
02687                         //floorx floorz                            
02688                         float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
02689                         float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
02690                         float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
02691                                                                 
02692                         //floorx floorz         
02693                         float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
02694                         float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
02695                         float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
02696 
02697                         float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
02698                         float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
02699                         float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
02700 
02701                         float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
02702                         float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
02703                         float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
02704 
02705                         float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
02706                         float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
02707                         float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
02708 
02709                         VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
02710                         VVector interp_mult = VVector( interpolatedval );
02711                         interp_mult.setX( -interp_mult.getX(  ) );
02712                         interp_mult *=  0.05f *mStreamlinesDt;
02713 
02714                         //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
02715                         VVector oldpos_world = VVector();
02716                         oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
02717                         oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
02718 
02719                         VVector newpos_world = oldpos_world + interp_mult;
02720 
02721                         VVector newpos_tex = VVector();
02722                         newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
02723                         newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
02724 
02725                         if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
02726                                 ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
02727                         {
02728                                 outofdata = true;
02729                                 break;
02730                         }
02731                                 
02732                         sactualpoint_x = newpos_tex.getX();
02733                         sactualpoint_y = newpos_tex.getY();
02734 
02735                         //TODO:
02736                         //convert to world space
02737                         newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
02738                         newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
02739                         streamlinevertices.push_back( newpos_tex );
02740 
02741                         //if the streamline reached the sink
02742                         float epsilon = 0.0000001f;
02743                         VVector posdifference = streamlinevertices[ streamlinevertices.size() - 1 ] - streamlinevertices[ streamlinevertices.size() - 2 ];
02744                         if ( posdifference.getMagnitude() < epsilon)
02745                         {
02746                                 outofdata = true;
02747                                 break;
02748                         }
02749 
02750                 }
02751                 if( !streamlinevertices.empty() ) 
02752                 {
02753                         streamlines[ j + 3 * (int)qnumbersteamlines ] = VStreamLine( streamlinevertices ) ;
02754                         streamlines[ j + 3 * (int)qnumbersteamlines ].regenerateVBO();
02755                 }
02756         }
02757 
02758 
02759         //delete pixeldata;
02760         pixeldata.clear();
02761 
02762 }
02763 
02764 void VFlowData::generateCPUStreamLinesRANDOM( float m_MaxSteps, float m_StreamSeparation, int m_TimeStep /* = 0  */ )
02765 {
02766         if( mNumStreamlines != 0 )
02767         {
02768                 if ( streamlines )
02769                 {
02770                         delete[] streamlines;
02771                         streamlines = NULL;
02772                         mNumStreamlines = 0;
02773                 }
02774         }
02775         //float *pixeldata; // velocoty texture
02776         std::vector< float > pixeldata;
02777 
02778         int texsize_x, texsize_y;
02779 
02780         float dataextent_x, dataextent_y;
02781         float datacenter_x, datacenter_y;
02782         float minx, miny;
02783 
02784         dataextent_x = mExtends.getX();
02785         dataextent_y = mExtends.getY();
02786         datacenter_x = mCenterPos.getX();
02787         datacenter_y = mCenterPos.getY();
02788         minx = mMinPos.getX();
02789         miny = mMinPos.getY();
02790 
02791         float keepratiox = ( dataextent_x > dataextent_y ) ? 1.0f  : dataextent_x / dataextent_y;
02792         float keepratioy = ( dataextent_y > dataextent_x ) ? 1.0f  : dataextent_y / dataextent_x;
02793 
02794         // generate seedpoints in texture coordinates
02795         float numbersteamlines = MINNUMBER +  ( 1.0f - m_StreamSeparation ) * ( MAXNUMBER - MINNUMBER );
02796         float spacing = 1.0f / numbersteamlines ;
02797 
02798         pixeldata = mTimeSteps[m_TimeStep].getFullFBODataVector();
02799         texsize_x = mTimeSteps[m_TimeStep].mFrameBufferObject->getWidth();
02800         texsize_y = mTimeSteps[m_TimeStep].mFrameBufferObject->getHeight();
02801 
02802         int size = (int)pixeldata.size();
02803 
02804         
02805         // for all streamlines
02806         mNumStreamlines = (int)numbersteamlines;
02807         streamlines = new VStreamLine[ (int)numbersteamlines + 1 ];
02808 
02809         srand ( time(NULL) );;
02810 
02811         for ( int j = 0; j < numbersteamlines; j++ )
02812         {
02813                 float randomf[ 2 ];
02814                 randomf[ 0 ] = ( float )( rand(  ) % 10000 + 1 ) / 10000.0f;
02815                 randomf[ 1 ] = ( float )( rand(  ) % 10000 + 1 ) / 10000.0f;
02816 
02817                 std::vector< VVector > streamlinevertices;
02818                 
02819                 bool outofdata = false;
02820 
02821                 float sactualpoint_x = randomf[ 0 ];
02822                 float sactualpoint_y = randomf[ 1 ];
02823 
02824                 VVector start_tex = VVector();
02825                 start_tex.setX( sactualpoint_x  );
02826                 start_tex.setY( sactualpoint_y  );
02827 
02828                 VVector start_world = VVector( start_tex );
02829                 
02830                 //TODO:
02831                 //convert to world space
02832                 start_world.setX( -( start_world.getX() * dataextent_x ) + minx + dataextent_x);
02833                 start_world.setY( ( start_world.getY() * dataextent_y ) + miny );
02834                 streamlinevertices.push_back( start_world );
02835 
02836                 for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
02837                 {
02838                         if (outofdata ) break;
02839 
02840                         // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
02841                         VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
02842                         int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
02843                         int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
02844                         int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
02845                         int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
02846 
02847                         if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
02848                         {
02849                                 // we have reached the border;
02850                                 outofdata = true;
02851                                 break;
02852                         }
02853                         //fetch velocity at the actual position in world coordinates
02854                         
02855                         //floorx floorz
02856                         float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
02857                         float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
02858                         float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
02859                                                                 
02860                         //floorx ceil           
02861                         float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
02862                         float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
02863                         float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
02864                                                                                    
02865                         //floorx floorz                            
02866                         float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
02867                         float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
02868                         float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
02869                                                                 
02870                         //floorx floorz         
02871                         float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
02872                         float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
02873                         float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
02874 
02875                         float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
02876                         float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
02877                         float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
02878 
02879                         float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
02880                         float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
02881                         float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
02882 
02883                         float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
02884                         float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
02885                         float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
02886 
02887                         VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
02888                         VVector interp_mult = VVector( interpolatedval );
02889                         interp_mult.setX( -interp_mult.getX(  ) );
02890                         interp_mult *=  0.05f *mStreamlinesDt;
02891 
02892                         //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
02893                         VVector oldpos_world = VVector();
02894                         oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
02895                         oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
02896 
02897                         VVector newpos_world = oldpos_world + interp_mult;
02898 
02899                         VVector newpos_tex = VVector();
02900                         newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
02901                         newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
02902 
02903                         if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
02904                                 ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
02905                         {
02906                                 outofdata = true;
02907                                 break;
02908                         }
02909                                 
02910                         sactualpoint_x = newpos_tex.getX();
02911                         sactualpoint_y = newpos_tex.getY();
02912 
02913                         //TODO:
02914                         //convert to world space
02915                         newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
02916                         newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
02917                         streamlinevertices.push_back( newpos_tex );
02918 
02919                         float epsilon = 0.0000001f;
02920                         VVector posdifference = streamlinevertices[ streamlinevertices.size() - 1 ] - streamlinevertices[ streamlinevertices.size() - 2 ];
02921                         if ( posdifference.getMagnitude() < epsilon)
02922                         {
02923                                 outofdata = true;
02924                                 break;
02925                         }
02926 
02927                 }
02928 
02929                 //revert the streamline poitns vector and ocntinue in the opposite direction
02930                 if( !streamlinevertices.empty() ) 
02931                 {
02932                         std::vector< VVector > _streamlinesvertices;
02933                         for( int k = 0; k < streamlinevertices.size(); k++)
02934                         {
02935                                 _streamlinesvertices.push_back( streamlinevertices[ streamlinevertices.size() - k - 1 ] );
02936                                 
02937                         }
02938 
02939                         streamlinevertices.clear();
02940                         streamlinevertices.swap( _streamlinesvertices );
02941                         _streamlinesvertices.clear();
02942                 }
02943                 
02944 
02945                 sactualpoint_x = randomf[ 0 ];
02946                 sactualpoint_y = randomf[ 1 ];
02947 
02948                 outofdata = false;
02949 
02950                 //and go to the opposite direction
02951                 for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
02952                 {
02953                         if (outofdata ) break;
02954 
02955                         
02956                         // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
02957                         VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
02958                         int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
02959                         int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
02960                         int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
02961                         int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
02962 
02963                         if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
02964                         {
02965                                 // we have reached the border;
02966                                 outofdata = true;
02967                                 break;
02968                         }
02969                         //fetch velocity at the actual position in world coordinates
02970                         
02971                         //floorx floorz
02972                         float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
02973                         float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
02974                         float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
02975                                                                 
02976                         //floorx ceil           
02977                         float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
02978                         float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
02979                         float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
02980                                                                                    
02981                         //floorx floorz                            
02982                         float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
02983                         float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
02984                         float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
02985                                                                 
02986                         //floorx floorz         
02987                         float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
02988                         float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
02989                         float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
02990 
02991                         float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
02992                         float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
02993                         float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
02994 
02995                         float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
02996                         float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
02997                         float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
02998 
02999                         float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
03000                         float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
03001                         float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
03002 
03003                         VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
03004                         VVector interp_mult = VVector( interpolatedval );
03005                         interp_mult.setX( -interp_mult.getX(  ) );
03006                         interp_mult *=  0.05f *mStreamlinesDt;
03007 
03008                         //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
03009                         VVector oldpos_world = VVector();
03010                         oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
03011                         oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
03012 
03013                         VVector newpos_world = oldpos_world - interp_mult;
03014 
03015                         VVector newpos_tex = VVector();
03016                         newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
03017                         newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
03018 
03019                         if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
03020                                 ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
03021                         {
03022                                 outofdata = true;
03023                                 break;
03024                         }
03025                                 
03026                         sactualpoint_x = newpos_tex.getX();
03027                         sactualpoint_y = newpos_tex.getY();
03028 
03029                         //TODO:
03030                         //convert to world space
03031                         newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
03032                         newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
03033                         streamlinevertices.push_back( newpos_tex );
03034 
03035                         float epsilon = 0.0000001f;
03036                         VVector posdifference = streamlinevertices[ streamlinevertices.size() - 1 ] - streamlinevertices[ streamlinevertices.size() - 2 ];
03037                         if ( posdifference.getMagnitude() < epsilon)
03038                         {
03039                                 outofdata = true;
03040                                 break;
03041                         }
03042 
03043                 }
03044                 if( !streamlinevertices.empty() ) 
03045                 {
03046                         streamlines[ j ] = VStreamLine( streamlinevertices ) ;
03047                         streamlines[ j ].regenerateVBO();
03048                 }
03049         }
03050         
03051         //delete pixeldata;
03052         pixeldata.clear();
03053 }
03054 void VFlowData::generateCPUStreamLinesMANUAL( float m_MaxSteps, float m_StreamSeparation, int m_TimeStep /* = 0  */ )
03055 {
03056         drawStreamlinesFromSeedpoints( m_TimeStep, m_MaxSteps  );
03057 }
03058 
03059 void VFlowData::generateCPUStreamLinesEVEN( float m_MaxSteps, float m_StreamSeparation, int m_TimeStep /* = 0  */ )
03060 {
03061         //create a streamline in the middle
03062         //input x, y world returns a vector of points
03063 
03064         if( mNumStreamlines != 0 )
03065         {
03066                 if ( streamlines )
03067                 {
03068                         delete[] streamlines;
03069                         streamlines = NULL;
03070                         mNumStreamlines = 0;
03071                 }
03072         }
03073         
03074         float dataextent_x = mExtends.getX();
03075         float dataextent_y = mExtends.getY();
03076         float datacenter_x = mCenterPos.getX();
03077         float datacenter_y = mCenterPos.getY();
03078         float minx = mMinPos.getX();
03079         float miny = mMinPos.getY();
03080 
03081         
03082 
03083         std::deque< VStreamLine > squeue;
03084         std::vector< VStreamLine > svector;
03085 
03086         //squeue.resize( 100 ); 
03087         //svector.resize( 100 );
03088 
03089         float dsep = 0.25f * mStreamlinesSeedSeparation * min( dataextent_x, dataextent_y ) ;
03090         float dtest = 0.25f * mStreamlinesTestSeparation * min( dataextent_x, dataextent_y ) ;
03091 
03092         squeue.resize( 1 ); 
03093         svector.resize( 1 );
03094         std::vector< float > thickness0;
03095         VStreamLine s0 = VStreamLine( generateCPUStreamSingleWithoutTests( datacenter_x , datacenter_y, dtest, m_MaxSteps, m_TimeStep ) );
03096         squeue[ 0 ] =  s0;
03097         svector[ 0 ] = s0;
03098 
03099 
03100         std::vector< VVector > candidateseeds;
03101 
03102         int cnt = 1;
03103         while( !squeue.empty() )
03104         {
03105                 VStreamLine _s = squeue[ 0 ];
03106                 squeue.pop_front();
03107                 std::cout << "flushing streamline" << std::endl;
03108 
03109                 candidateseeds = _s.getCandidateSeeds( dsep );
03110 
03111                 if ( candidateseeds.empty() ) continue;
03112 
03113                 for( int i  = 0; i < candidateseeds.size(); i++ )
03114                 {
03115                         VVector seed = candidateseeds[ i ];
03116 
03117                         bool isseedvalid = true;
03118 
03119                         for( int i  = 0; i < svector.size(); i++ )
03120                         {
03121                                 isseedvalid = svector[ i ].isPointAllowed( seed, dtest );
03122                                 if ( !isseedvalid ) break;
03123                         }
03124 
03125                         if( isseedvalid )
03126                         {
03127                                 std::vector< float > thickness1;
03128                                 VStreamLine s1 = VStreamLine( generateCPUStreamSingleWithTests( svector, seed.getX() , seed.getY(), dtest,  m_MaxSteps, m_TimeStep ) );
03129                                 
03130                                 int linesize = s1.getNumberOfPoints();
03131 
03132                                 if ( linesize < 5 )
03133                                 {
03134                                         std::cout << "streamline too short" << std::endl;
03135                                         continue;
03136                                 }
03137 
03138                                 std::cout << "new streamline added" << std::endl;
03139                                 cnt++;
03140                         
03141                                 squeue.push_back(  s1 );
03142                                 svector.push_back(  s1 );
03143                         }
03144                         
03145                 }
03146         }       
03147 
03148         
03149         mNumStreamlines = cnt;
03150         streamlines = new VStreamLine[ mNumStreamlines ];
03151 
03152         
03153         for( int j  = 0 ; j < mNumStreamlines; j++)
03154         {
03155                 streamlines[ j ] = svector[ j ];
03156                 streamlines[ j ].setSeparation( dsep, dtest );
03157                 std::cout << "Computing tapering coef for streamline "<< j << " out of " << mNumStreamlines<<"!" << std::endl;
03158                 streamlines[ j ].computeThicknessCoefficients( dtest, dsep, svector, j, max ( dataextent_x, dataextent_y ) );
03159                 std::cout << "Computing tapering coef for streamline "<< j << " out of " << mNumStreamlines<<" is done!" << std::endl;
03160                 streamlines[ j ].regenerateVBO();
03161 
03162         }
03163 
03164         squeue.clear();
03165         svector.clear();
03166 
03167 }
03168 
03169 std::vector<VVector> VFlowData::generateCPUStreamSingleWithoutTests( float xw, float yw, float dtest, float m_MaxSteps, 
03170                                                                                                                                         int m_TimeStep /* = 0  */)
03171 {
03172 
03173         std::vector<VVector> spoints;
03174 
03175         std::vector< float > pixeldata;
03176 
03177         int texsize_x, texsize_y;
03178 
03179         float dataextent_x, dataextent_y;
03180         float datacenter_x, datacenter_y;
03181         float minx, miny;
03182 
03183         dataextent_x = mExtends.getX();
03184         dataextent_y = mExtends.getY();
03185         datacenter_x = mCenterPos.getX();
03186         datacenter_y = mCenterPos.getY();
03187         minx = mMinPos.getX();
03188         miny = mMinPos.getY();
03189 
03190         pixeldata = mTimeSteps[m_TimeStep].getFullFBODataVector();
03191         texsize_x = mTimeSteps[m_TimeStep].mFrameBufferObject->getWidth();
03192         texsize_y = mTimeSteps[m_TimeStep].mFrameBufferObject->getHeight();
03193 
03194         int size = (int)pixeldata.size();
03195 
03196 
03197         bool outofdata = false;
03198         bool selfcross = false;
03199 
03200         float sactualpoint_x =  1.0 - (  xw - minx  ) / dataextent_x;
03201         float sactualpoint_y = ( yw - miny ) / dataextent_y;
03202 
03203         VVector start_world = VVector( xw, yw, 0.0f );
03204         spoints.push_back( start_world );
03205 //      vthickness->push_back( dtest );
03206 
03207         for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
03208         {
03209                 if ( outofdata ) break;
03210                 if ( selfcross ) break;
03211 
03212                 // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
03213                 VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
03214                 int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
03215                 int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
03216                 int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
03217                 int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
03218 
03219                 if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
03220                 {
03221                         // we have reached the border;
03222                         outofdata = true;
03223                         break;
03224                 }
03225                 //fetch velocity at the actual position in world coordinates
03226                 
03227                 //floorx floorz
03228                 float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
03229                 float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
03230                 float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
03231                                                         
03232                 //floorx ceil           
03233                 float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
03234                 float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
03235                 float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
03236                                                                            
03237                 //floorx floorz                            
03238                 float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
03239                 float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
03240                 float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
03241                                                         
03242                 //floorx floorz         
03243                 float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
03244                 float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
03245                 float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
03246 
03247                 float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
03248                 float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
03249                 float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
03250 
03251                 float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
03252                 float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
03253                 float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
03254 
03255                 float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
03256                 float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
03257                 float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
03258 
03259                 VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
03260                 VVector interp_mult = VVector( interpolatedval );
03261                 interp_mult.setX( -interp_mult.getX(  ) );
03262                 interp_mult.normalize();
03263                 interp_mult *=  0.05f *mStreamlinesDt;
03264 
03265                 //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
03266                 VVector oldpos_world = VVector();
03267                 oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
03268                 oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
03269 
03270                 VVector newpos_world = oldpos_world + interp_mult;
03271 
03272                 VVector newpos_tex = VVector();
03273                 newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
03274                 newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
03275 
03276                 if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
03277                         ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
03278                 {
03279                         outofdata = true;
03280                         break;
03281                 }
03282                         
03283                 sactualpoint_x = newpos_tex.getX();
03284                 sactualpoint_y = newpos_tex.getY();
03285 
03286                 //TODO:
03287                 //convert to world space
03288                 newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
03289                 newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
03290 
03291                 // test for spirals and selfcollision
03292 
03293                 float selfdistance = 200.0f * dtest;
03294                 
03295                 
03296                 for (int h = (int)(200.0f); h < spoints.size(); h++ )
03297                 //for (int h = (int)(100.0f / mStreamlinesDt); h < spoints.size(); h++ )
03298                 {
03299                         VVector sp = spoints[ h - (int)(200.0f) ];
03300                         //VVector sp = spoints[ h - (int)(100.0f / mStreamlinesDt) ];
03301                         float pdistance = ( newpos_tex - sp ).getMagnitude();
03302 
03303                         if ( pdistance < selfdistance ) 
03304                         {
03305                                 selfdistance = pdistance;
03306                         }
03307 
03308                         if ( pdistance < dtest ) 
03309                         {
03310                                 selfcross = true;
03311                                 break;
03312                         }
03313                         
03314                 }
03315 
03316                 if ( selfcross ) break;
03317 
03318                 spoints.push_back( newpos_tex );
03319                 //vthickness->push_back( selfdistance );
03320 
03321                 float epsilon = 0.000000f;
03322                 VVector posdifference = spoints[ spoints.size() - 1 ] - spoints[ spoints.size() - 2 ];
03323                 if ( posdifference.getMagnitude() <= epsilon)
03324                 {
03325                         outofdata = true;
03326                         break;
03327                 }
03328 
03329         }
03330 
03331         //revert the streamline poitns vector and ocntinue in the opposite direction
03332         if( !spoints.empty() ) 
03333         {
03334                 std::vector< VVector > _streamlinesvertices;
03335                 for( int k = 0; k < spoints.size(); k++)
03336                 {
03337                         _streamlinesvertices.push_back( spoints[ spoints.size() - k - 1 ] );
03338                         
03339                         
03340                 }
03341                 spoints.clear();
03342                 spoints.swap( _streamlinesvertices );
03343                 
03344         }
03345         
03346 
03347         sactualpoint_x =  1.0 - (  xw - minx  ) / dataextent_x;
03348         sactualpoint_y = ( yw - miny ) / dataextent_y;
03349 
03350         outofdata = false;
03351         selfcross = false;
03352 
03353         //and go to the opposite direction
03354         for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
03355         {
03356                 if ( outofdata ) break;
03357                 if ( selfcross ) break;
03358 
03359                 
03360                 // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
03361                 VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
03362                 int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
03363                 int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
03364                 int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
03365                 int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
03366 
03367                 if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
03368                 {
03369                         // we have reached the border;
03370                         outofdata = true;
03371                         break;
03372                 }
03373                 //fetch velocity at the actual position in world coordinates
03374                 
03375                 //floorx floorz
03376                 float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
03377                 float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
03378                 float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
03379                                                         
03380                 //floorx ceil           
03381                 float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
03382                 float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
03383                 float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
03384                                                                            
03385                 //floorx floorz                            
03386                 float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
03387                 float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
03388                 float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
03389                                                         
03390                 //floorx floorz         
03391                 float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
03392                 float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
03393                 float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
03394 
03395                 float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
03396                 float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
03397                 float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
03398 
03399                 float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
03400                 float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
03401                 float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
03402 
03403                 float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
03404                 float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
03405                 float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
03406 
03407                 VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
03408                 VVector interp_mult = VVector( interpolatedval );
03409                 interp_mult.setX( -interp_mult.getX(  ) );
03410                 interp_mult.normalize();
03411                 interp_mult *=  0.05f *mStreamlinesDt;
03412 
03413                 //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
03414                 VVector oldpos_world = VVector();
03415                 oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
03416                 oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
03417 
03418                 VVector newpos_world = oldpos_world - interp_mult;
03419 
03420                 VVector newpos_tex = VVector();
03421                 newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
03422                 newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
03423 
03424                 if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
03425                         ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
03426                 {
03427                         outofdata = true;
03428                         break;
03429                 }
03430                         
03431                 sactualpoint_x = newpos_tex.getX();
03432                 sactualpoint_y = newpos_tex.getY();
03433 
03434                 //TODO:
03435                 //convert to world space
03436                 newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
03437                 newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
03438 
03439                 float selfdistance = 200.0f * dtest;
03440                 
03441                 
03442                 for (int h = (int)(200.0f); h < spoints.size(); h++ )
03443                 //for (int h = (int)(100.0f / mStreamlinesDt); h < spoints.size(); h++ )
03444                 {
03445                         VVector sp = spoints[ h - (int)(200.0f) ];
03446                         //VVector sp = spoints[ h - (int)(100.0f / mStreamlinesDt) ];
03447                         float pdistance = ( newpos_tex - sp ).getMagnitude();
03448 
03449                         if ( pdistance < selfdistance ) 
03450                         {
03451                                 selfdistance = pdistance;
03452                         }
03453 
03454                         if ( pdistance < dtest ) 
03455                         {
03456                                 selfcross = true;
03457                                 break;
03458                         }
03459                         
03460                 }
03461 
03462                 if ( selfcross ) break;
03463 
03464                 spoints.push_back( newpos_tex );
03465 
03466                 float epsilon = 0.000000f;
03467                 VVector posdifference = spoints[ spoints.size() - 1 ] - spoints[ spoints.size() - 2 ];
03468                 if ( posdifference.getMagnitude() <= epsilon)
03469                 {
03470                         outofdata = true;
03471                         break;
03472                 }
03473 
03474         }
03475 
03476         
03477         pixeldata.clear();
03478 
03479         return spoints;
03480 
03481 }
03482 
03483 std::vector<VVector> VFlowData::generateCPUStreamSingleWithTests( 
03484         std::vector<VStreamLine> otherStreamlines,
03485         float xw, float yw, float dtest, float m_MaxSteps, int m_TimeStep /* = 0  */ )
03486 {
03487         std::vector<VVector> spoints;
03488         std::vector< float > pixeldata;
03489 
03490         int texsize_x, texsize_y;
03491 
03492         float dataextent_x, dataextent_y;
03493         float datacenter_x, datacenter_y;
03494         float minx, miny;
03495 
03496         dataextent_x = mExtends.getX();
03497         dataextent_y = mExtends.getY();
03498         datacenter_x = mCenterPos.getX();
03499         datacenter_y = mCenterPos.getY();
03500         minx = mMinPos.getX();
03501         miny = mMinPos.getY();
03502 
03503         pixeldata = mTimeSteps[m_TimeStep].getFullFBODataVector();
03504         texsize_x = mTimeSteps[m_TimeStep].mFrameBufferObject->getWidth();
03505         texsize_y = mTimeSteps[m_TimeStep].mFrameBufferObject->getHeight();
03506 
03507         int size = (int)pixeldata.size();
03508 
03509 
03510         bool outofdata = false;
03511 
03512         float sactualpoint_x =  1.0 - (  xw - minx  ) / dataextent_x;
03513         float sactualpoint_y = ( yw - miny ) / dataextent_y;
03514 
03515         VVector start_world = VVector( xw, yw, 0.0f );
03516         spoints.push_back( start_world );
03517 //      vthickness->push_back( dtest );
03518         
03519         bool tooclose = false;
03520         bool selfcross = false;
03521 
03522         for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
03523         {
03524                 if (outofdata ) break;
03525                 if( tooclose ) break;
03526                 if( selfcross ) break;
03527 
03528                 // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
03529                 VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
03530                 int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
03531                 int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
03532                 int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
03533                 int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
03534 
03535                 if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
03536                 {
03537                         // we have reached the border;
03538                         outofdata = true;
03539                         break;
03540                 }
03541                 //fetch velocity at the actual position in world coordinates
03542                 
03543                 //floorx floorz
03544                 float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
03545                 float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
03546                 float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
03547                                                         
03548                 //floorx ceil           
03549                 float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
03550                 float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
03551                 float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
03552                                                                            
03553                 //floorx floorz                            
03554                 float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
03555                 float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
03556                 float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
03557                                                         
03558                 //floorx floorz         
03559                 float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
03560                 float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
03561                 float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
03562 
03563                 float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
03564                 float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
03565                 float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
03566 
03567                 float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
03568                 float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
03569                 float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
03570 
03571                 float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
03572                 float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
03573                 float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
03574 
03575                 VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
03576                 VVector interp_mult = VVector( interpolatedval );
03577                 interp_mult.setX( -interp_mult.getX(  ) );
03578                 interp_mult.normalize();
03579                 interp_mult *=  0.05f *mStreamlinesDt;
03580 
03581                 //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
03582                 VVector oldpos_world = VVector();
03583                 oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
03584                 oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
03585 
03586                 VVector newpos_world = oldpos_world + interp_mult;
03587 
03588                 VVector newpos_tex = VVector();
03589                 newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
03590                 newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
03591 
03592                 if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
03593                         ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
03594                 {
03595                         outofdata = true;
03596                         break;
03597                 }
03598                         
03599                 sactualpoint_x = newpos_tex.getX();
03600                 sactualpoint_y = newpos_tex.getY();
03601 
03602                 //TODO:
03603                 //convert to world space
03604                 newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
03605                 newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
03606 
03607                 float selfdistance = 200.0f * dtest;
03608                 
03609                 
03610                 for (int h = (int)(200.0f); h < spoints.size(); h++ )
03611                 //for (int h = (int)(100.0f / mStreamlinesDt); h < spoints.size(); h++ )
03612                 {
03613                         VVector sp = spoints[ h - (int)(200.0f) ];
03614                         //VVector sp = spoints[ h - (int)(100.0f / mStreamlinesDt) ];
03615                         float pdistance = ( newpos_tex - sp ).getMagnitude();
03616 
03617                         if ( pdistance < selfdistance ) 
03618                         {
03619                                 selfdistance = pdistance;
03620                         }
03621 
03622                         if ( pdistance < dtest ) 
03623                         {
03624                                 selfcross = true;
03625                                 break;
03626                         }
03627                         
03628                 }
03629 
03630                 if ( selfcross ) break;
03631 
03632                 //control
03633                 float mdistance[ 1 ];
03634                 for( int k = 0; k < otherStreamlines.size(); k++)
03635                 {
03636                         tooclose = !otherStreamlines[ k ].isPointAllowed( newpos_tex /*this is in world despite the name*/, dtest, mdistance );
03637                         if ( tooclose ) break;
03638                         
03639                 }
03640 
03641                 
03642 
03643                 if ( !tooclose && !selfcross )
03644                 {
03645                 
03646                                 
03647                         spoints.push_back( newpos_tex );
03648 
03649 
03650                         float epsilon = 0.000000f;
03651                         VVector posdifference = spoints[ spoints.size() - 1 ] - spoints[ spoints.size() - 2 ];
03652                         if ( posdifference.getMagnitude() <= epsilon)
03653                         {
03654                                 outofdata = true;
03655                                 break;
03656                         }
03657                 
03658                 }
03659 
03660         }
03661 
03662         //if ( tooclose  || selfcross ) return spoints;
03663 
03664         //revert the streamline poitns vector and ocntinue in the opposite direction
03665         if( !spoints.empty() ) 
03666         {
03667                 std::vector< VVector > _streamlinesvertices;
03668                 for( int k = 0; k < spoints.size(); k++)
03669                 {
03670                         _streamlinesvertices.push_back( spoints[ spoints.size() - k - 1 ] );
03671                 }
03672                 spoints.clear();
03673                 spoints.swap( _streamlinesvertices );
03674                 
03675         }
03676         
03677 
03678         sactualpoint_x =  1.0 - (  xw - minx  ) / dataextent_x;
03679         sactualpoint_y = ( yw - miny ) / dataextent_y;
03680 
03681         outofdata = false;
03682         selfcross = false;
03683 
03684         //and go to the opposite direction
03685         for ( int i = 0; i <  MAXSTEPS * m_MaxSteps ; i++)
03686         {
03687                 if ( outofdata ) break;
03688                 if ( tooclose ) break;
03689                 if ( selfcross ) break;
03690                 
03691                 // transform texture coordinates sactualpint_x and sactualpoint_y into world coords
03692                 VVector arrayindex = VVector( texsize_x * sactualpoint_x, texsize_y * sactualpoint_y, 0.0f );
03693                 int xfloor = (int) ( arrayindex.getX() - 0.5f ) - 1;
03694                 int yfloor = (int) ( arrayindex.getY() - 0.5f ) - 1;
03695                 int xceil  = (int) ( arrayindex.getX() + 0.5f ) - 1;
03696                 int yceil  = (int) ( arrayindex.getY() + 0.5f ) - 1;
03697 
03698                 if ( xfloor < 0 || yfloor < 0 || xceil >= texsize_x || yceil >= texsize_x )
03699                 {
03700                         // we have reached the border;
03701                         outofdata = true;
03702                         break;
03703                 }
03704                 //fetch velocity at the actual position in world coordinates
03705                 
03706                 //floorx floorz
03707                 float velocity_x_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4     ];
03708                 float velocity_y_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 1 ];
03709                 float velocity_z_ff = pixeldata[ xfloor * 4 + yfloor * texsize_x * 4 + 2 ];
03710                                                         
03711                 //floorx ceil           
03712                 float velocity_x_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4      ];
03713                 float velocity_y_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 1  ];
03714                 float velocity_z_fc =  pixeldata[ xfloor * 4 + yceil * texsize_x * 4 + 2  ];
03715                                                                            
03716                 //floorx floorz                            
03717                 float velocity_x_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4      ];
03718                 float velocity_y_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 1  ];
03719                 float velocity_z_cf =  pixeldata[ xceil * 4 + yfloor* texsize_x * 4 + 2  ];
03720                                                         
03721                 //floorx floorz         
03722                 float velocity_x_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4      ];
03723                 float velocity_y_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 1  ];
03724                 float velocity_z_cc = pixeldata[ xceil * 4 + yceil * texsize_x * 4 + 2  ];
03725 
03726                 float interpolval_x_L = ( arrayindex.getX() - xfloor ) * velocity_x_cf + ( xceil - arrayindex.getX() ) * velocity_x_ff;
03727                 float interpolval_y_L = ( arrayindex.getX() - xfloor ) * velocity_y_cf + ( xceil - arrayindex.getX() ) * velocity_y_ff;
03728                 float interpolval_z_L = ( arrayindex.getX() - xfloor ) * velocity_z_cf + ( xceil - arrayindex.getX() ) * velocity_z_ff;
03729 
03730                 float interpolval_x_H = ( arrayindex.getX() - xfloor ) * velocity_x_cc + ( xceil - arrayindex.getX() ) * velocity_x_fc;
03731                 float interpolval_y_H = ( arrayindex.getX() - xfloor ) * velocity_y_cc + ( xceil - arrayindex.getX() ) * velocity_y_fc;
03732                 float interpolval_z_H = ( arrayindex.getX() - xfloor ) * velocity_z_cc + ( xceil - arrayindex.getX() ) * velocity_z_fc;
03733 
03734                 float interpolval_x = ( arrayindex.getY() - yfloor ) * interpolval_x_H + ( yceil - arrayindex.getY() ) * interpolval_x_L;
03735                 float interpolval_y = ( arrayindex.getY() - yfloor ) * interpolval_y_H + ( yceil - arrayindex.getY() ) * interpolval_y_L;
03736                 float interpolval_z = ( arrayindex.getY() - yfloor ) * interpolval_z_H + ( yceil - arrayindex.getY() ) * interpolval_z_L;
03737 
03738                 VVector interpolatedval = VVector( interpolval_x, interpolval_y, interpolval_z );
03739                 VVector interp_mult = VVector( interpolatedval );
03740                 interp_mult.setX( -interp_mult.getX(  ) );
03741                 interp_mult.normalize();
03742                 interp_mult *=  0.05f *mStreamlinesDt;
03743 
03744                 //VVector oldpos_world = mVertexToTexture.homogenTransform( VVector ( sactualpoint_x, sactualpoint_y, 0.0f ) );
03745                 VVector oldpos_world = VVector();
03746                 oldpos_world.setX( sactualpoint_x * dataextent_x + minx );
03747                 oldpos_world.setY( sactualpoint_y * dataextent_y + miny );
03748 
03749                 VVector newpos_world = oldpos_world - interp_mult;
03750 
03751                 VVector newpos_tex = VVector();
03752                 newpos_tex.setX( ( newpos_world.getX() - minx ) / dataextent_x );
03753                 newpos_tex.setY( ( newpos_world.getY() - miny ) / dataextent_y );
03754 
03755                 if(             ( newpos_tex.getX() ) > 1.0f || ( newpos_tex.getY() ) > 1.0f 
03756                         ||      ( newpos_tex.getX() ) < 0.0f || ( newpos_tex.getY() ) < 0.0f )
03757                 {
03758                         outofdata = true;
03759                         break;
03760                 }
03761                         
03762                 sactualpoint_x = newpos_tex.getX();
03763                 sactualpoint_y = newpos_tex.getY();
03764 
03765                 //TODO:
03766                 //convert to world space
03767                 newpos_tex.setX( -( newpos_tex.getX() * dataextent_x ) + minx + dataextent_x);
03768                 newpos_tex.setY( ( newpos_tex.getY() * dataextent_y ) + miny );
03769 
03770                 float selfdistance = 200.0f * dtest;
03771                 
03772                 
03773                 for (int h = (int)(200.0f); h < spoints.size(); h++ )
03774                 //for (int h = (int)(100.0f / mStreamlinesDt); h < spoints.size(); h++ )
03775                 {
03776                         VVector sp = spoints[ h - (int)(200.0f) ];
03777                         //VVector sp = spoints[ h - (int)(100.0f / mStreamlinesDt) ];
03778                         float pdistance = ( newpos_tex - sp ).getMagnitude();
03779 
03780                         if ( pdistance < selfdistance ) 
03781                         {
03782                                 selfdistance = pdistance;
03783                         }
03784 
03785                         if ( pdistance < dtest ) 
03786                         {
03787                                 selfcross = true;
03788                                 break;
03789                         }
03790                         
03791                 }
03792 
03793                 if ( selfcross ) break;
03794 
03795                 //control
03796                 float mdistance[ 1 ];
03797                 for( int k = 0; k < otherStreamlines.size(); k++)
03798                 {
03799                         tooclose = !otherStreamlines[ k ].isPointAllowed( newpos_tex /*this is in world despite the name*/, dtest, mdistance );
03800                         if ( tooclose ) break;
03801                         
03802                 }
03803 
03804                 if ( !tooclose && ! selfcross )
03805                 {
03806                         spoints.push_back( newpos_tex );
03807                         //vthickness->push_back( min ( mdistance[ 0 ], selfdistance ) );
03808 
03809 
03810                         float epsilon = 0.000000f;
03811                         VVector posdifference = spoints[ spoints.size() - 1 ] - spoints[ spoints.size() - 2 ];
03812                         if ( posdifference.getMagnitude() <= epsilon)
03813                         {
03814                                 outofdata = true;
03815                                 break;
03816                         }
03817                 }
03818                 
03819 
03820         }
03821 
03822         
03823         pixeldata.clear();
03824         
03825 
03826         return spoints;
03827 
03828 }
03829 
03830 
03831 void VFlowData::generateCPUStreamLines( float m_MaxSteps, float m_StreamSeparation, int m_TimeStep /* = 0  */ )
03832 {
03833 
03834         switch ( mSeedPlacing )
03835         {
03836                 case LEFT:
03837                 {
03838                         if ( mEuler )
03839                         {
03840                                 generateCPUStreamLinesLEFT( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03841                         }
03842                         else
03843                         {
03844                                 generateCPUStreamLinesLEFT_RK2( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03845                         }
03846                         break;
03847                 }
03848                         
03849                 case TOP:
03850                 {
03851                         if ( mEuler )
03852                         {
03853                                 generateCPUStreamLinesTOP( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03854                         }
03855                         else
03856                         {
03857                                 generateCPUStreamLinesTOP_RK2( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03858                         }
03859                         break;
03860                 }
03861                         
03862                 case RIGHT:
03863                 {
03864                         if ( mEuler )
03865                         {
03866                                 generateCPUStreamLinesRIGHT( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03867                         }
03868                         else
03869                         {
03870                                 generateCPUStreamLinesRIGHT_RK2( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03871                         }
03872                         
03873                         break;
03874                 }
03875                         
03876                 case BOTTOM:
03877                 {
03878                         if ( mEuler )
03879                         {
03880                                 generateCPUStreamLinesBOTTOM( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03881                         }
03882                         else
03883                         {
03884                                 generateCPUStreamLinesBOTTOM_RK2( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03885                         }
03886                         
03887                         break;
03888                 }
03889                         
03890                 case ALL:
03891                 {
03892                         if ( mEuler )
03893                         {
03894                                 generateCPUStreamLinesALL( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03895                         }
03896                         else
03897                         {
03898                                 generateCPUStreamLinesALL_RK2( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03899                         }
03900                         
03901                         break;
03902                 }
03903                 case RANDOM:
03904                 {
03905                         if ( mEuler )
03906                         {
03907                                 generateCPUStreamLinesRANDOM( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03908                         }
03909                         else
03910                         {
03911                                 generateCPUStreamLinesRANDOM_RK2( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03912                         }
03913                         
03914                         break;
03915                 }
03916                         
03917                 case MANUAL:
03918                 {
03919                         if ( mEuler )
03920                         {
03921                                 generateCPUStreamLinesMANUAL( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03922                         }
03923                         else
03924                         {
03925                                 generateCPUStreamLinesMANUAL_RK2( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03926                         }
03927                         
03928                         break;
03929                 }
03930                         
03931                 case EVEN:
03932                 {
03933                         if ( mEuler )
03934                         {
03935                                 generateCPUStreamLinesEVEN( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03936                         }
03937                         else
03938                         {
03939                                 generateCPUStreamLinesEVEN_RK2( m_MaxSteps, m_StreamSeparation, m_TimeStep /* = 0  */ );
03940                         }
03941                         
03942                         break;
03943                 }
03944         
03945         }
03946 
03947         
03948 
03949 }
03950 
03951 void VFlowData::generateVBO()
03952 {
03953         glGenBuffersARB( 1, &(mVertexVbo) );
03954         glBindBufferARB( GL_ARRAY_BUFFER_ARB, mVertexVbo );
03955         glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(float) * (int)mVertexGrid.size() * 3, &(mVertexGrid[0]), GL_STATIC_DRAW_ARB );
03956 
03957         glGenBuffersARB( 1, &(mIndexVbo) );
03958         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, mIndexVbo );
03959         glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(int) * (int)mIndexGrid.size(), &(mIndexGrid[0]), GL_STATIC_DRAW_ARB );
03960 
03961         for ( int i = 0; i < (int)mTimeSteps.size(); ++i )
03962         {
03963                 for ( int j = 0; j < (int) mTimeSteps[i].mTimeData.size(); ++j )
03964                 {
03965                         glGenBuffersARB(1, &( mTimeSteps[i].mTimeData[j].mSetVbo) );
03966 
03967                         glBindBufferARB(GL_ARRAY_BUFFER_ARB, mTimeSteps[i].mTimeData[j].mSetVbo);
03968                         glBufferDataARB(GL_ARRAY_BUFFER_ARB, 
03969                                                         sizeof(float) * (int)(mTimeSteps[i].mTimeData[j].mSet.size()) * 3, 
03970                                                         &(mTimeSteps[i].mTimeData[j].mSet[0]), 
03971                                                         GL_STATIC_DRAW_ARB);
03972 
03973                         mTimeSteps[i].mTimeData[j].mTexCoordChannel = GL_TEXTURE0 + j;
03974                 }
03975         }
03976 
03977         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, 0 );
03978         glBindBufferARB( GL_ARRAY_BUFFER, 0 );
03979 }
03980 
03981 void VFlowData::activateVBO( int m_TimeStep )
03982 {
03983         if( m_TimeStep > ( ( int )mTimeSteps.size(  ) - 1) )
03984         {
03985                 m_TimeStep = ( ( int )mTimeSteps.size(  ) - 1 );
03986         }
03987         for( int i = 0; i < ( int ) mTimeSteps[ m_TimeStep ].mTimeData.size(  ); ++i )
03988         {
03989                 glActiveTextureARB( mTimeSteps[ m_TimeStep ].mTimeData[ i ].mTexCoordChannel );
03990                 glClientActiveTextureARB( mTimeSteps[ m_TimeStep ].mTimeData[ i ].mTexCoordChannel );
03991                 glEnableClientState( GL_TEXTURE_COORD_ARRAY_EXT );
03992                 glBindBuffer( GL_ARRAY_BUFFER, mTimeSteps[ m_TimeStep ].mTimeData[ i ].mSetVbo );
03993                 glTexCoordPointerEXT( 3, GL_FLOAT, 0, 0, 0 );
03994         }
03995         
03996         glEnableClientState( GL_VERTEX_ARRAY );
03997         glBindBuffer( GL_ARRAY_BUFFER, mVertexVbo );
03998         glVertexPointer( 3, GL_FLOAT, 0, 0 );
03999 }
04000 
04001 void VFlowData::deactivateVBO()
04002 {
04003         glDisableClientState(GL_VERTEX_ARRAY);
04004 
04005         for ( int i = 0; i < (int)mTimeSteps[0].mTimeData.size(); ++i )
04006         {
04007                 glClientActiveTextureARB(GL_TEXTURE0_ARB + i);
04008                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
04009         }
04010 
04011         glClientActiveTextureARB(GL_TEXTURE0_ARB);
04012 
04013         glBindBufferARB(GL_ARRAY_BUFFER, 0);
04014         glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
04015 
04016 
04017 
04018 }
04019 
04020 void VFlowData::clear()
04021 {
04022         glDeleteBuffersARB( 1, &mVertexVbo );
04023         mVertexGrid.clear();
04024         
04025         glDeleteBuffersARB( 1, &mIndexVbo );
04026         mIndexGrid.clear();
04027 
04028         if(mGlyphIndexVbo != 0)
04029         {
04030                 glDeleteBuffers( 1, &(mGlyphIndexVbo) );
04031                 mGlyphIndexGrid.clear();
04032         }
04033 
04034         for ( int i = 0; i < (int)mTimeSteps.size(); ++i )
04035         {
04036                 for ( int j = 0; j < (int) mTimeSteps[i].mTimeData.size(); ++j )
04037                 {
04038                         glDeleteBuffersARB(1, &mTimeSteps[i].mTimeData[j].mSetVbo );
04039                         mTimeSteps[i].mTimeData[j].mSet.clear();
04040                 }
04041                 mTimeSteps[i].mTimeData.clear();
04042         }
04043         mTimeSteps.clear();
04044 
04045         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, 0 );
04046         glBindBufferARB( GL_ARRAY_BUFFER, 0 );
04047 
04048                 
04049 
04050         
04051 }
04052 
04053 VProgram * VFlowData::mRenderTextureProgram = NULL;

Generated on Mon Jan 21 01:15:16 2008 for FlowVis by  doxygen 1.5.4