examples/eqNBody/frameData.cpp

00001 /*
00002  * Copyright (c) 2009, Philippe Robert <probert@eyescale.ch> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #include "frameData.h"
00019 
00020 #include <vector_types.h>
00021 
00022 extern "C" {
00023     float v3_normalize(float3& vector)
00024     {
00025         float dist = sqrtf(vector.x*vector.x + vector.y*vector.y + vector.z*vector.z);
00026         if (dist > 1e-6)
00027         {
00028             vector.x /= dist;
00029             vector.y /= dist;
00030             vector.z /= dist;
00031         }
00032         return dist;
00033     }
00034     
00035     float v3_dot(float3 v0, float3 v1)
00036     {
00037         return v0.x*v1.x+v0.y*v1.y+v0.z*v1.z;
00038     }
00039     
00040     float3 v3_cross(float3 v0, float3 v1)
00041     {
00042         float3 rt;
00043         rt.x = v0.y*v1.z-v0.z*v1.y;
00044         rt.y = v0.z*v1.x-v0.x*v1.z;
00045         rt.z = v0.x*v1.y-v0.y*v1.x; 
00046         return rt;
00047     }
00048 };
00049 
00050 namespace eqNbody
00051 {
00052     
00053     FrameData::FrameData() : _statistics( true ) , _numDataProxies(0)
00054     {       
00055         _numBodies      = 0;
00056         _deltaTime      = 0.0f;
00057         _clusterScale   = 0.0f;
00058         _velocityScale  = 0.0f;
00059         _newParameters  = false;
00060     }
00061     
00062     FrameData::~FrameData()
00063     {
00064         _numDataProxies = 0;
00065     }
00066     
00067     void FrameData::serialize( eq::net::DataOStream& os, const uint64_t dirtyBits )
00068     {
00069         eq::Object::serialize( os, dirtyBits );
00070         
00071         if( dirtyBits & DIRTY_DATA ) {
00072             os.write(_hPos, sizeof(float)*_numBodies*4);
00073             os.write(_hVel, sizeof(float)*_numBodies*4);
00074             os.write(_hCol, sizeof(float)*_numBodies*4);
00075         }
00076         
00077         if( dirtyBits & DIRTY_FLAGS ) {
00078             os << _statistics << _numBodies << _clusterScale << _velocityScale << _deltaTime << _newParameters;
00079         }       
00080         
00081         if( dirtyBits & DIRTY_PROXYDATA ) {
00082             os << _numDataProxies;
00083             os.write(&_dataProxyID[0][0], sizeof(unsigned int) * MAX_NGPUS * 2);            
00084             os.write(&_dataRanges[0], sizeof(float) * MAX_NGPUS);           
00085         }
00086     }
00087     
00088     void FrameData::deserialize( eq::net::DataIStream& is, const uint64_t dirtyBits )
00089     {
00090         eq::Object::deserialize( is, dirtyBits );
00091         
00092         if( dirtyBits & DIRTY_DATA ) {
00093             is.read(_hPos, sizeof(float)*_numBodies*4);
00094             is.read(_hVel, sizeof(float)*_numBodies*4);
00095             is.read(_hCol, sizeof(float)*_numBodies*4);
00096         }
00097         
00098         if( dirtyBits & DIRTY_FLAGS ) {
00099             is >> _statistics >> _numBodies >> _clusterScale >> _velocityScale >> _deltaTime >> _newParameters;
00100         }
00101         
00102         if( dirtyBits & DIRTY_PROXYDATA ) {
00103             is >> _numDataProxies;
00104             is.read(&_dataProxyID[0][0], sizeof(unsigned int) * MAX_NGPUS * 2);
00105             is.read(&_dataRanges[0], sizeof(float) * MAX_NGPUS);
00106         }
00107     }
00108     
00109     void FrameData::addProxyID( unsigned int pid, const float *range )
00110     {
00111         EQASSERT(_numDataProxies < MAX_NGPUS);
00112         
00113         _dataProxyID[_numDataProxies][0] = pid;  
00114         _dataProxyID[_numDataProxies][1] = 0;
00115 
00116         _dataRanges[_numDataProxies++] = (range[1] - range[0]);
00117         setDirty( DIRTY_PROXYDATA );
00118     }
00119     
00120     void FrameData::updateProxyID( unsigned int pid, unsigned int version, const float *range )
00121     {
00122         // TODO: Better use a hash here!
00123         for(unsigned int i=0; i< _numDataProxies; i++) {
00124             if( pid == _dataProxyID[i][0]) {
00125                 _dataProxyID[i][1] = version;
00126                 _dataRanges[i] = (range[1] - range[0]);
00127                 break;
00128             }
00129         }
00130         setDirty( DIRTY_PROXYDATA );
00131     }
00132     
00133     uint32_t FrameData::commit()
00134     {
00135         bool ret = eq::Object::commit();
00136         EQASSERT(ret);
00137         
00138         for(unsigned int i=0; i< _numDataProxies; i++) {
00139             _dataRanges[i] = 0.0f;
00140         }       
00141         
00142         return ret;
00143     }
00144     
00145     bool FrameData::isReady()
00146     {
00147         float length = 0.0f;
00148         
00149         for(unsigned int i=0; i<_numDataProxies; i++) {
00150             length += _dataRanges[i];
00151         }
00152         
00153         // Return true if range [0 1] is covered, otherwise false
00154         return (length == 1.0f) ? true : false;
00155     }
00156     
00157     unsigned int FrameData::getVersionForProxyID( unsigned int pid ) const
00158     {       
00159         int version = -1;
00160         
00161         // TODO: Better use a hash here!
00162         for(unsigned int i=0; i< _numDataProxies; i++) {
00163             if( pid == getProxyID(i) ) {
00164                 version = getProxyVersion(i); 
00165                 break;
00166             }
00167         }
00168         
00169         EQASSERT(version != -1)
00170         
00171         return (unsigned int)version;
00172     }
00173     
00174     void FrameData::toggleStatistics()
00175     {
00176         _statistics = !_statistics;
00177         setDirty( DIRTY_FLAGS );
00178     }
00179     
00180     void FrameData::init(const unsigned int numBodies)
00181     {
00182         _numBodies  = numBodies;
00183         
00184         _hPos       = new float[numBodies*4];
00185         _hVel       = new float[numBodies*4];
00186         _hCol       = new float[numBodies*4];
00187         
00188         memset(_hPos, 0, numBodies*4*sizeof(float));
00189         memset(_hVel, 0, numBodies*4*sizeof(float));
00190         memset(_hCol, 0, numBodies*4*sizeof(float));
00191         
00192         setDirty( DIRTY_DATA );
00193         setDirty( DIRTY_FLAGS );
00194     }
00195     
00196     void FrameData::exit()
00197     {
00198         _numDataProxies = 0;
00199         _numBodies      = 0;
00200 
00201         delete [] _hPos;
00202         delete [] _hVel;    
00203         delete [] _hCol;    
00204     }
00205     
00206     void FrameData::updateParameters(NBodyConfig config, float clusterScale, float velocityScale, float ts)
00207     {       
00208         _clusterScale   = clusterScale;
00209         _velocityScale  = velocityScale;
00210         _deltaTime      = ts;
00211         _newParameters  = true;
00212         
00213         _randomizeData(config);
00214         
00215         setDirty( DIRTY_DATA );
00216         setDirty( DIRTY_FLAGS );
00217     }
00218     
00219     void FrameData::_randomizeData(NBodyConfig config)
00220     {
00221         switch(config)
00222         {
00223             default:
00224             case NBODY_CONFIG_RANDOM:
00225             {
00226                 float scale  = _clusterScale * std::max(1.0f, _numBodies / (1024.f));
00227                 float vscale = _velocityScale * scale;
00228                 
00229                 int p = 0, v = 0;
00230                 unsigned int i = 0;
00231                 while (i < _numBodies) 
00232                 {
00233                     float3 point;
00234                     //const int scale = 16;
00235                     point.x = rand() / (float) RAND_MAX * 2 - 1;
00236                     point.y = rand() / (float) RAND_MAX * 2 - 1;
00237                     point.z = rand() / (float) RAND_MAX * 2 - 1;
00238                     float lenSqr = v3_dot(point, point);
00239                     if (lenSqr > 1)
00240                         continue;
00241                     float3 velocity;
00242                     velocity.x = rand() / (float) RAND_MAX * 2 - 1;
00243                     velocity.y = rand() / (float) RAND_MAX * 2 - 1;
00244                     velocity.z = rand() / (float) RAND_MAX * 2 - 1;
00245                     lenSqr = v3_dot(velocity, velocity);
00246                     if (lenSqr > 1)
00247                         continue;
00248                     
00249                     _hPos[p++] = point.x * scale; // pos.x
00250                     _hPos[p++] = point.y * scale; // pos.y
00251                     _hPos[p++] = point.z * scale; // pos.z
00252                     _hPos[p++] = 1.0f; // mass
00253                     
00254                     _hVel[v++] = velocity.x * vscale; // pos.x
00255                     _hVel[v++] = velocity.y * vscale; // pos.x
00256                     _hVel[v++] = velocity.z * vscale; // pos.x
00257                     _hVel[v++] = 1.0f; // inverse mass
00258                     
00259                     i++;
00260                 }
00261             }
00262                 break;
00263             case NBODY_CONFIG_SHELL:
00264             {
00265                 float scale = _clusterScale;
00266                 float vscale = scale * _velocityScale;
00267                 float inner = 2.5f * scale;
00268                 float outer = 4.0f * scale;
00269                 
00270                 int p = 0, v=0;
00271                 unsigned int i = 0;
00272                 while (i < _numBodies)//for(int i=0; i < numBodies; i++) 
00273                 {
00274                     float x, y, z;
00275                     x = rand() / (float) RAND_MAX * 2 - 1;
00276                     y = rand() / (float) RAND_MAX * 2 - 1;
00277                     z = rand() / (float) RAND_MAX * 2 - 1;
00278                     
00279                     float3 point = {x, y, z};
00280                     float len = v3_normalize(point);
00281                     if (len > 1)
00282                         continue;
00283                     
00284                     _hPos[p++] =  point.x * (inner + (outer - inner) * rand() / (float) RAND_MAX);
00285                     _hPos[p++] =  point.y * (inner + (outer - inner) * rand() / (float) RAND_MAX);
00286                     _hPos[p++] =  point.z * (inner + (outer - inner) * rand() / (float) RAND_MAX);
00287                     _hPos[p++] = 1.0f;
00288                     
00289                     x = 0.0f; // * (rand() / (float) RAND_MAX * 2 - 1);
00290                     y = 0.0f; // * (rand() / (float) RAND_MAX * 2 - 1);
00291                     z = 1.0f; // * (rand() / (float) RAND_MAX * 2 - 1);
00292                     float3 axis = {x, y, z};
00293                     v3_normalize(axis);
00294                     
00295                     if (1 - v3_dot(point, axis) < 1e-6)
00296                     {
00297                         axis.x = point.y;
00298                         axis.y = point.x;
00299                         v3_normalize(axis);
00300                     }
00301                     //if (point.y < 0) axis = scalevec(axis, -1);
00302                     float3 vv = {_hPos[4*i], _hPos[4*i+1], _hPos[4*i+2]};
00303                     vv = v3_cross(vv, axis);
00304                     _hVel[v++] = vv.x * vscale;
00305                     _hVel[v++] = vv.y * vscale;
00306                     _hVel[v++] = vv.z * vscale;
00307                     _hVel[v++] = 1.0f;
00308                     
00309                     i++;
00310                 }
00311             }
00312                 break;
00313             case NBODY_CONFIG_EXPAND:
00314             {
00315                 float scale = _clusterScale * std::max(1.0f, _numBodies / (1024.f));
00316                 float vscale = scale * _velocityScale;
00317                 
00318                 int p = 0, v = 0;
00319                 for(unsigned int i=0; i < _numBodies;) 
00320                 {
00321                     float3 point;
00322                     
00323                     point.x = rand() / (float) RAND_MAX * 2 - 1;
00324                     point.y = rand() / (float) RAND_MAX * 2 - 1;
00325                     point.z = rand() / (float) RAND_MAX * 2 - 1;
00326                     
00327                     float lenSqr = v3_dot(point, point);
00328                     if (lenSqr > 1)
00329                         continue;
00330                     
00331                     _hPos[p++] = point.x * scale; // pos.x
00332                     _hPos[p++] = point.y * scale; // pos.y
00333                     _hPos[p++] = point.z * scale; // pos.z
00334                     _hPos[p++] = 1.0f; // mass
00335                     
00336                     _hVel[v++] = point.x * vscale; // pos.x
00337                     _hVel[v++] = point.y * vscale; // pos.x
00338                     _hVel[v++] = point.z * vscale; // pos.x
00339                     _hVel[v++] = 1.0f; // inverse mass
00340                     
00341                     i++;
00342                 }
00343             }
00344                 break;
00345         }
00346         
00347         if (_hCol)
00348         {
00349             int v = 0;
00350             for(unsigned int i=0; i < _numBodies; i++) 
00351             {
00352                 _hCol[v++] = rand() / (float) RAND_MAX;
00353                 _hCol[v++] = rand() / (float) RAND_MAX;
00354                 _hCol[v++] = rand() / (float) RAND_MAX;
00355                 _hCol[v++] = 1.0f;
00356             }
00357         }       
00358     }
00359 }
00360 
Generated on Mon Aug 10 18:58:33 2009 for Equalizer 0.9 by  doxygen 1.5.8