00001 // Filename: smoothMover.I 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 00020 //////////////////////////////////////////////////////////////////// 00021 // Function: SmoothMover::set_scale 00022 // Access: Published 00023 // Description: Specifies the current scale that should be applied to 00024 // the transform. This is not smoothed along with pos 00025 // and hpr, but rather takes effect immediately; it is 00026 // only here at all so we can return a complete matrix 00027 // in get_smooth_mat(). 00028 //////////////////////////////////////////////////////////////////// 00029 INLINE bool SmoothMover:: 00030 set_scale(const LVecBase3f &scale) { 00031 return set_sx(scale[0]) | set_sy(scale[1]) | set_sz(scale[2]); 00032 } 00033 00034 //////////////////////////////////////////////////////////////////// 00035 // Function: SmoothMover::set_scale 00036 // Access: Published 00037 // Description: Specifies the current scale that should be applied to 00038 // the transform. This is not smoothed along with pos 00039 // and hpr, but rather takes effect immediately; it is 00040 // only here at all so we can return a complete matrix 00041 // in get_smooth_mat(). 00042 //////////////////////////////////////////////////////////////////// 00043 INLINE bool SmoothMover:: 00044 set_scale(float sx, float sy, float sz) { 00045 return set_sx(sx) | set_sy(sy) | set_sz(sz); 00046 } 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Function: SmoothMover::set_sx 00050 // Access: Published 00051 // Description: Sets the X-axis scale only. See set_scale(). 00052 //////////////////////////////////////////////////////////////////// 00053 INLINE bool SmoothMover:: 00054 set_sx(float sx) { 00055 bool result = (sx != _scale[0]); 00056 _scale[0] = sx; 00057 _computed_smooth_mat = _computed_smooth_mat && !result; 00058 return result; 00059 } 00060 00061 //////////////////////////////////////////////////////////////////// 00062 // Function: SmoothMover::set_sy 00063 // Access: Published 00064 // Description: Sets the Y-axis scale only. See set_scale(). 00065 //////////////////////////////////////////////////////////////////// 00066 INLINE bool SmoothMover:: 00067 set_sy(float sy) { 00068 bool result = (sy != _scale[1]); 00069 _scale[1] = sy; 00070 _computed_smooth_mat = _computed_smooth_mat && !result; 00071 return result; 00072 } 00073 00074 //////////////////////////////////////////////////////////////////// 00075 // Function: SmoothMover::set_sz 00076 // Access: Published 00077 // Description: Sets the Z-axis scale only. See set_scale(). 00078 //////////////////////////////////////////////////////////////////// 00079 INLINE bool SmoothMover:: 00080 set_sz(float sz) { 00081 bool result = (sz != _scale[2]); 00082 _scale[2] = sz; 00083 _computed_smooth_mat = _computed_smooth_mat && !result; 00084 return result; 00085 } 00086 00087 //////////////////////////////////////////////////////////////////// 00088 // Function: SmoothMover::set_pos 00089 // Access: Published 00090 // Description: Specifies the position of the SmoothMover at a 00091 // particular time in the past. When mark_position() is 00092 // called, this will be recorded (along with hpr and 00093 // timestamp) in a position report, which will then be 00094 // used along with all other position reports to 00095 // determine the smooth position at any particular 00096 // instant. 00097 // 00098 // The return value is true if any parameter has changed 00099 // since the last call to set_pos(), or false if they 00100 // are the same. 00101 //////////////////////////////////////////////////////////////////// 00102 INLINE bool SmoothMover:: 00103 set_pos(const LVecBase3f &pos) { 00104 return set_x(pos[0]) | set_y(pos[1]) | set_z(pos[2]); 00105 } 00106 00107 //////////////////////////////////////////////////////////////////// 00108 // Function: SmoothMover::set_pos 00109 // Access: Published 00110 // Description: Specifies the position of the SmoothMover at a 00111 // particular time in the past. When mark_position() is 00112 // called, this will be recorded (along with hpr and 00113 // timestamp) in a position report, which will then be 00114 // used along with all other position reports to 00115 // determine the smooth position at any particular 00116 // instant. 00117 // 00118 // The return value is true if any parameter has changed 00119 // since the last call to set_pos(), or false if they 00120 // are the same. 00121 //////////////////////////////////////////////////////////////////// 00122 INLINE bool SmoothMover:: 00123 set_pos(float x, float y, float z) { 00124 return set_x(x) | set_y(y) | set_z(z); 00125 } 00126 00127 //////////////////////////////////////////////////////////////////// 00128 // Function: SmoothMover::set_x 00129 // Access: Published 00130 // Description: Sets the X position only. See set_pos(). 00131 //////////////////////////////////////////////////////////////////// 00132 INLINE bool SmoothMover:: 00133 set_x(float x) { 00134 bool result = (x != _sample._pos[0]); 00135 _sample._pos[0] = x; 00136 return result; 00137 } 00138 00139 //////////////////////////////////////////////////////////////////// 00140 // Function: SmoothMover::set_y 00141 // Access: Published 00142 // Description: Sets the Y position only. See set_pos(). 00143 //////////////////////////////////////////////////////////////////// 00144 INLINE bool SmoothMover:: 00145 set_y(float y) { 00146 bool result = (y != _sample._pos[1]); 00147 _sample._pos[1] = y; 00148 return result; 00149 } 00150 00151 //////////////////////////////////////////////////////////////////// 00152 // Function: SmoothMover::set_z 00153 // Access: Published 00154 // Description: Sets the Z position only. See set_pos(). 00155 //////////////////////////////////////////////////////////////////// 00156 INLINE bool SmoothMover:: 00157 set_z(float z) { 00158 bool result = (z != _sample._pos[2]); 00159 _sample._pos[2] = z; 00160 return result; 00161 } 00162 00163 //////////////////////////////////////////////////////////////////// 00164 // Function: SmoothMover::set_hpr 00165 // Access: Published 00166 // Description: Specifies the orientation of the SmoothMover at a 00167 // particular time in the past. When mark_position() is 00168 // called, this will be recorded (along with hpr and 00169 // timestamp) in a position report, which will then be 00170 // used along with all other position reports to 00171 // determine the smooth position at any particular 00172 // instant. 00173 // 00174 // The return value is true if any parameter has changed 00175 // since the last call to set_hpr(), or false if they 00176 // are the same. 00177 //////////////////////////////////////////////////////////////////// 00178 INLINE bool SmoothMover:: 00179 set_hpr(const LVecBase3f &hpr) { 00180 return set_h(hpr[0]) | set_p(hpr[1]) | set_r(hpr[2]); 00181 } 00182 00183 //////////////////////////////////////////////////////////////////// 00184 // Function: SmoothMover::set_hpr 00185 // Access: Published 00186 // Description: Specifies the orientation of the SmoothMover at a 00187 // particular time in the past. When mark_position() is 00188 // called, this will be recorded (along with hpr and 00189 // timestamp) in a position report, which will then be 00190 // used along with all other position reports to 00191 // determine the smooth position at any particular 00192 // instant. 00193 // 00194 // The return value is true if any parameter has changed 00195 // since the last call to set_hpr(), or false if they 00196 // are the same. 00197 //////////////////////////////////////////////////////////////////// 00198 INLINE bool SmoothMover:: 00199 set_hpr(float h, float p, float r) { 00200 return set_h(h) | set_p(p) | set_r(r); 00201 } 00202 00203 //////////////////////////////////////////////////////////////////// 00204 // Function: SmoothMover::set_h 00205 // Access: Published 00206 // Description: Sets the heading only. See set_hpr(). 00207 //////////////////////////////////////////////////////////////////// 00208 INLINE bool SmoothMover:: 00209 set_h(float h) { 00210 bool result = (h != _sample._hpr[0]); 00211 _sample._hpr[0] = h; 00212 return result; 00213 } 00214 00215 //////////////////////////////////////////////////////////////////// 00216 // Function: SmoothMover::set_p 00217 // Access: Published 00218 // Description: Sets the pitch only. See set_hpr(). 00219 //////////////////////////////////////////////////////////////////// 00220 INLINE bool SmoothMover:: 00221 set_p(float p) { 00222 bool result = (p != _sample._hpr[1]); 00223 _sample._hpr[1] = p; 00224 return result; 00225 } 00226 00227 //////////////////////////////////////////////////////////////////// 00228 // Function: SmoothMover::set_r 00229 // Access: Published 00230 // Description: Sets the roll only. See set_hpr(). 00231 //////////////////////////////////////////////////////////////////// 00232 INLINE bool SmoothMover:: 00233 set_r(float r) { 00234 bool result = (r != _sample._hpr[2]); 00235 _sample._hpr[2] = r; 00236 return result; 00237 } 00238 00239 //////////////////////////////////////////////////////////////////// 00240 // Function: SmoothMover::set_phony_timestamp 00241 // Access: Published 00242 // Description: Lies and specifies that the current position report 00243 // was received now. This is usually used for very old 00244 // position reports for which we're not sure of the 00245 // actual receipt time. 00246 //////////////////////////////////////////////////////////////////// 00247 INLINE void SmoothMover:: 00248 set_phony_timestamp() { 00249 double now = ClockObject::get_global_clock()->get_frame_time(); 00250 _sample._timestamp = now; 00251 } 00252 00253 //////////////////////////////////////////////////////////////////// 00254 // Function: SmoothMover::set_timestamp 00255 // Access: Published 00256 // Description: Specifies the time that the current position report 00257 // applies. This should be called, along with set_pos() 00258 // and set_hpr(), before a call to mark_position(). 00259 //////////////////////////////////////////////////////////////////// 00260 INLINE void SmoothMover:: 00261 set_timestamp(double timestamp) { 00262 _sample._timestamp = timestamp; 00263 record_timestamp_delay(timestamp); 00264 } 00265 00266 //////////////////////////////////////////////////////////////////// 00267 // Function: SmoothMover::compute_smooth_position 00268 // Access: Published 00269 // Description: Computes the smoothed position (and orientation) of 00270 // the mover at the indicated point in time, based on 00271 // the previous position reports. After this call has 00272 // been made, get_smooth_pos() etc. may be called to 00273 // retrieve the smoothed position. 00274 // 00275 // With no parameter, the function uses 00276 // ClockObject::get_frame_time() as the default time. 00277 //////////////////////////////////////////////////////////////////// 00278 INLINE bool SmoothMover:: 00279 compute_smooth_position() { 00280 return compute_smooth_position(ClockObject::get_global_clock()->get_frame_time()); 00281 } 00282 00283 //////////////////////////////////////////////////////////////////// 00284 // Function: SmoothMover::get_smooth_pos 00285 // Access: Published 00286 // Description: Returns the smoothed position as computed by a 00287 // previous call to compute_smooth_position(). 00288 //////////////////////////////////////////////////////////////////// 00289 INLINE const LPoint3f &SmoothMover:: 00290 get_smooth_pos() const { 00291 return _smooth_pos; 00292 } 00293 00294 //////////////////////////////////////////////////////////////////// 00295 // Function: SmoothMover::get_smooth_hpr 00296 // Access: Published 00297 // Description: Returns the smoothed orientation as computed by a 00298 // previous call to compute_smooth_position(). 00299 //////////////////////////////////////////////////////////////////// 00300 INLINE const LVecBase3f &SmoothMover:: 00301 get_smooth_hpr() const { 00302 return _smooth_hpr; 00303 } 00304 00305 //////////////////////////////////////////////////////////////////// 00306 // Function: SmoothMover::get_smooth_mat 00307 // Access: Published 00308 // Description: Returns the complete smoothed transformation matrix 00309 // as computed by a previous call to 00310 // compute_smooth_position(). 00311 //////////////////////////////////////////////////////////////////// 00312 INLINE const LMatrix4f &SmoothMover:: 00313 get_smooth_mat() { 00314 if (!_computed_smooth_mat) { 00315 compose_smooth_mat(); 00316 } 00317 return _smooth_mat; 00318 } 00319 00320 //////////////////////////////////////////////////////////////////// 00321 // Function: SmoothMover::get_smooth_forward_velocity 00322 // Access: Published 00323 // Description: Returns the speed at which the avatar is moving, in 00324 // feet per second, along its own forward axis (after 00325 // applying the avatar's hpr). This will be a positive 00326 // number if the avatar is moving forward, and a 00327 // negative number if it is moving backward. 00328 //////////////////////////////////////////////////////////////////// 00329 INLINE float SmoothMover:: 00330 get_smooth_forward_velocity() const { 00331 return _smooth_forward_velocity; 00332 } 00333 00334 //////////////////////////////////////////////////////////////////// 00335 // Function: SmoothMover::get_smooth_rotational_velocity 00336 // Access: Published 00337 // Description: Returns the speed at which the avatar is rotating in 00338 // the horizontal plane (i.e. heading), in degrees per 00339 // second. This may be positive or negative, according 00340 // to the direction of rotation. 00341 //////////////////////////////////////////////////////////////////// 00342 INLINE float SmoothMover:: 00343 get_smooth_rotational_velocity() const { 00344 return _smooth_rotational_velocity; 00345 } 00346 00347 //////////////////////////////////////////////////////////////////// 00348 // Function: SmoothMover::set_smooth_mode 00349 // Access: Published, Static 00350 // Description: Sets the smoothing mode of all SmoothMovers in the 00351 // world. If this is SM_off, no smoothing or prediction 00352 // will be performed, and get_smooth_pos() will simply 00353 // return the position last set by mark_position(). 00354 //////////////////////////////////////////////////////////////////// 00355 INLINE void SmoothMover:: 00356 set_smooth_mode(SmoothMover::SmoothMode mode) { 00357 _smooth_mode = mode; 00358 } 00359 00360 //////////////////////////////////////////////////////////////////// 00361 // Function: SmoothMover::get_smooth_mode 00362 // Access: Published, Static 00363 // Description: Returns the smoothing mode of all SmoothMovers in the 00364 // world. See set_smooth_mode(). 00365 //////////////////////////////////////////////////////////////////// 00366 INLINE SmoothMover::SmoothMode SmoothMover:: 00367 get_smooth_mode() { 00368 return _smooth_mode; 00369 } 00370 00371 //////////////////////////////////////////////////////////////////// 00372 // Function: SmoothMover::set_prediction_mode 00373 // Access: Published, Static 00374 // Description: Sets the predictioning mode of all SmoothMovers in the 00375 // world. If this is PM_off, no prediction will be 00376 // performed, but smoothing might still be performed. 00377 //////////////////////////////////////////////////////////////////// 00378 INLINE void SmoothMover:: 00379 set_prediction_mode(SmoothMover::PredictionMode mode) { 00380 _prediction_mode = mode; 00381 } 00382 00383 //////////////////////////////////////////////////////////////////// 00384 // Function: SmoothMover::get_prediction_mode 00385 // Access: Published, Static 00386 // Description: Returns the predictioning mode of all SmoothMovers in the 00387 // world. See set_prediction_mode(). 00388 //////////////////////////////////////////////////////////////////// 00389 INLINE SmoothMover::PredictionMode SmoothMover:: 00390 get_prediction_mode() { 00391 return _prediction_mode; 00392 } 00393 00394 //////////////////////////////////////////////////////////////////// 00395 // Function: SmoothMover::set_delay 00396 // Access: Published, Static 00397 // Description: Sets the amount of time, in seconds, to delay the 00398 // computed position of a SmoothMover. This is 00399 // particularly useful when the prediction mode is off, 00400 // because it can allow the apparent motion of an avatar 00401 // to appear smooth without relying on prediction, at 00402 // the cost of introducing additional lag in the 00403 // avatar's apparent position. 00404 //////////////////////////////////////////////////////////////////// 00405 INLINE void SmoothMover:: 00406 set_delay(double delay) { 00407 _delay = delay; 00408 } 00409 00410 //////////////////////////////////////////////////////////////////// 00411 // Function: SmoothMover::get_delay 00412 // Access: Published, Static 00413 // Description: Returns the amount of time, in seconds, to delay the 00414 // computed position of a SmoothMover. See set_delay(). 00415 //////////////////////////////////////////////////////////////////// 00416 INLINE double SmoothMover:: 00417 get_delay() { 00418 return _delay; 00419 } 00420 00421 //////////////////////////////////////////////////////////////////// 00422 // Function: SmoothMover::set_accept_clock_skew 00423 // Access: Published, Static 00424 // Description: Sets the 'accept clock skew' flag. When this flag is 00425 // true, clock skew from the other clients will be 00426 // tolerated by delaying each smooth mover's position an 00427 // additional amount, on top of that specified by 00428 // set_delay(), based on the measured average latency 00429 // for timestamp messages received by the client. 00430 // 00431 // In this way, if the other client has significant 00432 // clock skew with respect to our clock, it will be 00433 // evident as a large positive or negative average 00434 // latency for timestamps. By subtracting out this 00435 // average latency, we compensate for poor clock sync. 00436 //////////////////////////////////////////////////////////////////// 00437 INLINE void SmoothMover:: 00438 set_accept_clock_skew(bool flag) { 00439 _accept_clock_skew = flag; 00440 } 00441 00442 //////////////////////////////////////////////////////////////////// 00443 // Function: SmoothMover::get_accept_clock_skew 00444 // Access: Published, Static 00445 // Description: Returns the current state of the 'accept clock skew' 00446 // flag. See set_accept_clock_skew(). 00447 //////////////////////////////////////////////////////////////////// 00448 INLINE bool SmoothMover:: 00449 get_accept_clock_skew() { 00450 return _accept_clock_skew; 00451 } 00452 00453 //////////////////////////////////////////////////////////////////// 00454 // Function: SmoothMover::set_max_position_age 00455 // Access: Published, Static 00456 // Description: Sets the maximum amount of time a position is allowed 00457 // to remain unchanged before assuming it represents the 00458 // avatar actually standing still. 00459 //////////////////////////////////////////////////////////////////// 00460 INLINE void SmoothMover:: 00461 set_max_position_age(double age) { 00462 _max_position_age = age; 00463 } 00464 00465 //////////////////////////////////////////////////////////////////// 00466 // Function: SmoothMover::get_max_position_age 00467 // Access: Published, Static 00468 // Description: Returns the maximum amount of time a position is 00469 // allowed to remain unchanged before assuming it 00470 // represents the avatar actually standing still. 00471 //////////////////////////////////////////////////////////////////// 00472 INLINE double SmoothMover:: 00473 get_max_position_age() { 00474 return _max_position_age; 00475 } 00476 00477 //////////////////////////////////////////////////////////////////// 00478 // Function: SmoothMover::set_reset_velocity_age 00479 // Access: Published, Static 00480 // Description: Sets the amount of time that should elapse after the 00481 // last position report before the velocity is reset to 00482 // 0. This is similar to max_position_age, but it is 00483 // only used to determine the resetting of the reported 00484 // velocity. It should always be greater than or equal 00485 // to max_position_age. 00486 //////////////////////////////////////////////////////////////////// 00487 INLINE void SmoothMover:: 00488 set_reset_velocity_age(double age) { 00489 _reset_velocity_age = age; 00490 } 00491 00492 //////////////////////////////////////////////////////////////////// 00493 // Function: SmoothMover::get_reset_velocity_age 00494 // Access: Published, Static 00495 // Description: Returns the amount of time that should elapse after 00496 // the last position report before the velocity is reset 00497 // to 0. See set_reset_velocity_age(). 00498 //////////////////////////////////////////////////////////////////// 00499 INLINE double SmoothMover:: 00500 get_reset_velocity_age() { 00501 return _reset_velocity_age; 00502 } 00503 00504 //////////////////////////////////////////////////////////////////// 00505 // Function: SmoothMover::get_avg_timestamp_delay 00506 // Access: Private 00507 // Description: Returns the average delay observed in the last n 00508 // timestamps received from this client, in seconds. 00509 // This number represents the combination of the network 00510 // lag from this client, as well as the client's clock 00511 // skew relative to our clock. It could be negative if 00512 // the client's clock is running faster than our clock. 00513 //////////////////////////////////////////////////////////////////// 00514 INLINE double SmoothMover:: 00515 get_avg_timestamp_delay() const { 00516 nassertr(!_timestamp_delays.empty(), 0.0); 00517 return (double)_net_timestamp_delay / (double)_timestamp_delays.size() / 1000.0; 00518 }