1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 #include "OSGConfig.h"
40 #include "OSGBaseTypes.h"
41 #include "OSGMatrix.h"
42 #include "OSGMatrixUtility.h"
44 #include "OSGWalkEngine.h"
45 #include "OSGNavigator.h"
47 #include "OSGCamera.h"
48 #include "OSGBackground.h"
52 /***************************************************************************\
54 \***************************************************************************/
56 /*! \class OSG::WalkEngine
57 \ingroup GrpSystemWindowNavigators
66 WalkEngine::create(void)
68 return WalkEngineTransitPtr(new WalkEngine
);
71 /*------------------------------ get --------------------------------------*/
73 /*------------------------------ set --------------------------------------*/
75 void WalkEngine::setGround(Node
* const new_ground
)
80 void WalkEngine::setWorld(Node
* const new_world
)
85 void WalkEngine::setGroundDistance(Real32 groundDistance
)
87 _groundDistance
=groundDistance
;
90 void WalkEngine::setMinWallDistance (Real32 wallDistance
)
92 _wallDistance
=wallDistance
;
95 void WalkEngine::setPersonDimensions(Real32 height
,Real32 width
,Real32 fatness
)
102 /*---------------------- navigator engine callbacks ------------------------*/
103 void WalkEngine::idle(Int16 buttons
, Int16 x
, Int16 y
, Navigator
* nav
)
105 if (buttons
) moveTo(x
, y
, nav
);
108 void WalkEngine::onViewportChanged(Navigator
* nav
)
110 Viewport
*vp
= nav
->getViewport();
111 setGround(vp
->getRoot());
112 setWorld (vp
->getRoot());
115 /*---------------------- Walker Transformations ----------------------------*/
120 void WalkEngine::rotate (Real32 deltaX
, Real32 deltaY
)
122 Inherited::rotate(deltaX
, deltaY
);
128 Real32
WalkEngine::forward(Real32 step
)
130 Vec3f lv
= _rFrom
- _rAt
;
136 Vec3f mv
= lv
- upn
.dot(lv
)*upn
;
139 //side vector symbolizes shoulders
144 Pnt3f rFrom
= _rFrom
+ step
* mv
;
145 Pnt3f rAt
= _rAt
+ step
* mv
;
148 Line
line(rFrom
, -upn
);
150 //keep the walker at a constant distance from the ground
151 _act
->setLine(line
);
152 _act
->apply (_ground
);
156 dist
= _act
->getHitT();
159 rFrom
= rFrom
+ (_groundDistance
- dist
+ _height
) * upn
;
160 rAt
= rAt
+ (_groundDistance
- dist
+ _height
) * upn
;
162 else return 0.0f
; //can't jump so high
165 //finally check if the move is correct or not
167 line
.setValue(rFrom
, (rFrom
- _rFrom
));
168 _act
->setLine(line
);
169 _act
->apply (_world
);
173 dist
= _act
->getHitT();
174 if(dist
<= _fatness
+ _wallDistance
)
175 return 0.0; //running against a wall
178 //move was ok, store new values
185 /*! turns the viewer right or left
188 Real32
WalkEngine::right(Real32 step
)
190 // Int16 sign = (step >= 0) ? -1 : 1;
191 // Real32 angle = 0.19634954f;
193 // //rotate around the up vector
194 // FlyNavigator::rotate(sign*angle, 0);
197 Vec3f lv
= _rFrom
- _rAt
;
203 Vec3f mv
= lv
- upn
.dot(lv
)*upn
;
206 //side vector symbolizes shoulders
211 Pnt3f rFrom
= _rFrom
+ step
* sv
;
212 Pnt3f rAt
= _rAt
+ step
* sv
;
215 Line
line(rFrom
, -upn
);
217 //keep the walker at a constant distance from the ground
218 _act
->setLine(line
);
219 _act
->apply (_ground
);
223 dist
= _act
->getHitT();
226 rFrom
= rFrom
+ (_groundDistance
- dist
+ _height
) * upn
;
227 rAt
= rAt
+ (_groundDistance
- dist
+ _height
) * upn
;
229 else return 0.0; //can't jump so high
232 //finally check if the move is correct or not
234 line
.setValue(rFrom
, (rFrom
- _rFrom
));
235 _act
->setLine(line
);
236 _act
->apply (_world
);
240 dist
= _act
->getHitT();
241 if(dist
<= _fatness
+ _wallDistance
)
242 return 0.0; //running against a wall
245 //move was ok, store new values
252 /*------------------------- constructors ----------------------------------*/
254 WalkEngine::WalkEngine(void) :
258 _groundDistance(0.75f
),
263 _act(IntersectAction::create())
267 /*-------------------------- destructors ----------------------------------*/
269 WalkEngine::~WalkEngine()