Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGBillboard.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 <stdlib.h>
00044 #include <stdio.h>
00045 
00046 #include <OSGConfig.h>
00047 
00048 #include <OSGGL.h>
00049 
00050 #include "OSGNodePtr.h"
00051 #include "OSGBillboard.h"
00052 #include "OSGDrawAction.h"
00053 #include "OSGIntersectAction.h"
00054 #include "OSGRenderAction.h"
00055 #include "OSGCamera.h"
00056 #include "OSGNode.h"
00057 #include "OSGQuaternion.h"
00058 
00059 OSG_USING_NAMESPACE
00060 
00065 /*----------------------- constructors & destructors ----------------------*/
00066 
00068 
00069 Billboard::Billboard(void) :
00070     Inherited(),
00071     _camTransform()
00072 {
00073 }
00074 
00076 
00077 Billboard::Billboard(const Billboard &source) :
00078     Inherited(source),
00079     _camTransform(source._camTransform)
00080 {
00081 }
00082 
00084 
00085 Billboard::~Billboard(void)
00086 {
00087 }
00088 
00089 /*----------------------------- class specific ----------------------------*/
00090 
00092 
00093 void Billboard::initMethod (void)
00094 {
00095     DrawAction::registerEnterDefault( 
00096         getClassType(), 
00097         osgTypedMethodFunctor2BaseCPtrRef<
00098             Action::ResultE,
00099             BillboardPtr    , 
00100             CNodePtr        ,  
00101             Action         *>(&Billboard::drawEnter));
00102     
00103     DrawAction::registerLeaveDefault( 
00104         getClassType(), 
00105         osgTypedMethodFunctor2BaseCPtrRef<
00106             Action::ResultE,
00107             BillboardPtr    , 
00108             CNodePtr        ,  
00109             Action         *>(&Billboard::drawLeave));
00110 
00111 
00112     IntersectAction::registerEnterDefault( 
00113         getClassType(), 
00114         osgTypedMethodFunctor2BaseCPtrRef<
00115             Action::ResultE,
00116             BillboardPtr    , 
00117             CNodePtr        ,  
00118             Action         *>(&Billboard::intersectEnter));
00119 
00120     IntersectAction::registerLeaveDefault( 
00121         getClassType(), 
00122         osgTypedMethodFunctor2BaseCPtrRef<
00123             Action::ResultE,
00124             BillboardPtr    , 
00125             CNodePtr        ,   
00126             Action         *>(&Billboard::intersectLeave));
00127 
00128 
00129     RenderAction::registerEnterDefault(
00130         getClassType(), 
00131         osgTypedMethodFunctor2BaseCPtrRef<
00132             Action::ResultE,
00133             BillboardPtr    , 
00134             CNodePtr        ,  
00135             Action         *>(&Billboard::renderEnter));
00136 
00137     RenderAction::registerLeaveDefault(
00138         getClassType(), 
00139         osgTypedMethodFunctor2BaseCPtrRef<
00140             Action::ResultE,
00141             BillboardPtr    , 
00142             CNodePtr        ,  
00143             Action         *>(&Billboard::renderLeave));
00144 }
00145 
00147 
00148 void Billboard::changed(BitVector whichField, UInt32 origin)
00149 {
00150     Inherited::changed(whichField, origin);
00151 }
00152 
00154 
00155 void Billboard::dump(      UInt32    uiIndent,
00156                      const BitVector bvFlags ) const
00157 {
00158     Inherited::dump(uiIndent, bvFlags);
00159 }
00160 
00161 
00162 /*------------------------- volume update -------------------------------*/
00163 
00164 void Billboard::adjustVolume( Volume & volume )
00165 {
00166     Inherited::adjustVolume(volume);
00167     
00168     // enlarge the volume to adjust for rotations
00169     // keep the center, but make it a cube big enough to contain the 
00170     // billboard in all orientations
00171     
00172     Pnt3f min, max;
00173     
00174     volume.getBounds(min, max);
00175     
00176     Vec3f  dia    = max - min;
00177     Pnt3f  center = min + dia * .5;
00178     Real32 extend = dia.maxValue();
00179     
00180     dia.setValues(extend * Sqrt2, extend * Sqrt2, extend * Sqrt2);
00181     
00182     volume.extendBy( center - dia );
00183     volume.extendBy( center + dia );
00184 }
00185 
00186 void Billboard::accumulateMatrix(Matrix &result)
00187 {
00188     result.mult(_camTransform);
00189 }
00190 
00191 void Billboard::calcMatrix(      DrawActionBase *pAction,
00192                            const Matrix         &mToWorld,
00193                                  Matrix         &mResult)
00194 {
00195     Pnt3f eyepos(0.f, 0.f, 0.f);
00196     Pnt3f objpos(0.f, 0.f, 0.f);
00197 
00198     Vec3f vDir;
00199     Vec3f n(0.f, 0.f, 1.f);
00200 
00201     Quaternion q1;
00202 
00203     Matrix mCamToWorld = pAction->getCameraToWorld();
00204 
00205     mResult.invertFrom(mToWorld);
00206     
00207     mToWorld.mult(n);
00208 
00209     if(getAxisOfRotation() == Vec3f::Null)
00210     {
00211         if(_sfFocusOnCamera.getValue() == true)
00212         {
00213             Vec3f vUp;
00214             Vec3f uW;
00215             Vec3f vX;
00216 
00217             mCamToWorld.mult(eyepos);
00218             mToWorld   .mult(objpos);
00219             
00220             vDir = eyepos - objpos;
00221             
00222             vUp.setValue (mCamToWorld[0]);
00223             
00224             vUp = vDir.cross(vUp);
00225 
00226             vUp.normalize();
00227             vDir.normalize();
00228 
00229             Matrix mTr;
00230 
00231             vX = vUp.cross(vDir);
00232             vX.normalize();
00233 
00234             mTr[0][0] = vX[0];
00235             mTr[0][1] = vX[1];
00236             mTr[0][2] = vX[2];
00237             mTr[1][0] = vUp[0];
00238             mTr[1][1] = vUp[1];
00239             mTr[1][2] = vUp[2];
00240             mTr[2][0] = vDir[0];
00241             mTr[2][1] = vDir[1];
00242             mTr[2][2] = vDir[2];
00243 
00244             q1.setValue(mTr);
00245         }
00246         else
00247         {
00248             if(_sfAlignToScreen.getValue() == false)
00249             {
00250                 Vec3f u  (0.f, 1.f, 0.f);
00251                 Vec3f vUp;
00252                 Vec3f uW;
00253                 
00254                 mCamToWorld.mult(eyepos);
00255                 mToWorld   .mult(objpos);
00256                 
00257                 vDir = eyepos - objpos;
00258                 
00259 //            vDir.setValue(mCamToWorld[2]);
00260                 
00261                 vUp.setValue (mCamToWorld[1]);
00262                 
00263                 Quaternion qN(n, vDir);
00264                 
00265                 mToWorld.mult(u);
00266                 
00267                 qN.multVec(u, uW);
00268                 
00269                 q1.setValue(uW, vUp);
00270                 
00271                 q1.mult(qN);
00272             }
00273             else
00274             {
00275                 Vec3f u  (0.f, 1.f, 0.f);
00276                 Vec3f vUp;
00277                 Vec3f uW;
00278 
00279                 vDir.setValue(mCamToWorld[2]);
00280                 
00281                 vUp.setValue (mCamToWorld[1]);
00282                 
00283                 Quaternion qN(n, vDir);
00284                 
00285                 mToWorld.mult(u);
00286                 
00287                 qN.multVec(u, uW);
00288             
00289                 q1.setValue(uW, vUp);
00290                 
00291                 q1.mult(qN);
00292             }
00293         }
00294     }
00295     else
00296     {
00297         Vec3f wUp;
00298         Vec3f s;
00299         Vec3f tDir;
00300 
00301         mCamToWorld.mult(eyepos);
00302 
00303         mToWorld.mult(objpos);
00304 
00305         mToWorld.mult(getAxisOfRotation(), wUp);
00306 
00307         vDir = eyepos - objpos;
00308 
00309         s    = vDir.cross(wUp);
00310         tDir = wUp .cross(s  );
00311         
00312         q1.setValue(n, tDir);
00313 
00314         // clamp angle to [min; max]
00315         Vec3f axis;
00316         Real32 angle;
00317 
00318         if ( getMinAngle() <= getMaxAngle() ) {
00319             q1.getValueAsAxisRad(axis, angle);
00320 
00321             if (angle < getMinAngle())
00322                 angle = getMinAngle();
00323             if (angle > getMaxAngle())
00324                 angle = getMaxAngle();
00325 
00326             q1.setValueAsAxisRad(axis, angle);
00327         }
00328     }
00329 
00330     Matrix mTrans;
00331     Matrix mMat;
00332     
00333     mTrans[3][0] = mToWorld[3][0];
00334     mTrans[3][1] = mToWorld[3][1];
00335     mTrans[3][2] = mToWorld[3][2];
00336 
00337     mMat.setTransform(q1);
00338 
00339     mResult.mult(mTrans);
00340     mResult.mult(mMat  );
00341 
00342     mTrans[3][0] = -mToWorld[3][0];
00343     mTrans[3][1] = -mToWorld[3][1];
00344     mTrans[3][2] = -mToWorld[3][2];
00345 
00346     mResult.mult(mTrans);
00347     mResult.mult(mToWorld);
00348 
00349     _camTransform = mResult;
00350 }
00351 
00352 /*-------------------------------------------------------------------------*/
00353 /*                               Draw                                      */
00354 
00355 Action::ResultE Billboard::drawEnter(Action *action)
00356 {
00357     DrawAction *da = dynamic_cast<DrawAction *>(action);
00358 
00359     Matrix mMat;
00360 
00361     calcMatrix(da,     
00362                da->getActNode()->getToWorld(),
00363                mMat);
00364 
00365     // should use the chunk, but it's not updated yet
00366     glPushMatrix ();
00367     glMultMatrixf(mMat.getValues());
00368 
00369 // !!! can't use visibles, as ToWorld gives garbage leading to wrong culling
00370 //    da->selectVisibles();
00371 
00372     return Action::Continue;
00373 }
00374 
00375 Action::ResultE Billboard::drawLeave(Action *)
00376 {
00377     glPopMatrix();
00378 
00379     return Action::Continue;
00380 }
00381 
00382 /*-------------------------------------------------------------------------*/
00383 /*                            Intersect                                    */
00384 
00385 Action::ResultE Billboard::intersectEnter(Action *action)
00386 {
00387     IntersectAction *ia = dynamic_cast<IntersectAction *>(action);
00388     Matrix           m(_camTransform);
00389 
00390     m.invert();
00391 
00392     Pnt3f pos;
00393     Vec3f dir;
00394 
00395     m.multFullMatrixPnt(ia->getLine().getPosition (), pos);
00396     m.multMatrixVec    (ia->getLine().getDirection(), dir);
00397 
00398     ia->setLine(Line(pos, dir), ia->getMaxDist());
00399     ia->scale(dir.length());
00400 
00401     return Action::Continue;
00402 }
00403 
00404 Action::ResultE Billboard::intersectLeave(Action *action)
00405 {
00406     IntersectAction *ia = dynamic_cast<IntersectAction *>(action);
00407     Matrix           m(_camTransform);
00408 
00409     Pnt3f pos;
00410     Vec3f dir;
00411 
00412     m.multFullMatrixPnt(ia->getLine().getPosition (), pos);
00413     m.multMatrixVec    (ia->getLine().getDirection(), dir);
00414 
00415     ia->setLine(Line(pos, dir), ia->getMaxDist());
00416     ia->scale(dir.length());
00417 
00418     return Action::Continue;
00419 }
00420 
00421 /*-------------------------------------------------------------------------*/
00422 /*                                Render                                   */
00423 
00424 Action::ResultE Billboard::renderEnter(Action *action)
00425 {
00426     RenderAction *pAction = dynamic_cast<RenderAction *>(action);
00427 
00428     Matrix mMat;
00429 
00430     calcMatrix(pAction, pAction->top_matrix(), mMat);
00431 
00432     pAction->push_matrix(mMat);
00433 
00434 // !!! can't use visibles, as ToWorld gives garbage leading to wrong culling
00435 //    pAction->selectVisibles();
00436 
00437     return Action::Continue;
00438 }
00439 
00440 Action::ResultE Billboard::renderLeave(Action *action)
00441 {
00442     RenderAction *pAction = dynamic_cast<RenderAction *>(action);
00443 
00444     pAction->pop_matrix();
00445 
00446     return Action::Continue;
00447 }
00448 
00449 
00450 /*-------------------------------------------------------------------------*/
00451 /*                              cvs id's                                   */
00452 
00453 #ifdef __sgi
00454 #pragma set woff 1174
00455 #endif
00456 
00457 #ifdef OSG_LINUX_ICC
00458 #pragma warning( disable : 177 )
00459 #endif
00460 
00461 namespace
00462 {
00463     static char cvsid_cpp[] = "@(#)$Id: $";
00464     static char cvsid_hpp[] = OSGBILLBOARD_HEADER_CVSID;
00465     static char cvsid_inl[] = OSGBILLBOARD_INLINE_CVSID;
00466 }

Generated on Thu Aug 25 04:01:12 2005 for OpenSG by  doxygen 1.4.3