| | 35 | osg::Geode* createSectorForImage(osg::Image* image, osg::TexMat* texmat, float s,float t, float radius, float height, float length) |
| | 36 | { |
| | 37 | |
| | 38 | int numSegments = 20; |
| | 39 | float Theta = length/radius; |
| | 40 | float dTheta = Theta/(float)(numSegments-1); |
| | 41 | |
| | 42 | float ThetaZero = height*s/(t*radius); |
| | 43 | |
| | 44 | // set up the texture. |
| | 45 | osg::Texture2D* texture = new osg::Texture2D; |
| | 46 | texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); |
| | 47 | texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); |
| | 48 | texture->setResizeNonPowerOfTwoHint(false); |
| | 49 | texture->setImage(image); |
| | 50 | |
| | 51 | // set up the drawstate. |
| | 52 | osg::StateSet* dstate = new osg::StateSet; |
| | 53 | dstate->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); |
| | 54 | dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF); |
| | 55 | dstate->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); |
| | 56 | dstate->setTextureAttribute(0, texmat); |
| | 57 | |
| | 58 | // set up the geoset. |
| | 59 | osg::Geometry* geom = new osg::Geometry; |
| | 60 | geom->setStateSet(dstate); |
| | 61 | |
| | 62 | osg::Vec3Array* coords = new osg::Vec3Array(); |
| | 63 | osg::Vec2Array* tcoords = new osg::Vec2Array(); |
| | 64 | |
| | 65 | int i; |
| | 66 | float angle = -Theta/2.0f; |
| | 67 | for(i=0; |
| | 68 | i<numSegments; |
| | 69 | ++i, angle+=dTheta) |
| | 70 | { |
| | 71 | coords->push_back(osg::Vec3(sinf(angle)*radius,cosf(angle)*radius,height*0.5f)); // top |
| | 72 | coords->push_back(osg::Vec3(sinf(angle)*radius,cosf(angle)*radius,-height*0.5f)); // bottom. |
| | 73 | |
| | 74 | tcoords->push_back(osg::Vec2(angle/ThetaZero+0.5f,1.0f)); // top |
| | 75 | tcoords->push_back(osg::Vec2(angle/ThetaZero+0.5f,0.0f)); // bottom. |
| | 76 | |
| | 77 | } |
| | 78 | |
| | 79 | osg::Vec4Array* colors = new osg::Vec4Array(); |
| | 80 | colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); |
| | 81 | |
| | 82 | osg::DrawArrays* elements = new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,coords->size()); |
| | 83 | |
| | 84 | |
| | 85 | |
| | 86 | geom->setVertexArray(coords); |
| | 87 | geom->setTexCoordArray(0,tcoords); |
| | 88 | geom->setColorArray(colors); |
| | 89 | geom->setColorBinding(osg::Geometry::BIND_OVERALL); |
| | 90 | |
| | 91 | geom->addPrimitiveSet(elements); |
| | 92 | |
| | 93 | // set up the geode. |
| | 94 | osg::Geode* geode = new osg::Geode; |
| | 95 | geode->addDrawable(geom); |
| | 96 | |
| | 97 | return geode; |
| | 98 | |
| | 99 | } |
| | 100 | |
| | 101 | osg::Group * loadImages(std::string image1, std::string image2, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length) { |
| | 102 | osg::ref_ptr<osg::Image> imageLeft = osgDB::readImageFile(image1); |
| | 103 | osg::ref_ptr<osg::Image> imageRight = osgDB::readImageFile(image2); |
| | 104 | if (imageLeft.valid() && imageRight.valid()) |
| | 105 | { |
| | 106 | float average_s = (imageLeft->s()+imageRight->s())*0.5f; |
| | 107 | float average_t = (imageLeft->t()+imageRight->t())*0.5f; |
| | 108 | osg::Geode* geodeLeft = createSectorForImage(imageLeft.get(),texmatLeft,average_s,average_t, radius, height, length); |
| | 109 | geodeLeft->setNodeMask(0x01); |
| | 110 | |
| | 111 | osg::Geode* geodeRight = createSectorForImage(imageRight.get(),texmatRight,average_s,average_t, radius, height, length); |
| | 112 | geodeRight->setNodeMask(0x02); |
| | 113 | |
| | 114 | osg::Group * imageGroup = new osg::Group; |
| | 115 | |
| | 116 | imageGroup->addChild(geodeLeft); |
| | 117 | imageGroup->addChild(geodeRight); |
| | 118 | return imageGroup; |
| | 119 | } |
| | 120 | else |
| | 121 | { |
| | 122 | std::cout << "Warning: Unable to load both image files, '"<<image1<<"' & '"<<image2<<"', required for stereo imaging."<<std::endl; |
| | 123 | return 0; |
| | 124 | } |
| | 125 | } |
| | 126 | |
| | 127 | // create a switch containing a set of child each containing a |
| | 128 | // stereo image pair. |
| | 129 | osg::Switch* createScene(FileList fileList, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length) |
| | 130 | { |
| | 131 | osg::Switch* sw = new osg::Switch; |
| | 132 | |
| | 133 | // load the images. |
| | 134 | for(unsigned int i=0;i+1<fileList.size();i+=2) |
| | 135 | { |
| | 136 | osg::Group * imageGroup = loadImages(fileList[i],fileList[i+1],texmatLeft,texmatRight, radius, height, length); |
| | 137 | if (imageGroup) sw->addChild(imageGroup); |
| | 138 | } |
| | 139 | |
| | 140 | |
| | 141 | if (sw->getNumChildren()>0) |
| | 142 | { |
| | 143 | // select first child. |
| | 144 | sw->setSingleChildOn(0); |
| | 145 | } |
| | 146 | |
| | 147 | return sw; |
| | 148 | } |
| | 149 | |
| | 238 | |
| | 239 | void SlideEventHandler::set(FileList fileList, osg::Switch* sw, float offsetX, float offsetY, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length, float timePerSlide, bool autoSteppingActive) |
| | 240 | { |
| | 241 | _switch = sw; |
| | 242 | _switch->setUpdateCallback(this); |
| | 243 | _fileList=FileList(fileList); |
| | 244 | |
| | 245 | osg::ref_ptr<osg::Group> imageGroup = loadImages(fileList[0],fileList[1],texmatLeft,texmatRight, radius, height, length); |
| | 246 | if (imageGroup.get())_switch->addChild(imageGroup.get()); |
| | 247 | |
| | 248 | _texmatLeft = texmatLeft; |
| | 249 | _texmatRight = texmatRight; |
| | 250 | |
| | 251 | _radius=radius; |
| | 252 | _height=height; |
| | 253 | _length=length; |
| | 254 | |
| | 255 | _timePerSlide = timePerSlide; |
| | 256 | _autoSteppingActive = autoSteppingActive; |
| | 257 | |
| | 258 | _initSeperationX = offsetX; |
| | 259 | _currentSeperationX = _initSeperationX; |
| | 260 | |
| | 261 | _initSeperationY = offsetY; |
| | 262 | _currentSeperationY = _initSeperationY; |
| | 263 | |
| | 264 | initTexMatrices(); |
| | 265 | } |
| | 266 | |
| 284 | | osg::Geode* createSectorForImage(osg::Image* image, osg::TexMat* texmat, float s,float t, float radius, float height, float length) |
| 285 | | { |
| 286 | | |
| 287 | | int numSegments = 20; |
| 288 | | float Theta = length/radius; |
| 289 | | float dTheta = Theta/(float)(numSegments-1); |
| 290 | | |
| 291 | | float ThetaZero = height*s/(t*radius); |
| 292 | | |
| 293 | | // set up the texture. |
| 294 | | osg::Texture2D* texture = new osg::Texture2D; |
| 295 | | texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); |
| 296 | | texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); |
| 297 | | texture->setImage(image); |
| 298 | | |
| 299 | | // set up the drawstate. |
| 300 | | osg::StateSet* dstate = new osg::StateSet; |
| 301 | | dstate->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); |
| 302 | | dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF); |
| 303 | | dstate->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); |
| 304 | | dstate->setTextureAttribute(0, texmat); |
| 305 | | |
| 306 | | // set up the geoset. |
| 307 | | osg::Geometry* geom = new osg::Geometry; |
| 308 | | geom->setStateSet(dstate); |
| 309 | | |
| 310 | | osg::Vec3Array* coords = new osg::Vec3Array(); |
| 311 | | osg::Vec2Array* tcoords = new osg::Vec2Array(); |
| 312 | | |
| 313 | | int i; |
| 314 | | float angle = -Theta/2.0f; |
| 315 | | for(i=0; |
| 316 | | i<numSegments; |
| 317 | | ++i, angle+=dTheta) |
| 318 | | { |
| 319 | | coords->push_back(osg::Vec3(sinf(angle)*radius,cosf(angle)*radius,height*0.5f)); // top |
| 320 | | coords->push_back(osg::Vec3(sinf(angle)*radius,cosf(angle)*radius,-height*0.5f)); // bottom. |
| 321 | | |
| 322 | | tcoords->push_back(osg::Vec2(angle/ThetaZero+0.5f,1.0f)); // top |
| 323 | | tcoords->push_back(osg::Vec2(angle/ThetaZero+0.5f,0.0f)); // bottom. |
| 324 | | |
| 325 | | } |
| 326 | | |
| 327 | | osg::Vec4Array* colors = new osg::Vec4Array(); |
| 328 | | colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); |
| 329 | | |
| 330 | | osg::DrawArrays* elements = new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,coords->size()); |
| 331 | | |
| 332 | | |
| 333 | | |
| 334 | | geom->setVertexArray(coords); |
| 335 | | geom->setTexCoordArray(0,tcoords); |
| 336 | | geom->setColorArray(colors); |
| 337 | | geom->setColorBinding(osg::Geometry::BIND_OVERALL); |
| 338 | | |
| 339 | | geom->addPrimitiveSet(elements); |
| 340 | | |
| 341 | | // set up the geode. |
| 342 | | osg::Geode* geode = new osg::Geode; |
| 343 | | geode->addDrawable(geom); |
| 344 | | |
| 345 | | return geode; |
| 346 | | |
| 347 | | } |
| 348 | | |
| 349 | | // create a switch containing a set of child each containing a |
| 350 | | // stereo image pair. |
| 351 | | osg::Switch* createScene(const FileList& fileList, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length) |
| 352 | | { |
| 353 | | osg::Switch* sw = new osg::Switch; |
| 354 | | |
| 355 | | // load the images. |
| 356 | | for(unsigned int i=0;i+1<fileList.size();i+=2) |
| 357 | | { |
| 358 | | osg::ref_ptr<osg::Image> imageLeft = osgDB::readImageFile(fileList[i]); |
| 359 | | osg::ref_ptr<osg::Image> imageRight = osgDB::readImageFile(fileList[i+1]); |
| 360 | | if (imageLeft.valid() && imageRight.valid()) |
| 361 | | { |
| 362 | | float average_s = (imageLeft->s()+imageRight->s())*0.5f; |
| 363 | | float average_t = (imageLeft->t()+imageRight->t())*0.5f; |
| 364 | | |
| 365 | | osg::Geode* geodeLeft = createSectorForImage(imageLeft.get(),texmatLeft,average_s,average_t, radius, height, length); |
| 366 | | geodeLeft->setNodeMask(0x01); |
| 367 | | |
| 368 | | osg::Geode* geodeRight = createSectorForImage(imageRight.get(),texmatRight,average_s,average_t, radius, height, length); |
| 369 | | geodeRight->setNodeMask(0x02); |
| 370 | | |
| 371 | | osg::ref_ptr<osg::Group> imageGroup = new osg::Group; |
| 372 | | |
| 373 | | imageGroup->addChild(geodeLeft); |
| 374 | | imageGroup->addChild(geodeRight); |
| 375 | | |
| 376 | | sw->addChild(imageGroup.get()); |
| 377 | | } |
| 378 | | else |
| 379 | | { |
| 380 | | std::cout << "Warning: Unable to load both image files, '"<<fileList[i]<<"' & '"<<fileList[i+1]<<"', required for stereo imaging."<<std::endl; |
| 381 | | } |
| 382 | | } |
| 383 | | |
| 384 | | |
| 385 | | if (sw->getNumChildren()>0) |
| 386 | | { |
| 387 | | // select first child. |
| 388 | | sw->setSingleChildOn(0); |
| 389 | | } |
| 390 | | |
| 391 | | return sw; |
| 392 | | } |