00001 #include <ocean/GLvish/VRenderObject.hpp>
00002 #include <fish/lakeview/bone/FishField.hpp>
00003
00004 #include <ocean/GLvish/Colormap.hpp>
00005
00006 #include <eagle/FixedArray.hpp>
00007 #include <field/DirectProductArray.hpp>
00008 #include <ocean/GLvish/BoundingBox.hpp>
00009
00010 #include <fish/fiber/vector/Interpolate.hpp>
00011 #include <fish/fiber/vector/LinearIpol.hpp>
00012 #include <fish/fiber/vector/CubicIpol.hpp>
00013
00014 #include <ocean/GLvish/GlossyTexture.hpp>
00015
00016 #include <ocean/plankton/VOperatorCache.hpp>
00017
00018
00019
00020 using namespace Wizt;
00021 using namespace Fiber;
00022
00034
00035
00036
00037 class RampTexture : public GLTexture1D
00038 {
00039 typedef FixedArray<float,3> rgb;
00040
00041 public:
00042 RampTexture(const int tex_unit):GLTexture1D(tex_unit){}
00043
00044
00045 void enlighten()
00046 {
00047 rgb texture[512];
00048 rgb col;
00049 col = 0,0,0;
00050
00051 for(int i = 0; i < 512 ; i++)
00052 {
00053 col[0] = (float)i/512;
00054 col[1] = 1 - col[0];
00055 texture[i] = col;
00056 }
00057
00058 bind();
00059 GL::TexImage1D( texture, 512, GL_RGB);
00060 glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00061 glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00062 glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00063 }
00064
00065 void prerender()
00066 {
00067 enable();
00068
00069 bind();
00070 }
00071
00072 };
00073
00074
00075 class TexturedStreamLines : public virtual VRenderObject,
00076
00077 public virtual Fish<Field>
00078 {
00079 public:
00080 typedef MemArray<3, tvector> VectorArray_t;
00081 typedef MemArray<3, point> CoordsArray_t;
00082 typedef DirectProductMemArray<point> ProceduralArray_t;
00083
00084 typedef FixedArray<float,3> rgb;
00085
00086 GlossyTexture::Parameters GlossyParameters;
00087
00088
00089 typedef std::vector<point> Line_t;
00090
00091
00092 typedef VOperatorCache<std::vector<Line_t> > OpCache_t;
00093
00094 TypedSlot<int> LineLength;
00095 TypedSlot<int> LineWidth;
00096 TypedSlot<int> PointSize;
00097 TypedSlot<int> LineNumber;
00098 TypedSlot<double> StepSize;
00099 TypedSlot<double> FanDelta;
00100
00101 TypedSlot<double> X,
00102 Y,
00103 Z;
00104
00105
00106
00107
00108
00109 struct MyState : State
00110 {
00111 RefPtr<RampTexture> MyTexture;
00112 RefPtr<GlossyTexture> LineTexture;
00113 };
00114
00115 override RefPtr<State> newState() const
00116 {
00117 return new MyState();
00118 }
00119
00120
00121
00122 TexturedStreamLines(const string&name, int p, const RefPtr<VCreationPreferences>&VP)
00123 : VRenderObject(name, p, VP)
00124 , Fish<VObject>(this)
00125 , Fish<Field>("datafield")
00126 , GlossyParameters(this)
00127 , LineLength(this, "LineLength", 40)
00128 , LineWidth(this, "LineWidth", 2)
00129 , PointSize(this, "PointSize", 2)
00130 , LineNumber(this, "LineNumber", 10)
00131 , StepSize(this, "StepSize", 0.1)
00132 , FanDelta(this, "FanDelta", 0.05)
00133 , X(this, "X", 0.271)
00134 , Y(this, "Y", 0.294)
00135 , Z(this, "Z", 0.531)
00136 {
00137 LineLength.setProperty("max", 100);
00138 LineLength.setProperty("min", 1);
00139 LineWidth.setProperty("max", 20);
00140 PointSize.setProperty("max", 20);
00141 LineNumber.setProperty("min", 1);
00142 X.setProperty("max", 1.0);
00143 Y.setProperty("max", 1.0);
00144 Z.setProperty("max", 1.0);
00145 }
00146
00147
00148 override bool update( VRequest&R, double precision );
00149 override void render( VRenderContext&R ) const;
00150
00151 void getCoordinates(const point& float_index, point& position_cordinates);
00152 };
00153
00154
00159 bool TexturedStreamLines::update( VRequest&R, double precision )
00160 {
00161 printf("TexturedStreamLines::update(): updating\n");
00162
00163 FieldSelector FS = getFieldSelector(R);
00164
00165
00166 RefPtr<Grid> G = FS.GridSource();
00167 if (!G)
00168 return true;
00169
00170
00171 RefPtr<Field> Coords = G->CartesianPositions();
00172 if (!Coords) { puts("SimpleStreamline::update(): No coord field!"); return true; }
00173
00174
00175
00176 RefPtr<Field> Vectors = FS.getField();
00177 if (!Vectors) { puts("SimpleStreamline::update(): No vector field!"); return true; }
00178
00179
00180
00181
00182
00183 RefPtr<OpCache_t>&OC = OpCache_t::retrieve( *Vectors ) [ self() ];
00184 if (!OC) OC = new OpCache_t();
00185
00186
00187 RefPtr<MyState> S = myState(R);
00188
00189 assert(S);
00190
00191 RefPtr<VectorArray_t> Vctrs = Vectors->getData();
00192
00193 if( !Vctrs)
00194 {
00195 printf("TexturedStreamLines::update(): Could get vector field data yet!\n");
00196 if (OC)
00197 {
00198 OC->resize( 0 );
00199 GLCache::clear( *OC );
00200 }
00201 return true;
00202 }
00203 else
00204 printf("TexturedStreamLines::update(): Gotvector field data!\n");
00205
00206 RefPtr<ProceduralArray_t> PCrds = Coords->getData();
00207 RefPtr<CoordsArray_t> Crds = Coords->getData();
00208 if (!(Crds || PCrds))
00209 {
00210 printf("TexturedStreamLines::update(): Did not find any coordinates : %s\n",
00211 Typename( Coords->getType() ).c_str() );
00212 return true;
00213 }
00214
00215
00216
00217
00218 RefPtr<ValueSet> Changeables = new ValueSet();
00219 Changeables & R += X, Y, Z, LineLength, PointSize, StepSize, FanDelta, LineNumber;
00220
00221
00222 int line_number = 1;
00223 LineNumber << R >> line_number;
00224
00225
00226 if (OC->unchanged( Changeables ) )
00227 {
00228 printf("TexturedStreamLines::update(): Line Calc Skipped, Lines in Cache...\n");
00229 return true;
00230 }
00231
00232 OC->resize( line_number );
00233 GLCache::clear( *OC );
00234
00235
00236
00237 MultiIndex<3> FieldSize = Vctrs->Size();
00238
00239
00240 double x, y, z;
00241 point float_index;
00242 point max_float_index;
00243 point vertex;
00244 int line_length;
00245 double hh;
00246 double fan_delta;
00247
00248 LineLength << R >> line_length;
00249
00250 StepSize << R >> hh;
00251 FanDelta<< R >> fan_delta;
00252
00253
00254 X << R >> x;
00255 Y << R >> y;
00256 Z << R >> z;
00257
00258 max_float_index = FieldSize[0] - 1, FieldSize[1] - 1, FieldSize[2] - 1;
00259 float_index = x * FieldSize[0] - 1, y * FieldSize[1] -1 , z * FieldSize[2] - 1;
00260
00261
00262 for (int i = 0; i < 3; i++)
00263 {
00264 if( float_index[i] < 0 )
00265 float_index[i] = 0.0;
00266
00267 if( float_index[i] >= FieldSize[i] )
00268 float_index[i] = FieldSize[i] - 1;
00269 }
00270
00271
00272 point DomainStart = PCrds->first();
00273 point DomaintEnd = PCrds->last();
00274
00275 tvector DomainDiagonal = DomaintEnd - DomainStart;
00276
00277
00278
00279 std::vector<point> StartVertex;
00280 StartVertex.resize(line_number);
00281 StartVertex[0] = ( DomainStart + tvector(component_wise( component_wise(DomainDiagonal, max_float_index, Eagle::Operator<'/'>() ), float_index, Eagle::Operator<'*'>() ) ) );
00282
00283
00284 tvector CurrentDir;
00285 point CurrentVertex;
00286 point CurrentFloatIndex;
00287 tvector FanOffset;
00288 FanOffset = 1, 0, 0;
00289
00290 resetBBox( R );
00291 embrace( R, StartVertex[0]);
00292
00293 for(int l = 0; l < line_number; l++)
00294 {
00295
00296 StartVertex[l] = StartVertex[0] + FanOffset * l * fan_delta;
00297
00298 Line_t&myLine = (*OC)[l];
00299 myLine.clear();
00300
00301 for(int i = 0; i < line_length; i++)
00302 {
00303 if (i == 0)
00304 {
00305 CurrentVertex = StartVertex[l];
00306
00307 Interpolate<3, tvector, CubicIpol <tvector> > VecField(*Vctrs, float_index);
00308 CurrentDir = VecField.eval();
00309 }
00310 else
00311 {
00312 CurrentFloatIndex = point( tvector( component_wise(component_wise(CurrentVertex - DomainStart, DomainDiagonal, Eagle::Operator<'/'>() ), max_float_index, Eagle::Operator<'*'>()) ));
00313
00314 if(CurrentFloatIndex [0] < 0.0 ||CurrentFloatIndex [0] > max_float_index[0])
00315 break;
00316 if(CurrentFloatIndex [1] < 0.0 ||CurrentFloatIndex [1] > max_float_index[1])
00317 break;
00318 if(CurrentFloatIndex [2] < 0.0 ||CurrentFloatIndex [2] > max_float_index[2])
00319 break;
00320 Interpolate<3, tvector, CubicIpol <tvector> > VecField(*Vctrs, CurrentFloatIndex);
00321 CurrentDir = VecField.eval();
00322 }
00323
00324
00325 CurrentVertex += CurrentDir * hh;
00326 myLine.push_back(CurrentVertex);
00327 embrace( R, CurrentVertex);
00328 }
00329 }
00330
00331 printf("TexturedStreamLines::update(): Integrated into Cache\n");
00332 closeBBox( R );
00333
00334 return true;
00335 }
00336
00337
00338 void TexturedStreamLines::render( VRenderContext& Context ) const
00339 {
00340
00341
00342
00343
00344 RefPtr<Field> Vectors = getField( Context );
00345 if (!Vectors)
00346 {
00347 puts("void TexturedStreamLines::render(VRenderContext&RenderContext): NO VECTORS");
00348 return;
00349 }
00350 const RefPtr<OpCache_t>&OC = OpCache_t::retrieve( *Vectors ) ( self() );
00351 if (!OC)
00352 {
00353 puts("void TexturedStreamLines::render(VRenderContext&RenderContext): NO LINE CACHE");
00354 return;
00355 }
00356 if (OC->size()<1)
00357 {
00358 puts("void TexturedStreamLines::render(VRenderContext&RenderContext): NO LINES in CACHE");
00359 return;
00360 }
00361
00362 int line_width, point_size;
00363 int line_length = 1;
00364
00365 LineWidth << Context >> line_width;
00366 PointSize << Context >> point_size;
00367 LineLength << Context >> line_length;
00368
00369 if(line_width < 1)
00370 line_width = 1;
00371
00372 glEnable(GL_DEPTH_TEST);
00373 glDisable(GL_LIGHTING);
00374
00375 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00376 glBlendFunc(GL_ONE, GL_ONE);
00377
00378
00379 glEnable ( GL_COLOR_MATERIAL );
00380 glLineWidth( line_width );
00381
00382 if(point_size > 0)
00383 glPointSize( point_size );
00384 else
00385 glPointSize( 1 );
00386
00387 RefPtr<MyState> state = myState(Context);
00388
00389 if(!state)
00390 {
00391 printf("TexturedStreamLines::render(): Invalid State!\n");
00392 return;
00393 }
00394
00395 if (!state->LineTexture)
00396 {
00397
00398 state->LineTexture = new GlossyTexture(0);
00399 state->LineTexture->enlighten();
00400 state->LineTexture->enlighten(GlossyParameters, Context);
00401 }
00402
00403 if (!state->MyTexture)
00404 {
00405 printf("TexturedStreamLines::render, new RampTexture Created\n");
00406
00407 state->MyTexture = new RampTexture(1);
00408 state->MyTexture->enlighten();
00409 }
00410
00411 RefPtr<ValueSet> RenderParameterSpace = new ValueSet();
00412 RefPtr<DisplayList> DL;
00413 try{
00414 DL = Context(*OC)(this)( RenderParameterSpace );
00415 }
00416 catch(...){}
00417 RefPtr<ValueSet> Changeables = new ValueSet();
00418 Changeables & Context += LineLength, LineNumber, StepSize;
00419
00420
00421
00422
00423
00424
00425
00426 GlossyTexture::Render RenderLineTexture( *state->LineTexture, Context.CameraSettings );
00427
00428 glActiveTexture(GL_TEXTURE1);
00429 state->MyTexture->prerender();
00430
00431
00432 if ( DL && OC->unchanged( Changeables ))
00433 {
00434 printf("TexturedStreamLines::render(): Calling List\n");
00435 DL->call();
00436 }
00437 else
00438 {
00439 printf("TexturedStreamLines::render(): Rendering List\n");
00440
00441 DL = Context[*OC][this][ RenderParameterSpace ];
00442 if (!DL) throw "TexturedStreamLines::render() No Display List!?";
00443
00444 glCompile( *DL )
00445 {
00446 int l = 0;
00447 int p = 0;
00448
00449 for( OpCache_t::const_iterator lbit = OC->begin(); lbit != OC->end(); lbit++ )
00450 {
00451 p = 0;
00452
00453 Line_t::const_iterator lit = lbit->begin();
00454
00455 if (lit == lbit->end() )
00456 break;
00457
00458 glBegin( GL_LINE_STRIP );
00459 bivector dir;
00460
00461 for(; lit != lbit->end();)
00462 {
00463
00464 point P = *lit;
00465 lit++;
00466 if (lit != lbit->end())
00467 dir = (*lit - P).unit();
00468
00469 glMultiTexCoord3dv(GL_TEXTURE0, dir.ptr()) ;
00470 glMultiTexCoord1d (GL_TEXTURE1, (double)p/lbit->size());
00471 glVertex( P );
00472
00473 p++;
00474 }
00475
00476 l++;
00477 glEnd();
00478 }
00479
00480 glEnable( GL_BLEND );
00481
00482 if(point_size > 0 )
00483 {
00484 for( OpCache_t::const_iterator lbit = OC->begin(); lbit != OC->end(); lbit++ )
00485 {
00486 p = 0;
00487
00488 Line_t::const_iterator lit = lbit->begin();
00489
00490 if (lit == lbit->end() )
00491 break;
00492
00493 tvector dir;
00494 glBegin(GL_POINTS);
00495
00496 for(; lit != lbit->end();)
00497 {
00498
00499 point P = *lit;
00500 lit++;
00501 if (lit != lbit->end())
00502 dir = (*lit - P).unit();
00503
00504 glMultiTexCoord3dv(GL_TEXTURE0, dir.ptr()) ;
00505 glMultiTexCoord1d (GL_TEXTURE1, (double)p/lbit->size());
00506 glVertex( P );
00507
00508 p++;
00509 }
00510 glEnd();
00511 }
00512 }
00513 }
00514 }
00515
00516
00517
00518
00519
00520 state->touch();
00521 }
00522
00523
00524 static Ref< VCreator<TexturedStreamLines, AcceptList<Fiber::Field> > > myCreator("Tutorial/TexturedStreamLines");
00525
00526 VISH_DEFAULT_INIT