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