OSGProjectionCameraDecorator.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038
00039 //---------------------------------------------------------------------------
00040 //  Includes
00041 //---------------------------------------------------------------------------
00042
00043 #include <cstdlib>
00044 #include <cstdio>
00045
00046 #include "OSGConfig.h"
00047
00048 #include "OSGMatrixUtility.h"
00049 #include "OSGQuaternion.h"
00050 #include "OSGNode.h"
00051
00052 #include "OSGProjectionCameraDecorator.h"
00053
00054 OSG_USING_NAMESPACE
00055
00056 // Documentation for this class is emited in the
00057 // OSGProjectionCameraDecoratorBase.cpp file.
00058 // To modify it, please change the .fcd file (OSGProjectionCameraDecorator.fcd) and
00059 // regenerate the base file.
00060
00061 /*----------------------- constructors & destructors ----------------------*/
00062
00063 ProjectionCameraDecorator::ProjectionCameraDecorator(void) :
00064     Inherited()
00065 {
00066 }
00067
00068 ProjectionCameraDecorator::ProjectionCameraDecorator(
00069     const ProjectionCameraDecorator &source) :
00070
00071     Inherited(source)
00072 {
00073 }
00074
00075 ProjectionCameraDecorator::~ProjectionCameraDecorator(void)
00076 {
00077 }
00078
00079 /*----------------------------- class specific ----------------------------*/
00080
00081 void ProjectionCameraDecorator::initMethod(InitPhase ePhase)
00082 {
00083     Inherited::initMethod(ePhase);
00084 }
00085
00086 void ProjectionCameraDecorator::changed(ConstFieldMaskArg whichField,
00087                                         UInt32            origin,
00088                                         BitVector         details)
00089 {
00090     Inherited::changed(whichField, origin, details);
00091
00092     if(whichField & SurfaceFieldMask)
00093         updateData();
00094 }
00095
00096 void ProjectionCameraDecorator::dump(      UInt32    ,
00097                                      const BitVector ) const
00098 {
00099     SLOG << "Dump ProjectionCameraDecorator NI" << std::endl;
00100 }
00101
00104 void ProjectionCameraDecorator::updateData(void)
00105 {
00106     if(getMFSurface()->size() != 4)
00107     {
00108         FWARNING(("ProjectionCameraDecorator: only defined for 4 point "
00109                   "surfaces!\n"));
00110         return;
00111     }
00112
00113     Pnt3f p0(getSurface(0));
00114     Vec3f d1,d2,n;
00115
00116     d1 = getSurface(1) - p0;
00117     d2 = getSurface(3) - p0;
00118
00119     n = d1.cross(d2);
00120
00121     if(n.isZero())
00122     {
00123         FWARNING(("ProjectionCameraDecorator: normal is zero, surface "
00124                   "ill-defined!\n"));
00125         return;
00126     }
00127
00128     this->setLeft  (Plane(d1,p0));
00129     this->setBottom(Plane(d2,p0));
00130     this->setNormal(Plane(n ,p0));
00131     this->setWidth (d1.length());
00132     this->setHeight(d2.length());
00133 }
00134
00135
00136 void ProjectionCameraDecorator::getViewing(Matrix &result,
00137                                            UInt32  OSG_CHECK_ARG(width ),
00138                                            UInt32  OSG_CHECK_ARG(height))
00139 {
00140     Node *pUser = getUser();
00141
00142     if(pUser == NULL)
00143     {
00144         FWARNING(("ProjectionCameraDecorator::getViewing: no user!\n"));
00145
00146         Camera *pCamera = getDecoratee();
00147
00148         if(pCamera == NULL)
00149         {
00150             result.setIdentity();
00151
00152             return;
00153         }
00154
00155         pCamera->getBeacon()->getToWorld(result);
00156
00157         result.invert();
00158     }
00159     else
00160     {
00161         pUser->getToWorld(result);
00162
00163         result.invert();
00164     }
00165 }
00166
00167 void ProjectionCameraDecorator::getProjection(Matrix &result,
00168                                               UInt32  OSG_CHECK_ARG(width ),
00169                                               UInt32  OSG_CHECK_ARG(height))
00170 {
00171     Camera *camera = getDecoratee();
00172     Node   *pUser  = getUser     ();
00173
00174     if(camera == NULL)
00175     {
00176         FWARNING(("ProjectionCameraDecorator::getProjection: no "
00177                   "decoratee!\n"));
00178
00179         result.setIdentity();
00180
00181         return;
00182     }
00183
00184
00185     Matrix cam,user;
00186
00187     camera->getBeacon()->getToWorld(cam);
00188
00189     if(pUser == NULL)
00190     {
00191         FWARNING(("ProjectionCameraDecorator::getProjection: no user!\n"));
00192
00193         user = cam;
00194     }
00195     else
00196     {
00197         pUser->getToWorld(user);
00198     }
00199
00200     cam.invert();
00201
00202     cam.mult(user);
00203
00204     Pnt3f viewer(cam[3]);
00205
00206     Real32 eyeFac;
00207
00208     if(getLeftEye())
00209     {
00210         eyeFac=-.5;
00211     }
00212     else
00213     {
00214         eyeFac=+.5;
00215     }
00216
00217     viewer += Vec3f(cam[0]) * eyeFac * getEyeSeparation();
00218
00219     Real32 dist = getNormal().distance(viewer),
00220            dl   = getLeft  ().distance(viewer),
00221            db   = getBottom().distance(viewer),
00222            f    = camera->getNear() / dist;
00223
00224     MatrixFrustum(result, -dl * f, (getWidth ()-dl) * f,
00225                           -db * f, (getHeight()-db) * f,
00226                           camera->getNear(), camera->getFar() );
00227 }
00228
00229
00230 void ProjectionCameraDecorator::getProjectionTranslation(
00231     Matrix &result,
00232     UInt32  OSG_CHECK_ARG(width ),
00233     UInt32  OSG_CHECK_ARG(height))
00234 {
00235     Camera *camera = getDecoratee();
00236     Node   *pUser  = getUser     ();
00237
00238     if(camera == NULL)
00239     {
00240         FFATAL(("ProjectionCameraDecorator::getProjectionTranslation: "
00241                 "no decoratee!\n"));
00242
00243         result.setIdentity();
00244
00245         return;
00246     }
00247
00248
00249     Matrix cam,user;
00250
00251     camera->getBeacon()->getToWorld(cam);
00252
00253     if(pUser == NULL)
00254     {
00255         FWARNING(("ProjectionCameraDecorator::getProjectionTranslation: "
00256                   "no user!\n"));
00257
00258         user = cam;
00259     }
00260     else
00261     {
00262         pUser->getToWorld(user);
00263     }
00264
00265     cam.invert();
00266     cam.mult(user);
00267
00268     Vec3f dir(getNormal().getNormal()),
00269           up (getBottom().getNormal()),
00270           right;
00271     Vec3f pos(cam[3]);
00272
00273     Real32 eyeFac;
00274
00275     if(getLeftEye())
00276     {
00277         eyeFac=-.5;
00278     }
00279     else
00280     {
00281         eyeFac=+.5;
00282     }
00283
00284     pos += Vec3f(cam[0]) * eyeFac * getEyeSeparation();
00285
00286     right = up.cross(dir);
00287     up = dir.cross(right);
00288
00289     result.setIdentity();
00290     result.setValue(right, up, dir, pos);
00291     result.invert();
00292
00293     result.mult(cam);
00294 #if 0
00295 static bool hack = true;
00296     Quaternion q( getNormal().getNormal(), Vec3f(0,0,1));
00297
00298     Vec3f v;
00299     Real32 a;
00300     q.getValueAsAxisDeg(v,a);
00301
00302     // HACKKK
00303     if(hack && a > 50)
00304     {
00305         q.getValue(result);
00306
00307         Real32 ang1 = 54.44;
00308         Real32 ang2 = 6.27;
00309
00310         if(v[1] < 0)    ang1 = -ang1;
00311
00312         Quaternion q1,q2;
00313         Matrix m1,m2;
00314
00315         q1.setValueAsAxisDeg(0,1,0,ang1);
00316         q2.setValueAsAxisDeg(1,0,0,ang2);
00317
00318         q1.getValue(m1);
00319         q2.getValue(m2);
00320
00321         result = m2;
00322         result.mult(m1);
00323     }
00324 #endif 
00325 }
00326