Merge branch 'lua_versions' into main/rendor-staging
[ryzomcore.git] / ryzom / tools / reynolds / track.h
blob943ac4ffc1c83adc3f730ba3c1a01a26291d2280
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef NL_TRACK_H
20 #define NL_TRACK_H
22 #include "nel/misc/types_nl.h"
23 #include "nel/misc/smart_ptr.h"
24 #include "nel/misc/vector.h"
25 #include "nel/misc/vectord.h"
26 #include "nel/misc/entity_id.h"
27 #include "nel/misc/sheet_id.h"
29 #include "nel/pacs/u_move_container.h"
30 #include "nel/pacs/u_move_primitive.h"
32 #include "nel/georges/u_form.h"
33 #include "nel/georges/u_form_elm.h"
36 /**
37 * The base class for moving entity
38 * \author Benjamin Legros
39 * \author Nevrax France
40 * \date 2002
42 class CTrackBase
44 public:
45 /// State type
46 enum TTrackState
48 Idle = 0, // not controlled yet
49 MovingTowardsTarget, // first step of motion, moving towards target
50 TargetLocked, // close to target, locked
51 TargetLost, // target moved away, can't reach it any longer
52 TargetUnreachable // can't reach target, too far or too many obstacles on the way
55 /// Get Id
56 virtual const NLMISC::CEntityId &getId() const = 0;
58 /// Get SheetId
59 virtual const NLMISC::CSheetId &getSheetId() const = 0;
61 /// Has Id ?
62 virtual bool hasId() const = 0;
64 /// Get track Position
65 virtual void getPosition(NLMISC::CVectorD &pos, float &heading) const = 0;
67 /// Has Position ?
68 virtual bool hasPosition() const = 0;
70 /// Set user data
71 virtual void setUserData(void *data) = 0;
73 /// Get user data
74 virtual void *getUserData() = 0;
76 /// Get Track state
77 virtual TTrackState getTrackState() const = 0;
80 /**
81 * A track that represents a moving point
82 * \author Benjamin Legros
83 * \author Nevrax France
84 * \date 2002
86 class CTrack : public CTrackBase, public NLMISC::CRefCount
88 public:
89 /**
90 * The sheet type read by Georges
92 class CSheet
94 public:
95 CSheet(): WalkSpeed(1.3f), RunSpeed(6.0f), Radius(0.5f), Height(2.0f), Length(1.0), Width(1.0) {}
97 /// The Walk speed of the entity
98 float WalkSpeed;
99 /// The Run speed of the entity
100 float RunSpeed;
101 /// The Pacs radius of the entity
102 float Radius;
103 /// The Height radius of the entity
104 float Height;
105 /// The Animation length of the entity
106 float Length;
107 /// The Width length of the entity
108 float Width;
110 void readGeorges (const NLMISC::CSmartPtr<NLGEORGES::UForm> &form, const NLMISC::CSheetId &sheetId)
112 // the form was found so read the true values from George
113 form->getRootNode ().getValueByName (WalkSpeed, "Basics.MovementSpeeds.WalkSpeed");
114 form->getRootNode ().getValueByName (RunSpeed, "Basics.MovementSpeeds.RunSpeed");
115 form->getRootNode ().getValueByName (Radius, "Collision.CollisionRadius");
116 form->getRootNode ().getValueByName (Height, "Collision.Height");
117 form->getRootNode ().getValueByName (Width, "Collision.Width");
118 form->getRootNode ().getValueByName (Length, "Collision.Length");
121 void serial (NLMISC::IStream &s)
123 s.serial (WalkSpeed, RunSpeed);
124 s.serial (Radius, Height);
125 s.serial (Length, Width);
128 static uint getVersion () { return 1; }
130 /// The default sheet
131 static CSheet DefaultSheet;
134 public:
136 /// Constructor
137 CTrack() : _OwnControl(NULL), _MoveContainer(NULL), _MovePrimitive(NULL),
138 _Id(NLMISC::CEntityId::Unknown), _SheetId(NLMISC::CSheetId::Unknown), _Sheet(NULL), _Followed(NULL),
139 _HasPosition(false), _HasId(false), _IdRequested(false), _PositionUpdatesRequested(false), _IsStatic(false),
140 _ForceRelease(false), _ReceiveVision(false), _UserData(NULL), _State(Idle),
141 _SmoothedTargetDistanceDelta(3.0), _LastTargetDistance(-1.0)
146 /// Destructor
147 ~CTrack();
149 /// Init track
150 void setId(const NLMISC::CEntityId &id, const NLMISC::CSheetId &sheet);
152 /// Get Id
153 const NLMISC::CEntityId &getId() const
155 return _Id;
158 /// Get SheetId
159 const NLMISC::CSheetId &getSheetId() const
161 return _SheetId;
164 /// Get SheetId
165 const CSheet *getSheet() const
167 return _Sheet;
170 /// Has Id ?
171 bool hasId() const
173 return _HasId;
178 /// Update track position
179 void setPosition(const NLMISC::CVectorD &pos, float heading)
181 // don't allow more than one position to be set when control is owned
182 if (_HasPosition && _OwnControl)
183 return;
184 _Position = pos;
185 _Heading = heading;
186 _HasPosition = true;
189 /// Get track Position
190 void getPosition(NLMISC::CVectorD &pos, float &heading) const
192 if (_HasPosition)
194 pos = _Position;
195 heading = _Heading;
197 else
199 nlwarning("ReynoldsLib:CTrack:getPosition(): Track %s position not yet set", _Id.toString().c_str());
203 /// Set Static state
204 void setStatic(bool isstatic = true)
206 _IsStatic = isstatic;
211 /// Has Control Owned ?
212 bool hasControlOwned() const
214 return _OwnControl;
217 /// Has Position ?
218 bool hasPosition() const
220 return _HasPosition;
223 /// Invalid position
224 void invalidPosition()
226 _HasPosition = false;
229 /// Is static ?
230 bool isStatic() const
232 return _IsStatic;
237 /// Follow
238 void follow(CTrack *followed);
240 /// Leave
241 void leave();
243 /// Update
244 void update(double dt);
246 /// Update vision
247 void updateVision(const std::vector<NLMISC::CEntityId> &in, const std::vector<NLMISC::CEntityId> &out);
249 /// Update vision
250 void updateVision(const std::vector<NLMISC::CEntityId> &vision);
252 /// Force release
253 void forceRelease() { _ForceRelease = true; }
257 /// Get current state
258 TTrackState getTrackState() const { return _State; }
263 /// Set user data
264 void setUserData(void *data) { _UserData = data; }
266 /// Get user data
267 void *getUserData() { return _UserData; }
274 /// Get contact distance
275 double rawDistance(const CTrack *other, NLMISC::CVectorD &distance) const
277 distance = other->_Position - _Position;
278 distance.z = 0.0;
279 return distance.norm();
282 /// Get contact distance
283 double contactDistance(const CTrack *other, NLMISC::CVectorD &distance, double &rawdistance) const
285 rawdistance = rawDistance(other, distance);
286 return contactDistanceWithRawDistance(other, distance, rawdistance);
289 /// Get contact distance
290 double contactDistanceWithRawDistance(const CTrack *other, NLMISC::CVectorD &distance, double &rawdistance) const
292 double theta = atan2(distance.y, distance.x);
293 double theta1 = _Heading - theta;
294 double theta2 = other->_Heading - theta + 3.1415926535;
296 float l1 = _Sheet->Length,
297 w1 = _Sheet->Width;
298 float l2 = other->_Sheet->Length,
299 w2 = other->_Sheet->Width;
301 double r1 = 0.5 * sqrt( l1*l1 + (w1*w1-l1*l1)*NLMISC::sqr(sin(theta1)) );
302 double r2 = 0.5 * sqrt( l2*l2 + (w2*w2-l2*l2)*NLMISC::sqr(sin(theta2)) );
304 return rawdistance - r1 - r2;
309 protected:
311 /// Own Control
312 void acquireControl();
314 /// Release Control
315 void releaseControl();
317 /// Acquire vision
318 void acquireVision();
320 /// Release vision
321 void releaseVision();
323 /// Create Move primitive
324 void createMovePrimitive();
326 /// Delete Move primitive
327 void deleteMovePrimitive();
329 /// Check has position (ask for it if necessary)
330 bool isValid()
332 if (!hasId())
333 return false;
335 if (!hasPosition())
337 if (!hasControlOwned() && !_PositionUpdatesRequested)
338 requestPositionUpdates();
339 return false;
341 return true;
344 /// Request Id
345 void requestId();
347 /// Request Position
348 void requestPositionUpdates();
350 protected:
353 /// @name Track Id
354 //@{
356 /// Has Id
357 bool _HasId;
359 /// Id Requested
360 bool _IdRequested;
362 /// Entity Id
363 NLMISC::CEntityId _Id;
365 /// Sheet Id
366 NLMISC::CSheetId _SheetId;
368 /// Sheet
369 const CSheet *_Sheet;
371 /// Is static
372 bool _IsStatic;
374 //@}
378 /// @name Track Position Control
379 //@{
381 /// Own control
382 bool _OwnControl;
384 /// Has Position
385 bool _HasPosition;
387 /// Id Requested
388 bool _PositionUpdatesRequested;
390 /// Position
391 NLMISC::CVectorD _Position;
393 /// Heading
394 float _Heading;
396 /// Followed track
397 NLMISC::CSmartPtr<CTrack> _Followed;
399 //@}
403 /// @name Track PACS
404 //@{
406 /// Move Container
407 NLPACS::UMoveContainer *_MoveContainer;
409 /// Move Primitive
410 NLPACS::UMovePrimitive *_MovePrimitive;
412 //@}
416 /// @name Misc
417 //@{
419 /// Force release
420 bool _ForceRelease;
422 /// Vision container
423 typedef std::map<NLMISC::CEntityId, NLMISC::CSmartPtr<CTrack> > TVision;
425 /// Vision
426 TVision _Vision;
428 /// Receive vision
429 bool _ReceiveVision;
431 /// User data
432 void *_UserData;
434 /// Track state
435 TTrackState _State;
437 /// Last move cycle
438 uint32 _LastMoveCycle;
440 /// Last target distance
441 double _LastTargetDistance;
443 /// Smoothed target distance
444 double _SmoothedTargetDistanceDelta;
446 //@}
448 public:
449 /// @name Target attraction control
450 //@{
452 /// Required target spacing
453 static double TargetSpacing;
455 /// Target attraction strength
456 static double TargetAttraction;
458 /// Target attraction amplification
459 static double TargetAmp;
461 //@}
464 /// @name Obstacle repulsion control
465 //@{
467 /// Fast obstacle exclusion distance
468 static double ObstacleExcludeDistance;
470 /// Required obstacle spacing
471 static double ObstacleSpacing;
473 /// Obstacle repulsion strength
474 static double ObstacleRepulsion;
476 /// Obstacle repulsion amplification
477 static double ObstacleAmp;
479 //@}
482 /// @name Track motion control
483 //@{
485 /// Minimum motion distance
486 static double MinimumMotion;
488 /// Lock distance threshold
489 static double LockThreshold;
491 /// Lose distance threshold
492 static double LoseThreshold;
494 /// Stabilise cycle
495 static uint32 StabiliseCycle;
497 //@}
501 #endif // NL_TRACK_H
503 /* End of track.h */