00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "waterplan.h"
00024
00025
00026
00027 class ConstructStateCallback : public osgProducer::OsgCameraGroup::RealizeCallback
00028 {
00029 public:
00030 ConstructStateCallback(osg::Node* node1,osg::Node* node2):_node1(node1),_node2(node2),_initialized(false) {}
00031
00032 osg::StateSet* constructState(osg::Node* _node)
00033 {
00034
00035
00036 osg::ref_ptr<osg::Image> image_0 = osgDB::readImageFile("Textures/eau.jpg");
00037 osg::ref_ptr<osg::Image> image_1 = osgDB::readImageFile("Textures/eau2.jpg");
00038 osg::ref_ptr<osg::Image> image_2 = osgDB::readImageFile("Textures/eau111.jpg");
00039 osg::ref_ptr<osg::Image> image_3 = osgDB::readImageFile("Textures/eau2.jpg");
00040
00041 if (!image_0 || !image_1 || !image_2 || !image_3)
00042 {
00043 std::cout << "Warning: could not open files."<<std::endl;
00044 return new osg::StateSet;
00045 }
00046
00047 if (image_0->getPixelFormat()!=image_1->getPixelFormat() || image_0->getPixelFormat()!=image_2->getPixelFormat() || image_0->getPixelFormat()!=image_3->getPixelFormat())
00048 {
00049 std::cout << "Warning: image pixel formats not compatible."<<std::endl;
00050 return new osg::StateSet;
00051 }
00052
00053
00054 GLint textureSize = osg::Texture3D::getExtensions(0,true)->maxTexture3DSize();
00055 if (textureSize > 256)
00056 textureSize = 256;
00057
00058
00059 image_0->scaleImage(textureSize,textureSize,1);
00060 image_1->scaleImage(textureSize,textureSize,1);
00061 image_2->scaleImage(textureSize,textureSize,1);
00062 image_3->scaleImage(textureSize,textureSize,1);
00063
00064
00065
00066 osg::Image* image_3d = new osg::Image;
00067 image_3d->allocateImage(textureSize,textureSize,4,
00068 image_0->getPixelFormat(),image_0->getDataType());
00069
00070
00071 image_3d->copySubImage(0,0,0,image_0.get());
00072 image_3d->copySubImage(0,0,1,image_1.get());
00073 image_3d->copySubImage(0,0,2,image_2.get());
00074 image_3d->copySubImage(0,0,3,image_3.get());
00075
00076 image_3d->setInternalTextureFormat(image_0->getInternalTextureFormat());
00077
00078
00079
00080
00081
00082 osg::Texture3D* texture3D = new osg::Texture3D;
00083 texture3D->setFilter(osg::Texture3D::MIN_FILTER,osg::Texture3D::LINEAR);
00084 texture3D->setFilter(osg::Texture3D::MAG_FILTER,osg::Texture3D::LINEAR);
00085 texture3D->setWrap(osg::Texture3D::WRAP_S,osg::Texture3D::REPEAT);
00086 texture3D->setWrap(osg::Texture3D::WRAP_T,osg::Texture3D::REPEAT);
00087 texture3D->setWrap(osg::Texture3D::WRAP_R,osg::Texture3D::REPEAT);
00088 texture3D->setImage(image_3d);
00089
00090
00091
00092
00093
00094
00095
00096 osg::TexGen* texgen = new osg::TexGen;
00097 texgen->setMode(osg::TexGen::OBJECT_LINEAR);
00098
00099 if (_node1 == _node )
00100 texgen->setPlane(osg::TexGen::R, osg::Vec4(1.0f,0.0f,0.0f,0.2f));
00101 else
00102 texgen->setPlane(osg::TexGen::R, osg::Vec4(-0.4f,0.3f,0.3f,0.1f));
00103
00104
00105
00106 osg::StateSet* stateset = _node->getOrCreateStateSet();
00107
00108 stateset->setTextureMode(0,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
00109 stateset->setTextureAttribute(0,texgen);
00110 stateset->setTextureAttributeAndModes(0,texture3D,osg::StateAttribute::ON);
00111
00112 return stateset;
00113 }
00114
00115 virtual void operator()( osgProducer::OsgCameraGroup&, osgProducer::OsgSceneHandler& sh, const Producer::RenderSurface& )
00116 {
00117 {
00118 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
00119
00120 if (!_initialized)
00121 {
00122
00123
00124
00125 _initialized = true;
00126
00127 if (_node1) _node1->setStateSet(constructState(_node1));
00128 if (_node2) _node2->setStateSet(constructState(_node2));
00129 }
00130
00131
00132 }
00133
00134
00135 sh.init();
00136
00137 }
00138
00139
00140 OpenThreads::Mutex _mutex;
00141 bool _initialized;
00142 osg::Node* _node1;
00143 osg::Node* _node2;
00144
00145 };
00146
00147 class UpdateStateCallback : public osg::NodeCallback
00148 {
00149 public:
00150 osg::Vec4 depl ;
00151 public:
00152 UpdateStateCallback(osg::Vec4 d):depl(d) {}
00153
00154 void animateState(osg::StateSet* stateset)
00155 {
00156
00157
00158 osg::StateAttribute* attribute = stateset->getTextureAttribute(0,osg::StateAttribute::TEXGEN);
00159 osg::TexGen* texgen = dynamic_cast<osg::TexGen*>(attribute);
00160 if (texgen)
00161 {
00162
00163
00164 texgen->getPlane(osg::TexGen::R)[0] = depl.x();
00165 texgen->getPlane(osg::TexGen::R)[1] = depl.y();
00166 texgen->getPlane(osg::TexGen::R)[2] = depl.z();
00167 texgen->getPlane(osg::TexGen::R)[3] += depl.w();
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 }
00181
00182 }
00183
00184 virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
00185 {
00186
00187 osg::StateSet* stateset = node->getStateSet();
00188 if (stateset)
00189 {
00190
00191 animateState(stateset);
00192 }
00193
00194
00195
00196
00197 traverse(node,nv);
00198 }
00199 };
00200
00201 waterPlan::waterPlan()
00202 {
00203 water_geometry=NULL;
00204 water_geode=NULL;
00205 deplacement_texture = osg::Vec4(0.021f,0.001f,0.021f,0.005f);
00206 densite_texture=25;
00207 }
00208
00209
00210 waterPlan::~waterPlan()
00211 {
00212 }
00213
00214
00215 void waterPlan::setPlan(float xMin,float xMax,float yMin,float yMax,float z)
00216 {
00217 this->xMin=xMin;
00218 this->xMax=xMax;
00219 this->yMin=yMin;
00220 this->yMax=yMax;
00221 this->z=z;
00222 }
00223 void waterPlan::setTexture(std::string tex, float densite)
00224 {
00225 this->densite_texture=densite;
00226 this->texture = tex;
00227
00228 }
00229 void waterPlan::setDeplacementWater(osg::Vec4 depl)
00230 {
00231 deplacement_texture = depl;
00232
00233 }
00234 osg::Drawable* waterPlan::createMirrorSurface()
00235 {
00236
00237
00238 float densite_texture2=densite_texture;
00239 float d_txtX = densite_texture/(xMax - xMin) ;
00240 float d_txtY = densite_texture/(yMax - yMin);
00241
00242
00243
00244 water_geometry = new osg::Geometry;
00245
00246 osg::Vec3Array* coords = new osg::Vec3Array(5);
00247 (*coords)[0].set(xMin-16.5,yMax-20,z);
00248 (*coords)[1].set(xMin-27.5,yMax+0,z);
00249 (*coords)[2].set(xMin,yMin,z);
00250 (*coords)[3].set(xMax,yMin,z);
00251 (*coords)[4].set(xMax+11,yMax,z);
00252 water_geometry->setVertexArray(coords);
00253
00254 osg::Vec3Array* norms = new osg::Vec3Array(1);
00255 (*norms)[0].set(0.0f,0.0f,1.0f);
00256 water_geometry->setNormalArray(norms);
00257 water_geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
00258
00259 osg::Vec2Array* tcoords = new osg::Vec2Array(5);
00260 (*tcoords)[0].set(0.0f-15.5*d_txtX,densite_texture2*4-20*d_txtY*4);
00261 (*tcoords)[1].set(0.0f-27.5*d_txtX,densite_texture2*4);
00262 (*tcoords)[2].set(0.0f,0.0f);
00263 (*tcoords)[3].set(densite_texture2,0.0f);
00264 (*tcoords)[4].set(densite_texture2+12*d_txtX,densite_texture2*4);
00265 water_geometry->setTexCoordArray(0,tcoords);
00266
00267
00268 osg::Vec4Array* colours = new osg::Vec4Array(1);
00269 (*colours)[0].set(0.8f,0.8f,0.8f,0.7f);
00270 water_geometry->setColorArray(colours);
00271 water_geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
00272
00273
00274 water_geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,0,5));
00275
00276
00277
00278 return water_geometry;
00279 }
00280
00281 osg::Drawable* waterPlan::createMirrorSurfaceForTheDam(float x)
00282 {
00283
00284
00285 float dx=6.3;
00286 float dy=3.0;
00287 float dx2=2.2;
00288 float dx_texture=densite_texture * dx/(xMax - xMin) ;
00289 float dx_texture2=densite_texture * dx2/(xMax - xMin) ;
00290 float dy_texture=densite_texture * dy/(yMax - yMin);
00291 float d_txtX = densite_texture/(xMax - xMin) ;
00292 float d_txtY = densite_texture/(yMax - yMin);
00293
00294
00295
00296 water_geometry = new osg::Geometry;
00297
00298 int i=0;
00299
00300 osg::Vec3Array* coords = new osg::Vec3Array(11);
00301 (*coords)[i++].set(xMin,yMax-36,z);
00302 (*coords)[i++].set(xMin+35,yMin,z);
00303 (*coords)[i++].set(x-dx,yMin,z);
00304 (*coords)[i++].set(x-dx2,yMin+dy,z);
00305 (*coords)[i++].set(x,yMin+dy,z);
00306 (*coords)[i++].set(x,yMax+14,z);
00307 (*coords)[i++].set(x,yMin+dy,z);
00308 (*coords)[i++].set(x+dx2,yMin+dy,z);
00309 (*coords)[i++].set(x+dx,yMin,z);
00310 (*coords)[i++].set(xMax+23,yMin+10,z);
00311 (*coords)[i++].set(xMax-45,yMax+36,z);
00312 water_geometry->setVertexArray(coords);
00313
00314 osg::Vec3Array* norms = new osg::Vec3Array(2);
00315 (*norms)[0].set(0.0f,0.0f,1.0f);
00316 (*norms)[1].set(0.0f,0.0f,1.0f);
00317 water_geometry->setNormalArray(norms);
00318 water_geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
00319
00320 i=0;
00321 osg::Vec2Array* tcoords = new osg::Vec2Array(11);
00322 (*tcoords)[i++].set(0.0f,densite_texture-37*d_txtY);
00323 (*tcoords)[i++].set(0.0f+35*d_txtX,0.0f);
00324 (*tcoords)[i++].set(densite_texture/2.-dx_texture,0.0f);
00325 (*tcoords)[i++].set(densite_texture/2.-dx_texture2,dy_texture);
00326 (*tcoords)[i++].set(densite_texture/2.,dy_texture);
00327 (*tcoords)[i++].set(densite_texture/2.,densite_texture+14*d_txtY);
00328 (*tcoords)[i++].set(densite_texture/2.,dy_texture);
00329 (*tcoords)[i++].set(densite_texture/2.+dx_texture2,dy_texture);
00330 (*tcoords)[i++].set(densite_texture/2.+dx_texture,0.0f);
00331 (*tcoords)[i++].set(densite_texture+24*d_txtX,0.0f+10*d_txtY);
00332 (*tcoords)[i++].set(densite_texture-46*d_txtX,densite_texture+36*d_txtY);
00333 water_geometry->setTexCoordArray(0,tcoords);
00334
00335 osg::Vec4Array* colours = new osg::Vec4Array(1);
00336 (*colours)[0].set(1.0f,1.0f,1.0,0.7f);
00337 water_geometry->setColorArray(colours);
00338 water_geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
00339
00340 water_geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,0,6));
00341 water_geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,5,6));
00342
00343
00344 return water_geometry;
00345 }
00346
00347 osg::Drawable* waterPlan::createSurfaceBehindForTheDam(float x,float dz)
00348 {
00349
00350
00351 float dx=6.3;
00352 float dy=3.0;
00353 float dx2=2.2;
00354 float dx_texture=densite_texture * dx/(xMax - xMin) ;
00355 float dx_texture2=densite_texture * dx2/(xMax - xMin) ;
00356 float dy_texture=densite_texture * dy/(yMax - yMin);
00357 float d_txtX = densite_texture/(xMax - xMin) ;
00358 float d_txtY = densite_texture/(yMax - yMin);
00359
00360
00361
00362 water_geometry = new osg::Geometry;
00363
00364 int i=0;
00365
00366 osg::Vec3Array* coords = new osg::Vec3Array(11);
00367 (*coords)[i++].set(xMin,yMax-36,z+dz);
00368 (*coords)[i++].set(xMin+35,yMin,z+dz);
00369 (*coords)[i++].set(x-dx,yMin,z+dz);
00370 (*coords)[i++].set(x-dx2,yMin+dy,z+dz);
00371 (*coords)[i++].set(x,yMin+dy,z+dz);
00372 (*coords)[i++].set(x,yMax+14,z+dz);
00373 (*coords)[i++].set(x,yMin+dy,z+dz);
00374 (*coords)[i++].set(x+dx2,yMin+dy,z+dz);
00375 (*coords)[i++].set(x+dx,yMin,z+dz);
00376 (*coords)[i++].set(xMax+23,yMin+10,z+dz);
00377 (*coords)[i++].set(xMax-45,yMax+36,z+dz);
00378 water_geometry->setVertexArray(coords);
00379
00380 osg::Vec3Array* norms = new osg::Vec3Array(1);
00381 (*norms)[0].set(0.0f,0.0f,-1.0f);
00382 water_geometry->setNormalArray(norms);
00383 water_geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
00384
00385 i=0;
00386 osg::Vec2Array* tcoords = new osg::Vec2Array(11);
00387 (*tcoords)[i++].set(0.0f,densite_texture);
00388 (*tcoords)[i++].set(0.0f,0.0f);
00389 (*tcoords)[i++].set(densite_texture/2.-dx_texture,0.0f);
00390 (*tcoords)[i++].set(densite_texture/2.-dx_texture2,dy_texture);
00391 (*tcoords)[i++].set(densite_texture/2.,dy_texture);
00392 (*tcoords)[i++].set(densite_texture/2.,densite_texture);
00393 (*tcoords)[i++].set(densite_texture/2.,dy_texture);
00394 (*tcoords)[i++].set(densite_texture/2.+dx_texture2,dy_texture);
00395 (*tcoords)[i++].set(densite_texture/2.+dx_texture,0.0f);
00396 (*tcoords)[i++].set(densite_texture,0.0f);
00397 (*tcoords)[i++].set(densite_texture,densite_texture);
00398 water_geometry->setTexCoordArray(0,tcoords);
00399
00400 osg::Vec4Array* colours = new osg::Vec4Array(1);
00401 (*colours)[0].set(0.0f,0.0f,0.05f,0.2f);
00402 water_geometry->setColorArray(colours);
00403 water_geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
00404
00405 water_geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,0,6));
00406 water_geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,5,6));
00407
00408
00409 return water_geometry;
00410 }
00411 osg::Drawable* waterPlan::getOrCreateDrawable()
00412 {
00413 if(water_geometry==NULL)
00414 return createMirrorSurface();
00415 else
00416 return water_geometry;
00417 }
00418
00419 osg::StateSet* waterPlan::createMirrorTexturedState()
00420 {
00421 osg::StateSet* dstate = new osg::StateSet;
00422
00423
00424
00425
00426 dstate->setMode(GL_CULL_FACE,osg::StateAttribute::OFF|osg::StateAttribute::PROTECTED);
00427
00428 if(texture!="")
00429 {
00430 osg::Image* image = osgDB::readImageFile(texture.c_str());
00431 if (image)
00432 {
00433 osg::Texture2D* texture = new osg::Texture2D;
00434 texture->setImage(image);
00435 texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
00436 texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
00437 dstate->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON|osg::StateAttribute::PROTECTED);
00438
00439 }
00440 }
00441 return dstate;
00442 }
00443
00444 osg::Geode* waterPlan::getOrCreateGeodeWater(osg::StateSet* stateset)
00445 {
00446 if(water_geode==NULL)
00447 {
00448 if(water_geometry==NULL)
00449 createMirrorSurface();
00450
00451 water_geode = new osg::Geode;
00452 water_geode->addDrawable(water_geometry);
00453
00454 water_geode->setStateSet(stateset);
00455
00456
00457
00458
00459 UpdateStateCallback* update= new UpdateStateCallback(deplacement_texture);
00460
00461
00462 water_geode->setUpdateCallback(update);
00463
00464
00465
00466
00467
00468
00469
00470 return water_geode;
00471
00472 }else
00473 return water_geode;
00474 }
00475
00476 osg::Geode* waterPlan::createGeodeUnderWater(float x,float dz)
00477 {
00478 osg::StateSet* stateset = createMirrorTexturedState();
00479
00480 osg::Geode * under_water_geode = new osg::Geode;
00481
00482 under_water_geode->addDrawable(createSurfaceBehindForTheDam(x,dz));
00483
00484 under_water_geode->setStateSet(stateset);
00485
00486 return under_water_geode;
00487 }
00489 ConstructStateCallback* waterPlan::getStateCallback(osg::Node* node1,osg::Node* node2)
00490 {
00491
00492 ConstructStateCallback* cscb = new ConstructStateCallback(node1,node2);
00493
00494
00495 return cscb;
00496
00497 }