00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041
00042 #include <sstream>
00043 #include <fstream>
00044
00045 #include "OSGConfig.h"
00046
00047 #include "OSGAction.h"
00048 #include "OSGCamera.h"
00049 #include "OSGRenderAction.h"
00050 #include "OSGSceneFileHandler.h"
00051 #include "OSGVolumeDraw.h"
00052
00053 #include "OSGFishEyeProjector.h"
00054 #include "OSGFishEyeProjectorData.h"
00055
00056 #include "OSGFrameBufferObject.h"
00057 #include "OSGFrameBufferAttachment.h"
00058 #include "OSGRenderBuffer.h"
00059 #include "OSGTextureBuffer.h"
00060
00061 #include "OSGChunkMaterial.h"
00062 #include "OSGMaterialChunk.h"
00063 #include "OSGTextureObjChunk.h"
00064 #include "OSGDrawEnv.h"
00065 #include "OSGImageFunctions.h"
00066 #include "OSGStateOverride.h"
00067 #include "OSGTextureEnvChunk.h"
00068 #include "OSGSimpleSHLFunctions.h"
00069 #include "OSGPerspectiveCamera.h"
00070
00071 #include "OSGTypedGeoVectorProperty.h"
00072 #include "OSGTypedGeoIntegralProperty.h"
00073
00074
00075 #include "OSGMatrixUtility.h"
00076
00077 #include "OSGGLU.h"
00078
00079
00080 OSG_USING_NAMESPACE
00081
00089 UInt32 FishEyeProjector::_uiFramebuffer_object_extension =
00090 Window::invalidExtensionID;
00091
00092 UInt32 FishEyeProjector::_uiFuncDrawBuffers =
00093 Window::invalidFunctionID;
00094
00095 typedef void (OSG_APIENTRY *GLDrawBuffersEXTProcT)(
00096 GLsizei n,
00097 const GLenum *buffers);
00098
00099
00100
00101
00102 void osgMedian(Vec3d &vRes, const Vec3d &v1, const Vec3d &v2)
00103 {
00104 vRes[0] = (v1[0] + v2[0]) * 0.5;
00105 vRes[1] = (v1[1] + v2[1]) * 0.5;
00106 vRes[2] = (v1[2] + v2[2]) * 0.5;
00107 }
00108
00109 void osgMedian(Vec2d &vRes, const Vec2d &v1, const Vec2d &v2)
00110 {
00111 vRes[0] = (v1[0] + v2[0]) * 0.5;
00112 vRes[1] = (v1[1] + v2[1]) * 0.5;
00113 }
00114
00115
00116 Vec3d osgRotateX(Vec3d p,double theta)
00117 {
00118 Vec3d q;
00119
00120 q[0] = p[0];
00121 q[1] = p[1] * cos(theta) + p[2] * sin(theta);
00122 q[2] = -p[1] * sin(theta) + p[2] * cos(theta);
00123
00124 return q;
00125 }
00126
00127 int FishEyeProjector::MirrorPosition(Vec3d c,
00128 Real64 r,
00129 Vec3d p1,
00130 Vec3d p2,
00131 Vec3d &p0)
00132 {
00133 int i;
00134 int nres = 1000;
00135
00136 double theta,thetamax,thetamin,phi;
00137 double ctheta,stheta;
00138 double l1,l2,val,valmin;
00139 Vec3d p;
00140
00141 p0.setValues(0.0, 0.0, 0.0);
00142
00143 if(p1[2] < 0)
00144 return 1;
00145
00146
00147 p1[0] -= c[0];
00148 p2[0] -= c[0];
00149
00150
00151 phi = atan2(p1[1], p1[2]);
00152
00153 p1 = osgRotateX(p1, -phi);
00154
00155 if(fabs(p1[1]) > 0.00001)
00156 return 2;
00157
00158
00159
00160 if(fabs(p2[0]) <= r)
00161 return 3;
00162
00163 thetamax = acos(r / fabs(p2[0]));
00164
00165
00166 thetamin = thetamax;
00167 valmin = 1e32;
00168
00169 for(i = 0; i <= nres; i++)
00170 {
00171 theta = i * PiHalf / double(nres);
00172
00173 if(theta >= thetamax)
00174 break;
00175
00176 ctheta = cos(theta);
00177 stheta = sin(theta);
00178
00179 l1 = ((p2[0] + r * ctheta) *(p2[0] + r * ctheta) +
00180 (r * stheta)*(r * stheta));
00181
00182 l2 = ((p1[0] + r * ctheta) *(p1[0] + r * ctheta) +
00183 (p1[2] - r * stheta) *(p1[2] - r * stheta));
00184
00185 val = sqrt(l1) + sqrt(l2);
00186
00187 if (val < valmin)
00188 {
00189 valmin = val;
00190 thetamin = theta;
00191 }
00192 }
00193
00194 if(thetamin < 0)
00195 return 4;
00196
00197
00198 p[0] = -r * cos(thetamin);
00199 p[1] = 0;
00200 p[2] = r * sin(thetamin);
00201
00202
00203 p = osgRotateX(p, phi);
00204
00205
00206 p[0] += c[0];
00207
00208 p0 = p;
00209
00210 return 0;
00211 }
00212
00213 void FishEyeProjector::EstimateWarp(Real64 u, Real64 v,
00214 Real64 &x, Real64 &z,
00215 Real64 &br)
00216 {
00217 #if 0
00218 Int32 ix,iy;
00219 Real64 tu,tv;
00220 #endif
00221 Int32 n;
00222 Real64 mu,longitude,latitude;
00223 Vec3d p1,p,p0;
00224
00225 Real64 domeradius = this->getDomeRadius ();
00226 Real64 mirrorradius = this->getMirrorRadius();
00227 Vec3d mirrorpos = this->getMirrorPos ();
00228 Vec3d projectorpos = this->getProjectorPos();
00229 Real64 aspectratio = this->getAspectRatio ();
00230 Real64 throwdist = this->getThrowDist ();
00231
00232 Vec3d frustum[4];
00233
00234 if(this->getMode() == FishEyeProjector::MirrorDome)
00235 {
00236
00237 for(Int32 i = 0; i < 4; i++)
00238 frustum[i][0] = projectorpos[0] + 1;
00239
00240 frustum[0][1] = -0.5 / throwdist;
00241 frustum[1][1] = -0.5 / throwdist;
00242 frustum[2][1] = 0.5 / throwdist;
00243 frustum[3][1] = 0.5 / throwdist;
00244 frustum[0][2] = 0;
00245 frustum[1][2] = 1.0 / (throwdist * aspectratio);
00246 frustum[2][2] = 1.0 / (throwdist * aspectratio);
00247 frustum[3][2] = 0;
00248
00249
00250
00251 longitude = atan2(v, u);
00252 latitude = PiHalf * sqrt(u * u + v * v);
00253
00254 if (latitude > PiHalf)
00255 latitude = PiHalf;
00256
00257
00258 p1[0] = domeradius * sin(latitude) * sin(longitude);
00259 p1[1] = domeradius * sin(latitude) * cos(longitude);
00260 p1[2] = domeradius * cos(latitude);
00261
00262
00263 if ((n = MirrorPosition(mirrorpos,
00264 mirrorradius,
00265 p1,
00266 projectorpos,
00267 p0 )) != 0)
00268 {
00269 fprintf(stderr,"Error %d, at (%g,%g) = (%g,%g)\n",
00270 n,u,v,latitude,longitude);
00271 }
00272
00273
00274 mu = (frustum[0][0] - projectorpos[0]) / (p0[0] - projectorpos[0]);
00275
00276 p[0] = frustum[0][0];
00277 p[1] = projectorpos[1] + mu * (p0[1] - projectorpos[1]);
00278 p[2] = projectorpos[2] + mu * (p0[2] - projectorpos[2]);
00279
00280
00281 br = 1;
00282
00283 if (p1[0] > 0)
00284 br = 1 - p1[0] / domeradius;
00285
00286 if (br < 0)
00287 br = 0;
00288
00289 if (p1[0] >= mirrorpos[0])
00290 br = -1;
00291
00292 p[1] *= throwdist;
00293 p[1] *= 2;
00294 p[1] *= aspectratio;
00295
00296 p[2] *= throwdist;
00297 p[2] *= aspectratio;
00298 p[2] *= 2;
00299 p[2] -= 1;
00300
00301 x = p[1];
00302 z = p[2];
00303
00304 }
00305 else
00306 {
00307
00308 }
00309 }
00310
00311
00312
00313
00314 void FishEyeProjector::changed(ConstFieldMaskArg whichField,
00315 UInt32 origin,
00316 BitVector details)
00317 {
00318 if(0x0000 != (whichField & (ModeFieldMask | MeshRefinementLevelFieldMask)))
00319 {
00320 if(_sfMode.getValue() < 0x0001)
00321 _sfMode.setValue(0x0001);
00322
00323 if(_sfMode.getValue() > 0x0006)
00324 _sfMode.setValue(0x0006);
00325
00326 fprintf(stderr, "Rebuild for %d %d\n",
00327 _sfMode.getValue(),
00328 _sfMeshRefinementLevel.getValue());
00329
00330 rebuildGeometries();
00331 }
00332
00333 if(0x0000 != (whichField & ShowDomeIntensityFieldMask))
00334 {
00335 for(UInt32 i = 0; i < 4; ++i)
00336 {
00337 Geometry *pGeo = _mfGeometries[i];
00338
00339 if(pGeo == NULL)
00340 continue;
00341
00342 GeoVectorProperty *pColProp =
00343 pGeo->getProperty(Geometry::ColorsIndex);
00344
00345 if(pColProp != NULL)
00346 {
00347 pColProp->setIgnore(!this->getShowDomeIntensity());
00348 }
00349 }
00350 }
00351
00352 Inherited::changed(whichField, origin, details);
00353 }
00354
00355
00356
00357
00358 void FishEyeProjector::dump( UInt32 OSG_CHECK_ARG(uiIndent),
00359 const BitVector OSG_CHECK_ARG(bvFlags )) const
00360 {
00361 SLOG << "Dump VisitSubTree NI" << std::endl;
00362 }
00363
00364
00365
00366
00367 FishEyeProjector::FishEyeProjector(void) :
00368 Inherited ( )
00369 {
00370 }
00371
00372 FishEyeProjector::FishEyeProjector(const FishEyeProjector &source) :
00373
00374 Inherited (source)
00375 {
00376 }
00377
00378
00379
00380
00381 FishEyeProjector::~FishEyeProjector(void)
00382 {
00383 }
00384
00385
00386
00387
00394 ActionBase::ResultE FishEyeProjector::renderEnter(Action *action)
00395 {
00396 static Matrix transforms[] =
00397 {
00398
00399 Matrix( 1, 0, 0, 0,
00400 0, 1, 0, 0,
00401 0, 0, 1, 0,
00402 0, 0, 0, 1),
00403
00404
00405 Matrix( 0, 0, -1, 0,
00406 0, 1, 0, 0,
00407 1, 0, 0, 0,
00408 0, 0, 0, 1),
00409
00410
00411 Matrix( 1, 0, 0, 0,
00412 0, 0, 1, 0,
00413 0, -1, 0, 0,
00414 0, 0, 0, 1),
00415
00416
00417 Matrix( 1, 0, 0, 0,
00418 0, 0, -1, 0,
00419 0, 1, 0, 0,
00420 0, 0, 0, 1),
00421 };
00422
00423 static Matrix deltaTr[] =
00424 {
00425 Matrix ( 0.70710678f, 0, 0.70710678f, 0,
00426 0, 1, 0, 0,
00427 -0.70710678f, 0, 0.70710678f, 0,
00428 0, 0, 0, 1),
00429
00430 Matrix ( 0.70710678f, 0, 0.70710678f, 0,
00431 0, 1, 0, 0,
00432 -0.70710678f, 0, 0.70710678f, 0,
00433 0, 0, 0, 1),
00434
00435 Matrix (-0.70710678f, 0, -0.70710678f, 0,
00436 0, 1, 0, 0,
00437 0.70710678f, 0, -0.70710678f, 0,
00438 0, 0, 0, 1),
00439
00440 Matrix ( 0.70710678f, 0, -0.70710678f, 0,
00441 0, 1, 0, 0,
00442 0.70710678f, 0, 0.70710678f, 0,
00443 0, 0, 0, 1)
00444 };
00445
00446 RenderAction *a = dynamic_cast<RenderAction *>(action);
00447
00448 a->disableDefaultPartition();
00449
00450
00451 Background *pBack = a->getBackground();
00452
00453 Viewport *pPort = a->getViewport();
00454
00455
00456 FishEyeProjectorData *pData =
00457 a->getData<FishEyeProjectorData *>(_iDataSlotId);
00458
00459
00460 if(pData == NULL)
00461 {
00462 pData = this->initData(a);
00463 }
00464
00465 a->beginPartitionGroup();
00466 {
00467
00468 FrameBufferObject *pTarget = pData->getRenderTarget();
00469
00470 Matrix mGlobalCam;
00471
00472 if(pPort != NULL)
00473 {
00474 Camera *pGlobalCam = pPort->getCamera();
00475
00476
00477 pGlobalCam->getViewing(mGlobalCam,
00478 pPort->getPixelWidth (),
00479 pPort->getPixelHeight());
00480 }
00481
00482
00483 Camera *pCam = pData->getCamera();
00484
00485 for(UInt32 i = 0; i < 4; ++i)
00486 {
00487 a->pushPartition();
00488 {
00489 RenderPartition *pPart = a->getActivePartition();
00490
00491 pPart->setVolumeDrawing(false);
00492
00493 pPart->setRenderTarget(pTarget );
00494 pPart->setWindow (a->getWindow());
00495
00496 pPart->calcViewportDimension(0,
00497 0,
00498 1,
00499 1,
00500 this->getResolution(),
00501 this->getResolution());
00502
00503 Matrix m, t;
00504
00505
00506 pCam->getProjection (m,
00507 pPart->getViewportWidth (),
00508 pPart->getViewportHeight());
00509
00510 pCam->getProjectionTranslation(t,
00511 pPart->getViewportWidth (),
00512 pPart->getViewportHeight());
00513
00514 pPart->setupProjection(m, t);
00515
00516 m = transforms[i];
00517
00518 m.multLeft(deltaTr[i]);
00519
00520 m.invert();
00521
00522 m.mult(mGlobalCam);
00523
00524 pPart->setupViewing(m);
00525
00526 pPart->setNear (pCam->getNear());
00527 pPart->setFar (pCam->getFar ());
00528
00529 pPart->calcFrustum();
00530
00531 pPart->setBackground(pBack);
00532
00533
00534 a->useNodeList(false);
00535
00536 this->recurseFromThis(a);
00537
00538 pPart->setDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + i);
00539
00540 #ifdef OSG_DEBUGX
00541 std::string szMessage("fishX\n");
00542 pPart->setDebugString(szMessage );
00543 #endif
00544 }
00545 a->popPartition();
00546 }
00547
00548
00549
00550 a->pushPartition((RenderPartition::CopyWindow |
00551 RenderPartition::CopyViewportSize),
00552 RenderPartition::SimpleCallback);
00553 {
00554 RenderPartition *pPart = a->getActivePartition();
00555
00556 #ifdef OSG_DEBUGX
00557 std::string szMessage("PostProcessPartition\n");
00558 pPart->setDebugString(szMessage );
00559 #endif
00560
00561 Matrix m, t;
00562
00563 m.setIdentity();
00564 t.setIdentity();
00565
00566 MatrixOrthogonal( m,
00567 0.f, 1.f,
00568 0.f, 1.f,
00569 -1.f, 1.f);
00570
00571 pPart->setupProjection(m, t);
00572
00573 RenderPartition::SimpleDrawCallback f;
00574
00575 f = boost::bind(&FishEyeProjector::postProcess, this, _1);
00576
00577 pPart->dropFunctor(f);
00578 }
00579 a->popPartition();
00580 }
00581 a->endPartitionGroup();
00582
00583 return Action::Skip;
00584 }
00585
00586 ActionBase::ResultE FishEyeProjector::renderLeave(Action *action)
00587 {
00588 return Action::Skip;
00589 }
00590
00591
00592
00593
00594 void FishEyeProjector::initMethod(InitPhase ePhase)
00595 {
00596 Inherited::initMethod(ePhase);
00597
00598 if(ePhase == TypeObject::SystemPost)
00599 {
00600 RenderAction::registerEnterDefault(
00601 FishEyeProjector::getClassType(),
00602 reinterpret_cast<Action::Callback>(&FishEyeProjector::renderEnter));
00603
00604 RenderAction::registerLeaveDefault(
00605 FishEyeProjector::getClassType(),
00606 reinterpret_cast<Action::Callback>(&FishEyeProjector::renderLeave));
00607
00608 _uiFramebuffer_object_extension =
00609 Window::registerExtension("GL_EXT_framebuffer_object");
00610
00611 _uiFuncDrawBuffers =
00612 Window::registerFunction (
00613 OSG_DLSYM_UNDERSCORE"glDrawBuffersARB",
00614 _uiFramebuffer_object_extension);
00615 }
00616 }
00617
00618 void FishEyeProjector::warpData(Geometry *pGeo)
00619 {
00620 GeoVec3dPropertyUnrecPtr pPosProp =
00621 dynamic_cast<GeoVec3dProperty *>(
00622 pGeo->getProperty(Geometry::PositionsIndex));
00623
00624 GeoVec2dPropertyUnrecPtr pUVProp =
00625 dynamic_cast<GeoVec2dProperty *>(
00626 pGeo->getProperty(Geometry::TexCoordsIndex));
00627
00628 GeoColor3fPropertyUnrecPtr pColProp =
00629 dynamic_cast<GeoColor3fProperty *>(
00630 pGeo->getProperty(Geometry::ColorsIndex));
00631
00632 if(pColProp == NULL)
00633 {
00634 pColProp = GeoColor3fProperty::create();
00635
00636 GeoUInt32Property *pIdx =
00637 dynamic_cast<GeoUInt32Property *>(
00638 pGeo->getIndex(Geometry::TexCoordsIndex));
00639
00640
00641 pGeo->setProperty(pColProp, Geometry::ColorsIndex);
00642 pGeo->setIndex (pIdx, Geometry::ColorsIndex);
00643 }
00644
00645 if(this->getShowDomeIntensity() == false)
00646 pColProp->setIgnore(true);
00647
00648 MFVec3d &oPos = *(pPosProp->editFieldPtr());
00649 MFVec2d &oUV = *(pUVProp ->editFieldPtr());
00650 MFColor3f &oCol = *(pColProp->editFieldPtr());
00651
00652 oCol.resize(oPos.size());
00653
00654 Real64 x[3], z[3], b[3];
00655
00656 UInt32 uiNumTris = oPos.size() / 3;
00657
00658 UInt32 uiCurrIdx = 0;
00659
00660 for(UInt32 i = 0; i < uiNumTris; ++i)
00661 {
00662
00663 EstimateWarp(oPos[i * 3 + 0][0],
00664 oPos[i * 3 + 0][2], (x[0]), (z[0]), (b[0]));
00665
00666 EstimateWarp(oPos[i * 3 + 1][0],
00667 oPos[i * 3 + 1][2], (x[1]), (z[1]), (b[1]));
00668
00669 EstimateWarp(oPos[i * 3 + 2][0],
00670 oPos[i * 3 + 2][2], (x[2]), (z[2]), (b[2]));
00671
00672 if(b[0] < 0 || b[1] < 0 || b[2] < 0)
00673 {
00674 continue;
00675 }
00676
00677 for(UInt32 j = 0; j < 3; ++j)
00678 {
00679 oPos[uiCurrIdx][0] = x[j];
00680 oPos[uiCurrIdx][1] = 0;
00681 oPos[uiCurrIdx][2] = z[j];
00682
00683 oUV[uiCurrIdx] = oUV[i * 3 + j];
00684
00685 oCol[uiCurrIdx].setValuesRGB(b[j], b[j], b[j]);
00686
00687 ++uiCurrIdx;
00688 }
00689 }
00690
00691 oPos.resize(uiCurrIdx);
00692 oUV .resize(uiCurrIdx);
00693 oCol.resize(uiCurrIdx);
00694 }
00695
00696
00697 void FishEyeProjector::flattenVertex(Vec3d &oVertex,
00698 Real64 aperture)
00699 {
00700 double phi,r;
00701
00702 r = atan2(osgSqrt(oVertex[0] * oVertex[0] + oVertex[2] * oVertex[2]),
00703 oVertex[1]) / (osgDegree2Rad(aperture) / 2);
00704
00705 phi = atan2(oVertex[2], oVertex[0]);
00706
00707 oVertex[0] = r * osgCos(phi);
00708 oVertex[1] = 0;
00709 oVertex[2] = r * osgSin(phi);
00710 }
00711
00712 void FishEyeProjector::splitFaces(MFVec2d &vUV,
00713 MFVec3d &vP,
00714 UInt32 &uiSize)
00715 {
00716 UInt32 oldSize = uiSize;
00717 UInt32 n2 = uiSize;
00718
00719 for(UInt32 i = 0; i < oldSize; i++)
00720 {
00721 osgMedian(vP[n2 * 3 + 0], vP[i * 3 + 0], vP[i * 3 + 1]);
00722
00723 vP[n2 * 3 + 1] = vP[i * 3 + 1];
00724
00725 osgMedian(vP[n2 * 3 + 2], vP[i * 3 + 1], vP[i * 3 + 2]);
00726
00727
00728 osgMedian(vUV[n2 * 3 + 0], vUV[i * 3 + 0], vUV[i * 3 + 1]);
00729
00730 vUV[n2 * 3 + 1] = vUV[i * 3 + 1];
00731
00732 osgMedian(vUV[n2 * 3 + 2], vUV[i * 3 + 1], vUV[i * 3 + 2]);
00733
00734
00735
00736 osgMedian(vP[(n2+1) * 3 + 0], vP[i * 3 + 1],vP[i * 3 + 2]);
00737
00738 vP[(n2+1) * 3 + 1] = vP[i * 3 + 2];
00739
00740 osgMedian(vP[(n2+1) * 3 + 2], vP[i * 3 + 2],vP[i * 3 + 0]);
00741
00742
00743 osgMedian(vUV[(n2+1) * 3 + 0], vUV[i * 3 + 1], vUV[i * 3 + 2]);
00744
00745 vUV[(n2+1) * 3 + 1] = vUV[i * 3 + 2];
00746
00747 osgMedian(vUV[(n2+1) * 3 + 2], vUV[i * 3 + 2], vUV[i * 3 + 0]);
00748
00749
00750
00751 osgMedian(vP[(n2+2) * 3 + 0], vP[i * 3 + 0], vP[i * 3 + 1]);
00752 osgMedian(vP[(n2+2) * 3 + 1], vP[i * 3 + 1], vP[i * 3 + 2]);
00753 osgMedian(vP[(n2+2) * 3 + 2], vP[i * 3 + 2], vP[i * 3 + 0]);
00754
00755 osgMedian(vUV[(n2+2) * 3 + 0], vUV[i * 3 + 0], vUV[i * 3 + 1]);
00756 osgMedian(vUV[(n2+2) * 3 + 1], vUV[i * 3 + 1], vUV[i * 3 + 2]);
00757 osgMedian(vUV[(n2+2) * 3 + 2], vUV[i * 3 + 2], vUV[i * 3 + 0]);
00758
00759
00760
00761 osgMedian(vP[i * 3 + 1], vP[i * 3 + 0], vP[i * 3 + 1]);
00762 osgMedian(vP[i * 3 + 2], vP[i * 3 + 0], vP[i * 3 + 2]);
00763
00764 osgMedian(vUV[i * 3 + 1], vUV[i * 3 + 0], vUV[i * 3 + 1]);
00765 osgMedian(vUV[i * 3 + 2], vUV[i * 3 + 0], vUV[i * 3 + 2]);
00766
00767 n2 += 3;
00768 }
00769
00770 uiSize = n2;
00771 }
00772
00773
00774 void FishEyeProjector::initTopMesh(Geometry *pGeo)
00775 {
00776 GeoVec2dPropertyUnrecPtr pUVProp =
00777 dynamic_cast<GeoVec2dProperty *>(
00778 pGeo->getProperty(Geometry::TexCoordsIndex));
00779
00780 GeoVec3dPropertyUnrecPtr pPosProp =
00781 dynamic_cast<GeoVec3dProperty *>(
00782 pGeo->getProperty(Geometry::PositionsIndex));
00783
00784 OSG_ASSERT(pUVProp != NULL);
00785 OSG_ASSERT(pPosProp != NULL);
00786
00787 MFVec2d &oUV = *(pUVProp ->editFieldPtr());
00788 MFVec3d &oPos = *(pPosProp->editFieldPtr());
00789
00790 Real32 rSq2H = osgSqrt(2.0) / 2.0;
00791
00792 oUV .resize(3);
00793 oPos.resize(3);
00794
00795 oPos[0].setValues(-rSq2H, 0.0, 0.5);
00796 oPos[1].setValues( 0.0, rSq2H, 0.5);
00797 oPos[2].setValues( rSq2H, 0.0, 0.5);
00798
00799
00800 oUV[0].setValues(0.0, 1.0);
00801 oUV[1].setValues(0.0, 0.0);
00802 oUV[2].setValues(1.0, 0.0);
00803 }
00804
00805 void FishEyeProjector::initBottomMesh(Geometry *pGeo)
00806 {
00807 GeoVec2dPropertyUnrecPtr pUVProp =
00808 dynamic_cast<GeoVec2dProperty *>(
00809 pGeo->getProperty(Geometry::TexCoordsIndex));
00810
00811 GeoVec3dPropertyUnrecPtr pPosProp =
00812 dynamic_cast<GeoVec3dProperty *>(
00813 pGeo->getProperty(Geometry::PositionsIndex));
00814
00815 OSG_ASSERT(pUVProp != NULL);
00816 OSG_ASSERT(pPosProp != NULL);
00817
00818 MFVec2d &oUV = *(pUVProp ->editFieldPtr());
00819 MFVec3d &oPos = *(pPosProp->editFieldPtr());
00820
00821 Real32 rSq2H = osgSqrt(2.0) / 2.0;
00822
00823 oUV .resize(3);
00824 oPos.resize(3);
00825
00826 oPos[0].setValues(-rSq2H, 0.0, -0.5);
00827 oPos[1].setValues( rSq2H, 0.0, -0.5);
00828 oPos[2].setValues( 0.0, rSq2H, -0.5);
00829
00830 oUV[0].setValues(1.0, 0.0);
00831 oUV[1].setValues(0.0, 1.0);
00832 oUV[2].setValues(0.0, 0.0);
00833 }
00834
00835 void FishEyeProjector::initLeftMesh(Geometry *pGeo)
00836 {
00837 GeoVec2dPropertyUnrecPtr pUVProp =
00838 dynamic_cast<GeoVec2dProperty *>(
00839 pGeo->getProperty(Geometry::TexCoordsIndex));
00840
00841 GeoVec3dPropertyUnrecPtr pPosProp =
00842 dynamic_cast<GeoVec3dProperty *>(
00843 pGeo->getProperty(Geometry::PositionsIndex));
00844
00845 OSG_ASSERT(pUVProp != NULL);
00846 OSG_ASSERT(pPosProp != NULL);
00847
00848 MFVec2d &oUV = *(pUVProp ->editFieldPtr());
00849 MFVec3d &oPos = *(pPosProp->editFieldPtr());
00850
00851 Real32 rSq2H = osgSqrt(2.0) / 2.0;
00852
00853 oUV .resize(6);
00854 oPos.resize(6);
00855
00856 oPos[0].setValues(-rSq2H, 0.0, -0.5);
00857 oPos[1].setValues( 0.0, rSq2H, -0.5);
00858 oPos[2].setValues(-rSq2H, 0.0, 0.5);
00859
00860 oUV[0].setValues(0.0, 0.0);
00861 oUV[1].setValues(1.0, 0.0);
00862 oUV[2].setValues(0.0, 1.0);
00863
00864
00865 oPos[3].setValues(-rSq2H, 0.0, 0.5);
00866 oPos[4].setValues( 0.0, rSq2H, -0.5);
00867 oPos[5].setValues( 0.0, rSq2H, 0.5);
00868
00869 oUV[3].setValues(0.0, 1.0);
00870 oUV[4].setValues(1.0, 0.0);
00871 oUV[5].setValues(1.0, 1.0);
00872 }
00873
00874 void FishEyeProjector::initRightMesh(Geometry *pGeo)
00875 {
00876 GeoVec2dPropertyUnrecPtr pUVProp =
00877 dynamic_cast<GeoVec2dProperty *>(
00878 pGeo->getProperty(Geometry::TexCoordsIndex));
00879
00880 GeoVec3dPropertyUnrecPtr pPosProp =
00881 dynamic_cast<GeoVec3dProperty *>(
00882 pGeo->getProperty(Geometry::PositionsIndex));
00883
00884 OSG_ASSERT(pUVProp != NULL);
00885 OSG_ASSERT(pPosProp != NULL);
00886
00887 MFVec2d &oUV = *(pUVProp ->editFieldPtr());
00888 MFVec3d &oPos = *(pPosProp->editFieldPtr());
00889
00890 Real32 rSq2H = osgSqrt(2.0) / 2.0;
00891
00892 oUV .resize(6);
00893 oPos.resize(6);
00894
00895 oPos[0].setValues(0.0, rSq2H, -0.5);
00896 oPos[1].setValues(rSq2H, 0.0, -0.5);
00897 oPos[2].setValues(rSq2H, 0.0, 0.5);
00898
00899 oUV[0].setValues(0.0, 0.0);
00900 oUV[1].setValues(1.0, 0.0);
00901 oUV[2].setValues(1.0, 1.0);
00902
00903
00904 oPos[3].setValues( 0.0, rSq2H, -0.5);
00905 oPos[4].setValues(rSq2H, 0.0, 0.5);
00906 oPos[5].setValues( 0.0, rSq2H, 0.5);
00907
00908 oUV[3].setValues(0.0, 0.0);
00909 oUV[4].setValues(1.0, 1.0);
00910 oUV[5].setValues(0.0, 1.0);
00911 }
00912
00913 void FishEyeProjector::updateMesh(Geometry *pGeo)
00914 {
00915 GeoVec2dPropertyUnrecPtr pUVProp =
00916 dynamic_cast<GeoVec2dProperty *>(
00917 pGeo->getProperty(Geometry::TexCoordsIndex));
00918
00919 GeoVec3dPropertyUnrecPtr pPosProp =
00920 dynamic_cast<GeoVec3dProperty *>(
00921 pGeo->getProperty(Geometry::PositionsIndex));
00922
00923 OSG_ASSERT(pUVProp != NULL);
00924 OSG_ASSERT(pPosProp != NULL);
00925
00926 MFVec2d &oUV = *(pUVProp ->editFieldPtr());
00927 MFVec3d &oPos = *(pPosProp->editFieldPtr());
00928
00929 UInt32 uiNumTris = oPos.size() / 3;
00930
00931 for(UInt32 i = 0; i < this->getMeshRefinementLevel(); i++)
00932 {
00933 oUV .resize(4 * uiNumTris * 3);
00934 oPos.resize(4 * uiNumTris * 3);
00935
00936 splitFaces(oUV, oPos, uiNumTris);
00937 }
00938
00939 for(UInt32 i = 0; i < oPos.size(); i++)
00940 oPos[i].normalize();
00941
00942 for(UInt32 i = 0; i < oPos.size(); i++)
00943 {
00944 flattenVertex(oPos[i], 180.0);
00945 }
00946
00947
00948 GeoUInt32Property *pIdx =
00949 dynamic_cast<GeoUInt32Property *>(
00950 pGeo->getIndex(Geometry::TexCoordsIndex));
00951
00952 GeoUInt32Property *pLen =
00953 dynamic_cast<GeoUInt32Property *>(pGeo->getLengths());
00954
00955 GeoUInt8Property *pTyp =
00956 dynamic_cast<GeoUInt8Property *>(pGeo->getTypes());
00957
00958 OSG_ASSERT(pIdx != NULL);
00959 OSG_ASSERT(pLen != NULL);
00960 OSG_ASSERT(pTyp != NULL);
00961
00962
00963
00964 if(this->getMode() == FishEyeProjector::MirrorDome )
00965 {
00966 warpData(pGeo);
00967 }
00968 else
00969 {
00970 GeoVectorProperty *pColProp = pGeo->getProperty(Geometry::ColorsIndex);
00971
00972 if(pColProp != NULL)
00973 {
00974 pColProp->setIgnore(true);
00975 }
00976 }
00977
00978 pTyp->clear();
00979 pLen->clear();
00980
00981 pTyp->push_back(GL_TRIANGLES);
00982 pLen->push_back(oPos.size() );
00983
00984 pIdx->clear();
00985
00986 for(UInt32 i = 0; i < oPos.size(); ++i)
00987 {
00988 pIdx->push_back(i);
00989 }
00990 }
00991
00992 void FishEyeProjector::rebuildGeometries(void)
00993 {
00994 if(this->_mfGeometries.size() == 0)
00995 {
00996 for(UInt32 i = 0; i < 4; ++i)
00997 {
00998 GeometryUnrecPtr pGeo = Geometry::create();
00999
01000 GeoVec2dPropertyUnrecPtr pUV = GeoVec2dProperty::create();
01001 GeoVec3dPropertyUnrecPtr pPos = GeoVec3dProperty::create();
01002
01003 GeoUInt32PropertyUnrecPtr pIdx = GeoUInt32Property::create();
01004 GeoUInt32PropertyUnrecPtr pLen = GeoUInt32Property::create();
01005 GeoUInt8PropertyUnrecPtr pTyp = GeoUInt8Property ::create();
01006
01007 pGeo->setProperty(pUV, Geometry::TexCoordsIndex);
01008 pGeo->setProperty(pPos, Geometry::PositionsIndex);
01009
01010 pGeo->setTypes (pTyp);
01011 pGeo->setLengths(pLen);
01012
01013 pGeo->setIndex(pIdx, Geometry::PositionsIndex);
01014 pGeo->setIndex(pIdx, Geometry::TexCoordsIndex);
01015
01016 this->pushToGeometries(pGeo);
01017 }
01018 }
01019
01020
01021 initTopMesh (this->getGeometries(0));
01022 updateMesh (this->getGeometries(0));
01023
01024 initBottomMesh(this->getGeometries(1));
01025 updateMesh (this->getGeometries(1));
01026
01027 initLeftMesh (this->getGeometries(2));
01028 updateMesh (this->getGeometries(2));
01029
01030 initRightMesh (this->getGeometries(3));
01031 updateMesh (this->getGeometries(3));
01032 }
01033
01034 FishEyeProjectorData *FishEyeProjector::initData(RenderActionBase *pAction)
01035 {
01036 FishEyeProjectorDataUnrecPtr pData =
01037 pAction->getData<FishEyeProjectorData *>(_iDataSlotId);
01038
01039 if(pData == NULL)
01040 {
01041 pData = setupStageData(pAction);
01042
01043 this->setData(pData, _iDataSlotId, pAction);
01044 }
01045
01046 return pData;
01047 }
01048
01049 FishEyeProjectorDataTransitPtr FishEyeProjector::setupStageData(
01050 RenderActionBase *pAction)
01051 {
01052 FishEyeProjectorDataTransitPtr returnValue =
01053 FishEyeProjectorData::createLocal();
01054
01055 if(returnValue == NULL)
01056 return returnValue;
01057
01058 FrameBufferObjectUnrecPtr pTarget = NULL;
01059 RenderBufferUnrecPtr pDepthBuffer = NULL;
01060
01061 pTarget = FrameBufferObject::createLocal();
01062 pDepthBuffer = RenderBuffer ::createLocal();
01063
01064 pDepthBuffer->setInternalFormat (GL_DEPTH_COMPONENT24);
01065
01066 pTarget ->setDepthAttachment(pDepthBuffer );
01067
01068 returnValue ->setRenderTarget (pTarget );
01069
01070
01071 for(UInt32 i = 0; i < 4; ++i)
01072 {
01073 TextureObjChunkUnrecPtr pTex = TextureObjChunk::createLocal();
01074
01075 ImageUnrecPtr pImg = Image::createLocal();
01076
01077 pImg->set(Image::OSG_RGB_PF,
01078 this->getResolution(),
01079 this->getResolution(),
01080 1,
01081 1,
01082 1,
01083 0.0,
01084 0,
01085 Image::OSG_UINT8_IMAGEDATA,
01086 false,
01087 1);
01088
01089 pTex ->setImage (pImg );
01090 pTex ->setMinFilter (GL_LINEAR );
01091 pTex ->setMagFilter (GL_LINEAR );
01092 pTex ->setWrapS (GL_CLAMP_TO_EDGE );
01093 pTex ->setWrapT (GL_CLAMP_TO_EDGE );
01094 pTex ->setInternalFormat(this->getBufferFormat());
01095
01096
01097 TextureBufferUnrecPtr pTexBuffer = TextureBuffer::createLocal();
01098
01099 pTexBuffer->setTexture (pTex );
01100 pTexBuffer->setTexTarget(GL_TEXTURE_2D);
01101
01102 pTarget->setColorAttachment(pTexBuffer, i);
01103
01104 returnValue->editMFTextures()->push_back(pTex);
01105 }
01106
01107
01108
01109 pTarget->setSize(this->getResolution(),
01110 this->getResolution());
01111
01112
01113
01114 PerspectiveCameraUnrecPtr pCam = PerspectiveCamera::createLocal();
01115
01116 pCam->setNear(pAction->getCamera()->getNear());
01117 pCam->setFar (pAction->getCamera()->getFar ());
01118
01119 pCam->setFov (osgDegree2Rad(90.f));
01120
01121 returnValue->setCamera(pCam);
01122
01123
01124 returnValue->setTextureRes (this->getResolution ());
01125 returnValue->setTextureFormat(this->getBufferFormat());
01126
01127
01128 commitChanges();
01129
01130
01131 return returnValue;
01132 }
01133
01134
01135 void FishEyeProjector::resizeStageData(FishEyeProjectorData *pData,
01136 Int32 iPixelWidth,
01137 Int32 iPixelHeight)
01138 {
01139 FWARNING(("FishEyeProjector resize not implemented ==> wrong results\n"));
01140 }
01141
01142
01143 void FishEyeProjector::postProcess(DrawEnv *pEnv)
01144 {
01145 Window *win = pEnv->getWindow();
01146
01147 if(win->hasExtension(_uiFramebuffer_object_extension) == false)
01148 {
01149 FNOTICE(("Framebuffer objects not supported on Window %p!\n", win));
01150 return;
01151 }
01152
01153 FishEyeProjectorData *pData =
01154 pEnv->getData<FishEyeProjectorData *>(_iDataSlotId);
01155
01156
01157 if(pData == NULL)
01158 return;
01159
01160
01161
01162
01163 if(this->getMode() == WarpMap)
01164 {
01165 glClearColor(0.0,0.0,0.0,0.0);
01166 }
01167 else
01168 {
01169 glClearColor(0.05f,0.05f,0.05f,0.0f);
01170 }
01171
01172
01173 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01174
01175
01176
01177 glMatrixMode(GL_MODELVIEW);
01178 glPushMatrix();
01179 glLoadIdentity();
01180
01181 switch(this->getMode())
01182 {
01183 case TruncateBottom:
01184 gluLookAt(0.0,-1.0,0.25,0.0,0.0,0.25,0.0,0.0,1.0);
01185 break;
01186
01187 case TruncateTop:
01188 gluLookAt(0.0,-1.0,-0.25,0.0,0.0,-0.25,0.0,0.0,1.0);
01189 break;
01190
01191 case DomeVertical:
01192 case DomeHorizontal:
01193 case WarpMap:
01194 case MirrorDome:
01195 default:
01196 gluLookAt(0.0,-1.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0);
01197 break;
01198 }
01199
01200
01201 glMatrixMode(GL_PROJECTION);
01202 glPushMatrix();
01203 glLoadIdentity();
01204
01205
01206 glViewport(0,0,
01207 pEnv->getPixelWidth (),
01208 pEnv->getPixelHeight());
01209
01210 double r = pEnv->getPixelWidth () / double(pEnv->getPixelHeight());
01211
01212 switch(this->getMode())
01213 {
01214 case TruncateBottom:
01215 case TruncateTop:
01216 glOrtho(-r*0.75,r*0.75,-0.75,0.75,0.1,10.0);
01217 break;
01218
01219 case DomeHorizontal:
01220 glOrtho(-r*0.75,r*0.75,-0.75,0.75,0.1,10.0);
01221 break;
01222
01223 case DomeVertical:
01224 case WarpMap:
01225 case MirrorDome:
01226 default:
01227 glOrtho(-r,r,-1.0,1.0,0.1,10.0);
01228 break;
01229 }
01230
01231
01232
01233
01234 if(this->getShowMesh() == true)
01235 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
01236
01237 glColor3f(1.0,1.0,1.0);
01238
01239
01240 TextureObjChunk *pTexT = pData->getTextures (3);
01241 Geometry *pGeoT = this->getGeometries(0);
01242
01243 pTexT->activate(pEnv);
01244
01245 pGeoT->drawPrimitives(pEnv);
01246
01247
01248 TextureObjChunk *pTexB = pData->getTextures (2);
01249 Geometry *pGeoB = this->getGeometries(1);
01250
01251 pTexB->changeFrom(pEnv, pTexT);
01252
01253 pGeoB->drawPrimitives(pEnv);
01254
01255
01256 TextureObjChunk *pTexL = pData->getTextures (0);
01257 Geometry *pGeoL = this->getGeometries(2);
01258
01259 pTexL->changeFrom(pEnv, pTexB);
01260
01261 pGeoL->drawPrimitives(pEnv);
01262
01263
01264 TextureObjChunk *pTexR = pData->getTextures (1);
01265 Geometry *pGeoR = this->getGeometries(3);
01266
01267 pTexR->changeFrom(pEnv, pTexL);
01268
01269 pGeoR->drawPrimitives(pEnv);
01270
01271 pTexR->deactivate(pEnv);
01272
01273 if(this->getShowMesh() == true)
01274 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
01275
01276
01277 #ifdef OSG_DRAW_FACES
01278 glMatrixMode(GL_MODELVIEW);
01279 glLoadIdentity();
01280
01281 glMatrixMode(GL_PROJECTION);
01282 glLoadIdentity();
01283
01284 glOrtho(-1.0,1.0,-1.0,1.0,0.1,10.0);
01285
01286 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
01287
01288 glDisable(GL_DEPTH_TEST);
01289
01290 TextureObjChunk *pTex1 = pData->getTextures(0);
01291
01292 pTex1->activate(pEnv);
01293
01294 glBegin(GL_QUADS);
01295 {
01296 glTexCoord2f(0.0, 0.0);
01297 glVertex3f(-0.9, -0.9, -1.0);
01298
01299 glTexCoord2f(1.0, 0.0);
01300 glVertex3f(-0.6, -0.9, -1.0);
01301
01302 glTexCoord2f(1.0, 1.0);
01303 glVertex3f(-0.6, -0.6, -1.0);
01304
01305 glTexCoord2f(0.0, 1.0);
01306 glVertex3f(-0.9, -0.6, -1.0);
01307 }
01308 glEnd();
01309
01310 TextureObjChunk *pTex2 = pData->getTextures(1);
01311
01312 pTex2->changeFrom(pEnv, pTex1);
01313
01314 glBegin(GL_QUADS);
01315 {
01316 glTexCoord2f(0.0, 0.0);
01317 glVertex3f(-0.5, -0.9, -1.0);
01318
01319 glTexCoord2f(1.0, 0.0);
01320 glVertex3f(-0.2, -0.9, -1.0);
01321
01322 glTexCoord2f(1.0, 1.0);
01323 glVertex3f(-0.2, -0.6, -1.0);
01324
01325 glTexCoord2f(0.0, 1.0);
01326 glVertex3f(-0.5, -0.6, -1.0);
01327 }
01328 glEnd();
01329
01330 pTex1 = pData->getTextures(2);
01331
01332 pTex1->changeFrom(pEnv, pTex2);
01333
01334 glBegin(GL_QUADS);
01335 {
01336 glTexCoord2f(0.0, 0.0);
01337 glVertex3f(-0.1, -0.9, -1.0);
01338
01339 glTexCoord2f(1.0, 0.0);
01340 glVertex3f( 0.2, -0.9, -1.0);
01341
01342 glTexCoord2f(1.0, 1.0);
01343 glVertex3f( 0.2, -0.6, -1.0);
01344
01345 glTexCoord2f(0.0, 1.0);
01346 glVertex3f(-0.1, -0.6, -1.0);
01347 }
01348 glEnd();
01349
01350 pTex2 = pData->getTextures(3);
01351
01352 pTex2->changeFrom(pEnv, pTex1);
01353
01354 glBegin(GL_QUADS);
01355 {
01356 glTexCoord2f(0.0, 0.0);
01357 glVertex3f(0.3, -0.9, -1.0);
01358
01359 glTexCoord2f(1.0, 0.0);
01360 glVertex3f(0.6, -0.9, -1.0);
01361
01362 glTexCoord2f(1.0, 1.0);
01363 glVertex3f(0.6, -0.6, -1.0);
01364
01365 glTexCoord2f(0.0, 1.0);
01366 glVertex3f(0.3, -0.6, -1.0);
01367 }
01368 glEnd();
01369
01370 pTex2->deactivate(pEnv);
01371
01372 glEnable(GL_DEPTH_TEST);
01373 #endif
01374
01375
01376 glMatrixMode(GL_PROJECTION);
01377 glPopMatrix();
01378
01379 glMatrixMode(GL_MODELVIEW);
01380 glPopMatrix();
01381
01382 }
01383