00001 #include <ocean/GLvish/VRenderObject.hpp>
00002
00003 #include <fish/lakeview/bone/FishSlice.hpp>
00004 #include <fish/lakeview/bone/FishField.hpp>
00005
00006 #include <field/DirectProductArray.hpp>
00007 #include <ocean/GLvish/BoundingBox.hpp>
00008
00009 using namespace Wizt;
00010 using namespace Fiber;
00011
00012
00035 class VectorFieldLines : public virtual VRenderObject, virtual public Fish<Slice>, virtual public Fish<Field>
00036 {
00037 public:
00038
00039
00040
00041 typedef MemArray<3, Eagle::tvector3> VectorArray_t;
00042 typedef MemArray<3, Eagle::point3> CoordsArray_t;
00043 typedef DirectProductMemArray<Eagle::point3> ProceduralArray_t;
00044
00045
00046 TypedSlot<double> LineLength;
00047 TypedSlot<int> LineWidth;
00048
00049
00050
00051 struct MyState : State
00052 {
00053 double line_length;
00054 double line_width;
00055 RefPtr<Field> Coords,
00056 Vectors;
00057
00058 bool changed( const double ll, const int lw)
00059 {
00060 if ( ll != line_length || lw != line_width)
00061 return true;
00062 return false;
00063 }
00064
00065 void update( const double ll, const int lw)
00066 {
00067 line_length = ll;
00068 line_width = lw;
00069 }
00070 };
00071
00072 override RefPtr<State> newState() const
00073 {
00074 return new MyState();
00075 }
00076
00077
00078
00079 VectorFieldLines(const string&name, int p, const RefPtr<VCreationPreferences>&VP)
00080 : VRenderObject(name, p, VP)
00081 , Fish<VObject>(this)
00082 , Fish<Field>("datafield")
00083 , LineLength(this, "LineLength", 0.1)
00084 , LineWidth(this, "LineWidth", 1)
00085 {
00086 LineLength.setProperty("max", 10.0);
00087 LineWidth.setProperty("max", 10);
00088
00089 acceptType<Eagle::tvector3>();
00090 }
00091
00092
00093 override bool update( VRequest&R, double precision );
00094 override void render( VRenderContext&R ) const;
00095 };
00096
00097
00098
00103 bool VectorFieldLines::update( VRequest&R, double precision )
00104 {
00105 printf("VectorFieldLines::update(): updating\n");
00106
00107 FieldSelector FS = getFieldSelector(R);
00108
00109
00110 RefPtr<Grid> G = FS.GridSource();
00111 if (!G)
00112 {
00113 if (RefPtr<MyState> S = getState(R) )
00114 {
00115 S-> Coords = NullPtr();
00116 S-> Vectors = NullPtr();
00117 }
00118 return true;
00119 }
00120
00121
00122 RefPtr<Field> Coords = G->CartesianPositions();
00123 if (!Coords) { puts("VectorFieldLines::update(): No coord field!"); return true; }
00124
00125
00126
00127 RefPtr<Field> Vectors = FS.getField() ;
00128 if (!Vectors) { puts("VectorFieldLines::update(): No vector field!"); return true; }
00129
00130
00131
00132 RefPtr<MyState> S = myState(R);
00133
00134 assert(S);
00135
00136
00137 S -> Coords = Coords;
00138 S -> Vectors = Vectors;
00139
00140 return true;
00141 }
00142
00143
00144 void VectorFieldLines::render( VRenderContext& Context ) const
00145 {
00146
00147
00148 printf("VectorFieldLines::render(): starting to render\n");
00149 double line_length = 0.0;
00150 int line_width = 2;
00151
00152 LineLength << Context >> line_length;
00153 LineWidth << Context >> line_width;
00154
00155 glEnable(GL_DEPTH_TEST);
00156 glDisable(GL_LIGHTING);
00157
00158
00159 RefPtr<MyState> state = myState(Context);
00160
00161
00162 if(!state)
00163 {
00164 printf("VectorFieldLines::render(): Invalid State!\n");
00165 return;
00166 }
00167 if (!state->Coords)
00168 {
00169 printf("VectorFieldLines::render(): Invalid Coordinates!\n");
00170 return;
00171 }
00172 if (!state->Vectors)
00173 {
00174 printf("VectorFieldLines::render(): Invalid Vectors!\n");
00175 return;
00176 }
00177
00178
00179 RefPtr<ValueSet> RenderParameterSpace = new ValueSet();
00180
00181 RefPtr<DisplayList> DL;
00182 try{
00183 DL = Context(*state)(this)( RenderParameterSpace );
00184 }
00185 catch(...){}
00186 if (DL && !state->changed(line_length, line_width) )
00187 {
00188 if(DL->call())
00189 {
00190 printf("VectorFieldLines::render(): Called List\n");
00191 return;
00192 }
00193 }
00194 else
00195 {
00196 DL = Context[*state][this][ RenderParameterSpace ];
00197 if (!DL) throw "VectorFieldLines::render() No Display List!?";
00198
00199 state->update( line_length, line_width);
00200
00201
00202
00203
00204
00205 RefPtr<ProceduralArray_t> PCrds = state->Coords->getData();
00206 RefPtr<CoordsArray_t> Crds = state->Coords->getData();
00207 if (!(Crds || PCrds))
00208 {
00209 printf("VectorFieldLines::render(): Did not find any coordinates : %s\n",
00210 Typename( state->Coords->getType() ).c_str() );
00211 return;
00212 }
00213
00214 if (PCrds)
00215 {
00216 point Start = PCrds->first();
00217 point End = PCrds->last();
00218 setBoundingBall(Context, new BoundingBox(Start, End) );
00219 printf("VectorFieldLines::render(): got procedural coordinates\n" );
00220 }
00221 if (Crds)
00222 {
00223 point Start = Crds->first();
00224 point End = Crds->last();
00225 setBoundingBall(Context, new BoundingBox(Start, End) );
00226 printf("VectorFieldLines::render(): got numerical coordinates\n" );
00227 }
00228
00229
00230
00231 RefPtr<VectorArray_t> Vctrs = state->Vectors->getData();
00232 if (!Vctrs)
00233 {
00234 printf("VectorFieldLines::render(): No vectors\n" );
00235 return;
00236 }
00237 else
00238 printf("VectorFieldLines::render(): got Vectors data\n" );
00239
00240
00241
00242 MultiIndex<3> M;
00243
00244 glCompile( *DL )
00245 {
00246 printf("VectorFieldLines::render(): compiling new list\n");
00247 glLineWidth(line_width);
00248 glBegin(GL_LINES);
00249 glColor3f(1.0,1.0,1.0);
00250
00251 do
00252 {
00253 point Vertex, VertexTo;
00254
00255 if (Crds)
00256 {
00257 Vertex = (*Crds)[M];
00258 }
00259 else
00260 {
00261 Vertex = (*PCrds)[M];
00262 }
00263
00264
00265 tvector Vector = (*Vctrs)[M];
00266 VertexTo = Vertex + Vector * line_length;
00267
00268
00269 glVertex(Vertex);
00270 glVertex(VertexTo);
00271
00272
00273
00274
00275 }
00276 while( M.inc( (*Vctrs).Size() ) );
00277
00278 glEnd();
00279
00280 }
00281
00282 }
00283 }
00284
00285
00286 static Ref<VCreator<VectorFieldLines, AcceptList<Fiber::BundlePtr> > > myCreator("Tutorial/VectorFieldLines");
00287
00288 VISH_DEFAULT_INIT