OSGWalkEngine.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 #include "OSGConfig.h"
00040 #include "OSGBaseTypes.h"
00041 #include "OSGMatrix.h"
00042 #include "OSGMatrixUtility.h"
00043
00044 #include "OSGWalkEngine.h"
00045 #include "OSGNavigator.h"
00046 #include "OSGNode.h"
00047 #include "OSGCamera.h"
00048 #include "OSGBackground.h"
00049 #include "OSGIntersectAction.h"
00050
00051 OSG_USING_NAMESPACE
00052
00053 /***************************************************************************\
00054  *                            Description                                  *
00055 \***************************************************************************/
00056
00066 WalkEngineTransitPtr
00067 WalkEngine::create(void)
00068 {
00069     return WalkEngineTransitPtr(new WalkEngine);
00070 }
00071
00072 /*------------------------------ get --------------------------------------*/
00073
00074 /*------------------------------ set --------------------------------------*/
00075
00076 void WalkEngine::setGround(Node * const new_ground)
00077 {
00078     _ground=new_ground;
00079 }
00080
00081 void WalkEngine::setWorld(Node * const new_world)
00082 {
00083     _world=new_world;
00084 }
00085
00086 void WalkEngine::setGroundDistance(Real32 groundDistance)
00087 {
00088     _groundDistance=groundDistance;
00089 }
00090
00091 void WalkEngine::setMinWallDistance (Real32 wallDistance)
00092 {
00093     _wallDistance=wallDistance;
00094 }
00095
00096 void WalkEngine::setPersonDimensions(Real32 height,Real32 width,Real32 fatness)
00097 {
00098     _height  = height;
00099     _width   = width;
00100     _fatness = fatness;
00101 }
00102
00103 /*---------------------- navigator engine callbacks ------------------------*/
00104 void WalkEngine::idle(Int16 buttons, Int16 x, Int16 y, Navigator* nav)
00105 {
00106     if (buttons) moveTo(x, y, nav);
00107 }
00108
00109 void WalkEngine::onViewportChanged(Navigator* nav)
00110 {
00111     Viewport *vp = nav->getViewport();
00112     setGround(vp->getRoot());
00113     setWorld (vp->getRoot());
00114 }
00115
00116 /*---------------------- Walker Transformations ----------------------------*/
00117
00121 void WalkEngine::rotate (Real32 deltaX, Real32 deltaY)
00122 {
00123     Inherited::rotate(deltaX, deltaY);
00124 }
00125
00129 Real32 WalkEngine::forward(Real32 step)
00130 {
00131     Vec3f lv = _rFrom - _rAt;
00132     lv.normalize();
00133
00134     Vec3f upn = _vUp;
00135     upn.normalize();
00136
00137     Vec3f mv = lv - upn.dot(lv)*upn;
00138     mv.normalize();
00139
00140     //side vector symbolizes shoulders
00141     Vec3f sv = mv;
00142     sv.crossThis(upn);
00143     sv.normalize();
00144
00145     Pnt3f rFrom = _rFrom + step * mv;
00146     Pnt3f rAt   = _rAt   + step * mv;
00147
00148     Real32 dist;
00149     Line line(rFrom, -upn);
00150
00151     //keep the walker at a constant distance from the ground
00152     _act->setLine(line   );
00153     _act->apply  (_ground);
00154
00155     if(_act->didHit())
00156     {
00157         dist = _act->getHitT();
00158         if(dist >= _height)
00159         {
00160             rFrom = rFrom + (_groundDistance - dist + _height) * upn;
00161             rAt   = rAt   + (_groundDistance - dist + _height) * upn;
00162         }
00163         else return 0.0f;    //can't jump so high
00164     }
00165
00166     //finally check if the move is correct or not
00167
00168     line.setValue(rFrom, (rFrom - _rFrom));
00169     _act->setLine(line  );
00170     _act->apply  (_world);
00171
00172     if(_act->didHit())
00173     {
00174         dist = _act->getHitT();
00175         if(dist <= _fatness + _wallDistance)
00176             return 0.0;     //running against a wall
00177     }
00178
00179     //move was ok, store new values
00180     _rFrom = rFrom;
00181     _rAt   = rAt;
00182
00183     return step;
00184 }
00185
00189 Real32 WalkEngine::right(Real32 step)
00190 {
00191 //    Int16 sign = (step >= 0) ? -1 : 1;
00192 //    Real32 angle = 0.19634954f;
00193 //
00194 //    //rotate around the up vector
00195 //    FlyNavigator::rotate(sign*angle, 0);
00196 //    return step;
00197
00198     Vec3f lv = _rFrom - _rAt;
00199     lv.normalize();
00200
00201     Vec3f upn = _vUp;
00202     upn.normalize();
00203
00204     Vec3f mv = lv - upn.dot(lv)*upn;
00205     mv.normalize();
00206
00207     //side vector symbolizes shoulders
00208     Vec3f sv = mv;
00209     sv.crossThis(upn);
00210     sv.normalize();
00211
00212     Pnt3f rFrom = _rFrom + step * sv;
00213     Pnt3f rAt   = _rAt   + step * sv;
00214
00215     Real32 dist;
00216     Line line(rFrom, -upn);
00217
00218     //keep the walker at a constant distance from the ground
00219     _act->setLine(line   );
00220     _act->apply  (_ground);
00221
00222     if(_act->didHit())
00223     {
00224         dist = _act->getHitT();
00225         if(dist >= _height)
00226         {
00227             rFrom = rFrom + (_groundDistance - dist + _height) * upn;
00228             rAt   = rAt   + (_groundDistance - dist + _height) * upn;
00229         }
00230         else return 0.0;    //can't jump so high
00231     }
00232
00233     //finally check if the move is correct or not
00234
00235     line.setValue(rFrom, (rFrom - _rFrom));
00236     _act->setLine(line  );
00237     _act->apply  (_world);
00238
00239     if(_act->didHit())
00240     {
00241         dist = _act->getHitT();
00242         if(dist <= _fatness + _wallDistance)
00243             return 0.0;     //running against a wall
00244     }
00245
00246     //move was ok, store new values
00247     _rFrom = rFrom;
00248     _rAt   = rAt;
00249
00250     return step;
00251 }
00252
00253 /*------------------------- constructors ----------------------------------*/
00254
00255 WalkEngine::WalkEngine(void) :
00256     Inherited(),
00257     _ground(NULL),
00258     _world(NULL),
00259     _groundDistance(0.75f),
00260     _wallDistance(0.1f),
00261     _height(0.85f),
00262     _width(0.5f),
00263     _fatness(0.5f),
00264     _act(IntersectAction::create())
00265 {
00266 }
00267
00268 /*-------------------------- destructors ----------------------------------*/
00269
00270 WalkEngine::~WalkEngine()
00271 {
00272     delete _act;
00273 }