Changeset 6624 for OpenSceneGraph/trunk/examples/osgmovie/osgmovie.cpp
- Timestamp:
- 05/08/07 14:18:57 (6 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/examples/osgmovie/osgmovie.cpp
r5953 r6624 11 11 #include <osg/Texture2D> 12 12 #include <osg/TextureRectangle> 13 #include <osg/TextureCubeMap> 13 14 #include <osg/TexMat> 14 15 #include <osg/CullFace> … … 26 27 public: 27 28 28 MovieEventHandler() {} 29 MovieEventHandler():_trackMouse(false) {} 30 31 void setMouseTracking(bool track) { _trackMouse = track; } 32 bool getMouseTracking() const { return _trackMouse; } 29 33 30 34 void set(osg::Node* node); … … 92 96 93 97 98 bool _trackMouse; 94 99 ImageStreamList _imageStreamList; 95 100 … … 117 122 case(osgGA::GUIEventAdapter::RELEASE): 118 123 { 119 120 osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa); 121 osgUtil::LineSegmentIntersector::Intersections intersections; 122 if (view && view->computeIntersections(ea.getX(), ea.getY(), nv->getNodePath(), intersections)) 123 { 124 125 // use the nearest intersection 126 const osgUtil::LineSegmentIntersector::Intersection& intersection = *(intersections.begin()); 127 osg::Drawable* drawable = intersection.drawable.get(); 128 osg::Geometry* geometry = drawable ? drawable->asGeometry() : 0; 129 osg::Vec3Array* vertices = geometry ? dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()) : 0; 130 if (vertices) 131 { 132 // get the vertex indices. 133 const osgUtil::LineSegmentIntersector::Intersection::IndexList& indices = intersection.indexList; 134 const osgUtil::LineSegmentIntersector::Intersection::RatioList& ratios = intersection.ratioList; 135 136 if (indices.size()==3 && ratios.size()==3) 124 if (_trackMouse) 125 { 126 osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa); 127 osgUtil::LineSegmentIntersector::Intersections intersections; 128 if (view && view->computeIntersections(ea.getX(), ea.getY(), nv->getNodePath(), intersections)) 129 { 130 131 // use the nearest intersection 132 const osgUtil::LineSegmentIntersector::Intersection& intersection = *(intersections.begin()); 133 osg::Drawable* drawable = intersection.drawable.get(); 134 osg::Geometry* geometry = drawable ? drawable->asGeometry() : 0; 135 osg::Vec3Array* vertices = geometry ? dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()) : 0; 136 if (vertices) 137 137 { 138 unsigned int i1 = indices[0]; 139 unsigned int i2 = indices[1]; 140 unsigned int i3 = indices[2]; 141 142 float r1 = ratios[0]; 143 float r2 = ratios[1]; 144 float r3 = ratios[2]; 145 146 osg::Array* texcoords = (geometry->getNumTexCoordArrays()>0) ? geometry->getTexCoordArray(0) : 0; 147 osg::Vec2Array* texcoords_Vec2Array = dynamic_cast<osg::Vec2Array*>(texcoords); 148 if (texcoords_Vec2Array) 138 // get the vertex indices. 139 const osgUtil::LineSegmentIntersector::Intersection::IndexList& indices = intersection.indexList; 140 const osgUtil::LineSegmentIntersector::Intersection::RatioList& ratios = intersection.ratioList; 141 142 if (indices.size()==3 && ratios.size()==3) 149 143 { 150 // we have tex coord array so now we can compute the final tex coord at the point of intersection. 151 osg::Vec2 tc1 = (*texcoords_Vec2Array)[i1]; 152 osg::Vec2 tc2 = (*texcoords_Vec2Array)[i2]; 153 osg::Vec2 tc3 = (*texcoords_Vec2Array)[i3]; 154 osg::Vec2 tc = tc1*r1 + tc2*r2 + tc3*r3; 155 156 osg::notify(osg::NOTICE)<<"We hit tex coords "<<tc<<std::endl; 157 144 unsigned int i1 = indices[0]; 145 unsigned int i2 = indices[1]; 146 unsigned int i3 = indices[2]; 147 148 float r1 = ratios[0]; 149 float r2 = ratios[1]; 150 float r3 = ratios[2]; 151 152 osg::Array* texcoords = (geometry->getNumTexCoordArrays()>0) ? geometry->getTexCoordArray(0) : 0; 153 osg::Vec2Array* texcoords_Vec2Array = dynamic_cast<osg::Vec2Array*>(texcoords); 154 if (texcoords_Vec2Array) 155 { 156 // we have tex coord array so now we can compute the final tex coord at the point of intersection. 157 osg::Vec2 tc1 = (*texcoords_Vec2Array)[i1]; 158 osg::Vec2 tc2 = (*texcoords_Vec2Array)[i2]; 159 osg::Vec2 tc3 = (*texcoords_Vec2Array)[i3]; 160 osg::Vec2 tc = tc1*r1 + tc2*r2 + tc3*r3; 161 162 osg::notify(osg::NOTICE)<<"We hit tex coords "<<tc<<std::endl; 163 164 } 158 165 } 166 else 167 { 168 osg::notify(osg::NOTICE)<<"Intersection has insufficient indices to work with"; 169 } 170 159 171 } 160 else161 {162 osg::notify(osg::NOTICE)<<"Intersection has insufficient indices to work with";163 }164 165 172 } 166 }167 else168 {169 osg::notify(osg::NOTICE)<<"No intersection"<<std::endl;173 else 174 { 175 osg::notify(osg::NOTICE)<<"No intersection"<<std::endl; 176 } 170 177 } 171 178 break; … … 277 284 } 278 285 286 osg::Geometry* createDomeDistortionMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector, 287 osg::ArgumentParser& arguments) 288 { 289 double sphere_radius = 1.0; 290 if (arguments.read("--radius", sphere_radius)) {} 291 292 double collar_radius = 0.45; 293 if (arguments.read("--collar", collar_radius)) {} 294 295 osg::Vec3d center(0.0,0.0,0.0); 296 osg::Vec3d eye(0.0,0.0,0.0); 297 298 double distance = sqrt(sphere_radius*sphere_radius - collar_radius*collar_radius); 299 if (arguments.read("--distance", distance)) {} 300 301 bool centerProjection = false; 302 303 osg::Vec3d projector = eye - osg::Vec3d(0.0,0.0, distance); 304 305 306 osg::notify(osg::NOTICE)<<"Projector position = "<<projector<<std::endl; 307 osg::notify(osg::NOTICE)<<"distance = "<<distance<<std::endl; 308 309 310 // create the quad to visualize. 311 osg::Geometry* geometry = new osg::Geometry(); 312 313 geometry->setSupportsDisplayList(false); 314 315 osg::Vec3 xAxis(widthVector); 316 float width = widthVector.length(); 317 xAxis /= width; 318 319 osg::Vec3 yAxis(heightVector); 320 float height = heightVector.length(); 321 yAxis /= height; 322 323 int noSteps = 50; 324 325 osg::Vec3Array* vertices = new osg::Vec3Array; 326 osg::Vec2Array* texcoords = new osg::Vec2Array; 327 osg::Vec4Array* colors = new osg::Vec4Array; 328 329 osg::Vec3 bottom = origin; 330 osg::Vec3 dx = xAxis*(width/((float)(noSteps-1))); 331 osg::Vec3 dy = yAxis*(height/((float)(noSteps-1))); 332 333 osg::Vec3d screenCenter = origin + widthVector*0.5f + heightVector*0.5f; 334 float screenRadius = heightVector.length() * 0.5f; 335 336 osg::Vec3 cursor = bottom; 337 int i,j; 338 339 for(i=0;i<noSteps;++i) 340 { 341 osg::Vec3 cursor = bottom+dy*(float)i; 342 for(j=0;j<noSteps;++j) 343 { 344 osg::Vec2 delta(cursor.x() - screenCenter.x(), cursor.y() - screenCenter.y()); 345 double theta = atan2(delta.x(), delta.y()); 346 if (theta<0.0) theta += 2*osg::PI; 347 double phi = osg::PI_2 * delta.length() / screenRadius; 348 if (phi > osg::PI_2) phi = osg::PI_2; 349 350 double f = distance * sin(phi); 351 double e = distance * cos(phi) + sqrt( sphere_radius*sphere_radius - f*f); 352 double l = e * cos(phi); 353 double h = e * sin(phi); 354 double gamma = atan2(h, l-distance); 355 356 osg::Vec2 texcoord(theta/(2.0*osg::PI), 1.0-gamma/osg::PI); 357 358 osg::notify(osg::NOTICE)<<"cursor = "<<cursor<< " theta = "<<theta<< "phi="<<phi<<" gamma = "<<gamma<<" texcoord="<<texcoord<<std::endl; 359 360 vertices->push_back(cursor); 361 colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); 362 texcoords->push_back(texcoord); 363 364 cursor += dx; 365 } 366 // osg::notify(osg::NOTICE)<<std::endl; 367 } 368 369 // pass the created vertex array to the points geometry object. 370 geometry->setVertexArray(vertices); 371 372 geometry->setColorArray(colors); 373 geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); 374 375 geometry->setTexCoordArray(0,texcoords); 376 377 for(i=0;i<noSteps-1;++i) 378 { 379 osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::QUAD_STRIP); 380 for(j=0;j<noSteps;++j) 381 { 382 elements->push_back(j+(i+1)*noSteps); 383 elements->push_back(j+(i)*noSteps); 384 } 385 geometry->addPrimitiveSet(elements); 386 } 387 388 return geometry; 389 } 390 391 392 void setDomeCorrection(osgViewer::Viewer& viewer, osg::ArgumentParser& arguments) 393 { 394 // enforce single threading right now to avoid double buffering of RTT texture 395 viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); 396 397 osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); 398 if (!wsi) 399 { 400 osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl; 401 return; 402 } 403 404 unsigned int width, height; 405 wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height); 406 407 while (arguments.read("--width",width)) {} 408 while (arguments.read("--height",height)) {} 409 410 osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; 411 traits->x = 0; 412 traits->y = 0; 413 traits->width = width; 414 traits->height = height; 415 traits->windowDecoration = false; 416 traits->doubleBuffer = true; 417 traits->sharedContext = 0; 418 419 420 421 osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get()); 422 if (!gc) 423 { 424 osg::notify(osg::NOTICE)<<"GraphicsWindow has not been created successfully."<<std::endl; 425 return; 426 } 427 428 osg::ref_ptr<osg::Drawable> distortionCorrectionMash = createDomeDistortionMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), arguments); 429 430 osg::Texture* texture = 0; 431 for(int i=1;i<arguments.argc() && !texture;++i) 432 { 433 if (arguments.isString(i)) 434 { 435 osg::Image* image = osgDB::readImageFile(arguments[i]); 436 osg::ImageStream* imagestream = dynamic_cast<osg::ImageStream*>(image); 437 if (imagestream) imagestream->play(); 438 439 if (image) 440 { 441 #if 0 442 texture = new osg::TextureRectangle(image); 443 #else 444 texture = new osg::Texture2D(image); 445 #endif 446 } 447 } 448 } 449 450 if (!texture) 451 { 452 return; 453 } 454 455 // distortion correction set up. 456 { 457 osg::Geode* geode = new osg::Geode(); 458 geode->addDrawable(distortionCorrectionMash.get()); 459 460 // new we need to add the texture to the mesh, we do so by creating a 461 // StateSet to contain the Texture StateAttribute. 462 osg::StateSet* stateset = geode->getOrCreateStateSet(); 463 stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); 464 stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); 465 #if 0 466 osg::TexMat* texmat = new osg::TexMat; 467 texmat->setScaleByTextureRectangleSize(true); 468 stateset->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON); 469 #endif 470 osg::ref_ptr<osg::Camera> camera = new osg::Camera; 471 camera->setGraphicsContext(gc.get()); 472 camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); 473 camera->setClearColor( osg::Vec4(0.1,0.1,1.0,1.0) ); 474 camera->setViewport(new osg::Viewport(0, 0, width, height)); 475 GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; 476 camera->setDrawBuffer(buffer); 477 camera->setReadBuffer(buffer); 478 camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); 479 camera->setAllowEventFocus(false); 480 //camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE); 481 //camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); 482 483 camera->setProjectionMatrixAsOrtho2D(0,width,0,height); 484 camera->setViewMatrix(osg::Matrix::identity()); 485 486 // add subgraph to render 487 camera->addChild(geode); 488 489 camera->setName("DistortionCorrectionCamera"); 490 491 viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd(), false); 492 } 493 494 viewer.getCamera()->setNearFarRatio(0.0001f); 495 } 496 279 497 int main(int argc, char** argv) 280 498 { … … 289 507 arguments.getApplicationUsage()->addCommandLineOption("--texture2D","Use Texture2D rather than TextureRectangle."); 290 508 arguments.getApplicationUsage()->addCommandLineOption("--shader","Use shaders to post process the video."); 509 arguments.getApplicationUsage()->addCommandLineOption("--dome","Use full dome distortion correction."); 291 510 292 511 bool useTextureRectangle = true; … … 351 570 352 571 353 for(int i=1;i<arguments.argc();++i) 354 { 355 if (arguments.isString(i)) 356 { 357 osg::Image* image = osgDB::readImageFile(arguments[i]); 358 osg::ImageStream* imagestream = dynamic_cast<osg::ImageStream*>(image); 359 if (imagestream) imagestream->play(); 360 361 if (image) 362 { 363 geode->addDrawable(myCreateTexturedQuadGeometry(pos,image->s(),image->t(),image, useTextureRectangle)); 364 365 pos.z() += image->t()*1.5f; 366 } 367 else 368 { 369 std::cout<<"Unable to read file "<<arguments[i]<<std::endl; 370 } 371 } 372 } 373 374 if (geode->getNumDrawables()==0) 375 { 376 // nothing loaded. 377 arguments.getApplicationUsage()->write(std::cout); 378 return 1; 379 } 572 if (arguments.read("--dome") || arguments.read("--puffer") ) 573 { 574 setDomeCorrection(viewer, arguments); 575 } 576 else 577 { 578 for(int i=1;i<arguments.argc();++i) 579 { 580 if (arguments.isString(i)) 581 { 582 osg::Image* image = osgDB::readImageFile(arguments[i]); 583 osg::ImageStream* imagestream = dynamic_cast<osg::ImageStream*>(image); 584 if (imagestream) imagestream->play(); 585 586 if (image) 587 { 588 geode->addDrawable(myCreateTexturedQuadGeometry(pos,image->s(),image->t(),image, useTextureRectangle)); 589 590 pos.z() += image->t()*1.5f; 591 } 592 else 593 { 594 std::cout<<"Unable to read file "<<arguments[i]<<std::endl; 595 } 596 } 597 } 598 if (!viewer.getSceneData()) 599 { 600 arguments.getApplicationUsage()->write(std::cout); 601 return 1; 602 } 603 } 604 380 605 381 606 // pass the model to the MovieEventHandler so it can pick out ImageStream's to manipulate. 382 607 MovieEventHandler* meh = new MovieEventHandler(); 383 608 geode->setEventCallback(meh); 384 meh->set( geode.get());609 meh->set(viewer.getSceneData()); 385 610 386 611 // report any errors if they have occured when parsing the program aguments. … … 397 622 } 398 623 624 399 625 // set the scene to render 400 626 viewer.setSceneData(geode.get());
