Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

direct/src/deadrec/smoothMover.h

Go to the documentation of this file.
00001 // Filename: smoothMover.h
00002 // Created by:  drose (19Oct01)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #ifndef SMOOTHMOVER_H
00020 #define SMOOTHMOVER_H
00021 
00022 #include "directbase.h"
00023 #include "luse.h"
00024 #include "clockObject.h"
00025 #include "circBuffer.h"
00026 
00027 static const int max_position_reports = 10;
00028 static const int max_timestamp_delays = 10;
00029 
00030 ////////////////////////////////////////////////////////////////////
00031 //       Class : SmoothMover
00032 // Description : This class handles smoothing of sampled motion points
00033 //               over time, e.g. for smoothing the apparent movement
00034 //               of remote avatars, whose positions are sent via
00035 //               occasional telemetry updates.
00036 //
00037 //               It can operate in any of three modes: off, in which
00038 //               it does not smooth any motion but provides the last
00039 //               position it was told; smoothing only, in which it
00040 //               smooths motion information but never tries to
00041 //               anticipate where the avatar might be going; or full
00042 //               prediction, in which it smooths motion as well as
00043 //               tries to predict the avatar's position in lead of the
00044 //               last position update.  The assumption is that all
00045 //               SmoothMovers in the world will be operating in the
00046 //               same mode together.
00047 ////////////////////////////////////////////////////////////////////
00048 class EXPCL_DIRECT SmoothMover {
00049 PUBLISHED:
00050   SmoothMover();
00051   ~SmoothMover();
00052 
00053   // This method is just used to specify a scale which is only used
00054   // when composing the matrix for return by get_smooth_mat().  It
00055   // might change from time to time, but it is not smoothed.
00056   INLINE bool set_scale(const LVecBase3f &scale);
00057   INLINE bool set_scale(float sx, float sy, float sz);
00058   INLINE bool set_sx(float sx);
00059   INLINE bool set_sy(float sy);
00060   INLINE bool set_sz(float sz);
00061 
00062   // These methods are used to specify each position update.  Call the
00063   // appropriate set_* function(s), as needed, and then call
00064   // mark_position().  The return value of each function is true if
00065   // the parameter value has changed, or false if it remains the same
00066   // as last time.
00067   INLINE bool set_pos(const LVecBase3f &pos);
00068   INLINE bool set_pos(float x, float y, float z);
00069   INLINE bool set_x(float x);
00070   INLINE bool set_y(float y);
00071   INLINE bool set_z(float z);
00072 
00073   INLINE bool set_hpr(const LVecBase3f &hpr);
00074   INLINE bool set_hpr(float h, float p, float r);
00075   INLINE bool set_h(float h);
00076   INLINE bool set_p(float p);
00077   INLINE bool set_r(float r);
00078 
00079   bool set_mat(const LMatrix4f &mat);
00080 
00081   INLINE void set_phony_timestamp();
00082   INLINE void set_timestamp(double timestamp);
00083 
00084   void mark_position();
00085   void clear_positions(bool reset_velocity);
00086 
00087   INLINE bool compute_smooth_position();
00088   bool compute_smooth_position(double timestamp);
00089   bool get_latest_position();
00090 
00091   INLINE const LPoint3f &get_smooth_pos() const;
00092   INLINE const LVecBase3f &get_smooth_hpr() const;
00093   INLINE const LMatrix4f &get_smooth_mat();
00094 
00095   INLINE float get_smooth_forward_velocity() const;
00096   INLINE float get_smooth_rotational_velocity() const;
00097 
00098 
00099   // These static methods control the global properties of all
00100   // SmoothMovers.
00101   enum SmoothMode {
00102     SM_off,
00103     SM_on,
00104     // We might conceivably add more kinds of smooth modes later, for
00105     // instance, SM_spline.
00106   };
00107   enum PredictionMode {
00108     PM_off,
00109     PM_on,
00110     // Similarly for other kinds of prediction modes.  I don't know
00111     // why, though; linear interpolation seems to work pretty darn
00112     // well.
00113   };
00114 
00115   INLINE static void set_smooth_mode(SmoothMode mode);
00116   INLINE static SmoothMode get_smooth_mode();
00117 
00118   INLINE static void set_prediction_mode(PredictionMode mode);
00119   INLINE static PredictionMode get_prediction_mode();
00120 
00121   INLINE static void set_delay(double delay); 
00122   INLINE static double get_delay(); 
00123 
00124   INLINE static void set_accept_clock_skew(bool flag); 
00125   INLINE static bool get_accept_clock_skew(); 
00126 
00127   INLINE static void set_max_position_age(double age); 
00128   INLINE static double get_max_position_age(); 
00129 
00130   INLINE static void set_reset_velocity_age(double age); 
00131   INLINE static double get_reset_velocity_age(); 
00132 
00133   void output(ostream &out) const;
00134   void write(ostream &out) const;
00135 
00136 private:
00137   void set_smooth_pos(const LPoint3f &pos, const LVecBase3f &hpr,
00138                       double timestamp);
00139   void compose_smooth_mat();
00140   void linear_interpolate(int point_before, int point_after, double timestamp);
00141   void compute_velocity(const LVector3f &pos_delta, 
00142                         const LVecBase3f &hpr_delta,
00143                         double age);
00144 
00145   void record_timestamp_delay(double timestamp);
00146   INLINE double get_avg_timestamp_delay() const;
00147 
00148   LVecBase3f _scale;
00149 
00150   class SamplePoint {
00151   public:
00152     LPoint3f _pos;
00153     LVecBase3f _hpr;
00154     double _timestamp;
00155   };
00156   SamplePoint _sample;
00157 
00158   LPoint3f _smooth_pos;
00159   LVecBase3f _smooth_hpr;
00160   LMatrix4f _smooth_mat;
00161   double _smooth_timestamp;
00162   bool _smooth_position_known;
00163   bool _smooth_position_changed;
00164   bool _computed_smooth_mat;
00165 
00166   double _smooth_forward_velocity;
00167   double _smooth_rotational_velocity;
00168 
00169   typedef CircBuffer<SamplePoint, max_position_reports> Points;
00170   Points _points;
00171   int _last_point_before;
00172   int _last_point_after;
00173 
00174   // This array is used to record the average delay in receiving
00175   // timestamps from a particular client, in milliseconds.  This value
00176   // will measure both the latency and clock skew from that client,
00177   // allowing us to present smooth motion in spite of extreme latency
00178   // or poor clock synchronization.
00179   typedef CircBuffer<int, max_timestamp_delays> TimestampDelays;
00180   TimestampDelays _timestamp_delays;
00181   int _net_timestamp_delay;
00182   double _last_heard_from;
00183 
00184   static SmoothMode _smooth_mode;
00185   static PredictionMode _prediction_mode;
00186   static double _delay;
00187   static bool _accept_clock_skew;
00188   static double _max_position_age;
00189   static double _reset_velocity_age;
00190 };
00191 
00192 #include "smoothMover.I"
00193 
00194 #endif

Generated on Fri May 2 01:37:18 2003 for Direct by doxygen1.3