00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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
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
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
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;
00250 _hPos[p++] = point.y * scale;
00251 _hPos[p++] = point.z * scale;
00252 _hPos[p++] = 1.0f;
00253
00254 _hVel[v++] = velocity.x * vscale;
00255 _hVel[v++] = velocity.y * vscale;
00256 _hVel[v++] = velocity.z * vscale;
00257 _hVel[v++] = 1.0f;
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)
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;
00290 y = 0.0f;
00291 z = 1.0f;
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
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;
00332 _hPos[p++] = point.y * scale;
00333 _hPos[p++] = point.z * scale;
00334 _hPos[p++] = 1.0f;
00335
00336 _hVel[v++] = point.x * vscale;
00337 _hVel[v++] = point.y * vscale;
00338 _hVel[v++] = point.z * vscale;
00339 _hVel[v++] = 1.0f;
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