Panda3D
smoothMover.h
1 // Filename: smoothMover.h
2 // Created by: drose (19Oct01)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #ifndef SMOOTHMOVER_H
16 #define SMOOTHMOVER_H
17 
18 #include "directbase.h"
19 #include "luse.h"
20 #include "clockObject.h"
21 #include "circBuffer.h"
22 #include "nodePath.h"
23 #include "pdeque.h"
24 
25 static const int max_position_reports = 10;
26 static const int max_timestamp_delays = 10;
27 
28 
29 ////////////////////////////////////////////////////////////////////
30 // Class : SmoothMover
31 // Description : This class handles smoothing of sampled motion points
32 // over time, e.g. for smoothing the apparent movement
33 // of remote avatars, whose positions are sent via
34 // occasional telemetry updates.
35 //
36 // It can operate in any of three modes: off, in which
37 // it does not smooth any motion but provides the last
38 // position it was told; smoothing only, in which it
39 // smooths motion information but never tries to
40 // anticipate where the avatar might be going; or full
41 // prediction, in which it smooths motion as well as
42 // tries to predict the avatar's position in lead of the
43 // last position update. The assumption is that all
44 // SmoothMovers in the world will be operating in the
45 // same mode together.
46 ////////////////////////////////////////////////////////////////////
47 class EXPCL_DIRECT SmoothMover {
48 PUBLISHED:
49  SmoothMover();
50  ~SmoothMover();
51 
52  // These methods are used to specify each position update. Call the
53  // appropriate set_* function(s), as needed, and then call
54  // mark_position(). The return value of each function is true if
55  // the parameter value has changed, or false if it remains the same
56  // as last time.
57  INLINE bool set_pos(const LVecBase3 &pos);
58  INLINE bool set_pos(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z);
59  INLINE bool set_x(PN_stdfloat x);
60  INLINE bool set_y(PN_stdfloat y);
61  INLINE bool set_z(PN_stdfloat z);
62 
63  INLINE bool set_hpr(const LVecBase3 &hpr);
64  INLINE bool set_hpr(PN_stdfloat h, PN_stdfloat p, PN_stdfloat r);
65  INLINE bool set_h(PN_stdfloat h);
66  INLINE bool set_p(PN_stdfloat p);
67  INLINE bool set_r(PN_stdfloat r);
68 
69  INLINE bool set_pos_hpr(const LVecBase3 &pos, const LVecBase3 &hpr);
70  INLINE bool set_pos_hpr(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat h, PN_stdfloat p, PN_stdfloat r);
71 
72  INLINE const LPoint3 &get_sample_pos() const;
73  INLINE const LVecBase3 &get_sample_hpr() const;
74 
75  INLINE void set_phony_timestamp(double timestamp = 0.0, bool period_adjust = false);
76 
77  INLINE void set_timestamp(double timestamp);
78 
79  INLINE bool has_most_recent_timestamp() const;
80  INLINE double get_most_recent_timestamp() const;
81 
82  void mark_position();
83  void clear_positions(bool reset_velocity);
84 
85  INLINE bool compute_smooth_position();
86  bool compute_smooth_position(double timestamp);
87  bool get_latest_position();
88 
89  INLINE const LPoint3 &get_smooth_pos() const;
90  INLINE const LVecBase3 &get_smooth_hpr() const;
91 
92  INLINE void apply_smooth_pos(NodePath &node) const;
93  INLINE void apply_smooth_pos_hpr(NodePath &pos_node, NodePath &hpr_node) const;
94  INLINE void apply_smooth_hpr(NodePath &node) const;
95 
96  INLINE void compute_and_apply_smooth_pos(NodePath &node);
97  INLINE void compute_and_apply_smooth_pos_hpr(NodePath &pos_node, NodePath &hpr_node);
98  INLINE void compute_and_apply_smooth_hpr(NodePath &hpr_node);
99 
100  INLINE PN_stdfloat get_smooth_forward_velocity() const;
101  INLINE PN_stdfloat get_smooth_lateral_velocity() const;
102  INLINE PN_stdfloat get_smooth_rotational_velocity() const;
103  INLINE const LVecBase3 &get_forward_axis() const;
104 
105  void handle_wrt_reparent(NodePath &old_parent, NodePath &new_parent);
106 
107  enum SmoothMode {
108  SM_off,
109  SM_on,
110  // We might conceivably add more kinds of smooth modes later, for
111  // instance, SM_spline.
112  };
113  enum PredictionMode {
114  PM_off,
115  PM_on,
116  // Similarly for other kinds of prediction modes. I don't know
117  // why, though; linear interpolation seems to work pretty darn
118  // well.
119  };
120 
121  INLINE void set_smooth_mode(SmoothMode mode);
122  INLINE SmoothMode get_smooth_mode();
123 
124  INLINE void set_prediction_mode(PredictionMode mode);
125  INLINE PredictionMode get_prediction_mode();
126 
127  INLINE void set_delay(double delay);
128  INLINE double get_delay();
129 
130  INLINE void set_accept_clock_skew(bool flag);
131  INLINE bool get_accept_clock_skew();
132 
133  INLINE void set_max_position_age(double age);
134  INLINE double get_max_position_age();
135 
136  INLINE void set_expected_broadcast_period(double period);
137  INLINE double get_expected_broadcast_period();
138 
139  INLINE void set_reset_velocity_age(double age);
140  INLINE double get_reset_velocity_age();
141 
142  INLINE void set_directional_velocity(bool flag);
143  INLINE bool get_directional_velocity();
144 
145  INLINE void set_default_to_standing_still(bool flag);
146  INLINE bool get_default_to_standing_still();
147 
148  void output(ostream &out) const;
149  void write(ostream &out) const;
150 
151 private:
152  void set_smooth_pos(const LPoint3 &pos, const LVecBase3 &hpr,
153  double timestamp);
154  void linear_interpolate(int point_before, int point_after, double timestamp);
155  void compute_velocity(const LVector3 &pos_delta,
156  const LVecBase3 &hpr_delta,
157  double age);
158 
159  void record_timestamp_delay(double timestamp);
160  INLINE double get_avg_timestamp_delay() const;
161 
162 public:
163  // This internal class is declared public to work around compiler
164  // issues.
165  class SamplePoint {
166  public:
167  LPoint3 _pos;
168  LVecBase3 _hpr;
169  double _timestamp;
170  };
171 
172 private:
173  SamplePoint _sample;
174 
175  LPoint3 _smooth_pos;
176  LVecBase3 _smooth_hpr;
177  LVector3 _forward_axis;
178  double _smooth_timestamp;
179  bool _smooth_position_known;
180  bool _smooth_position_changed;
181  bool _computed_forward_axis;
182 
183  double _smooth_forward_velocity;
184  double _smooth_lateral_velocity;
185  double _smooth_rotational_velocity;
186 
187  bool _has_most_recent_timestamp;
188  double _most_recent_timestamp;
189 
190  // typedef CircBuffer<SamplePoint, max_position_reports> Points;
191  typedef pdeque<SamplePoint> Points;
192  Points _points;
193  int _last_point_before;
194  int _last_point_after;
195 
196  // This array is used to record the average delay in receiving
197  // timestamps from a particular client, in milliseconds. This value
198  // will measure both the latency and clock skew from that client,
199  // allowing us to present smooth motion in spite of extreme latency
200  // or poor clock synchronization.
202  TimestampDelays _timestamp_delays;
203  int _net_timestamp_delay;
204  double _last_heard_from;
205 
206  SmoothMode _smooth_mode;
207  PredictionMode _prediction_mode;
208  double _delay;
209  bool _accept_clock_skew;
210  double _max_position_age;
211  double _expected_broadcast_period;
212  double _reset_velocity_age;
213  bool _directional_velocity;
214  bool _default_to_standing_still;
215 };
216 
217 #include "smoothMover.I"
218 
219 #endif
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Definition: lvector3.h:100
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
This class handles smoothing of sampled motion points over time, e.g.
Definition: smoothMover.h:47
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:165