From 181f690bb8865001b8edba9767eea2192c637db3 Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 7 Dec 2007 02:25:10 +0000 Subject: [PATCH] ClockObject::calc_frame_rate_deviation() --- panda/src/grutil/frameRateMeter.cxx | 5 +++-- panda/src/putil/clockObject.cxx | 35 +++++++++++++++++++++++++++++ panda/src/putil/clockObject.h | 1 + 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/panda/src/grutil/frameRateMeter.cxx b/panda/src/grutil/frameRateMeter.cxx index 1fa46af613..d97960eb8b 100644 --- a/panda/src/grutil/frameRateMeter.cxx +++ b/panda/src/grutil/frameRateMeter.cxx @@ -181,14 +181,15 @@ do_update(Thread *current_thread) { _last_update = _clock_object->get_frame_time(current_thread); double frame_rate = _clock_object->get_average_frame_rate(current_thread); + double deviation = _clock_object->calc_frame_rate_deviation(current_thread); static const size_t buffer_size = 1024; char buffer[buffer_size]; #ifdef WIN32_VC // Windows doesn't define snprintf(). Hope we don't overflow. - sprintf(buffer, _text_pattern.c_str(), frame_rate); + sprintf(buffer, _text_pattern.c_str(), frame_rate, deviation); #else - snprintf(buffer, buffer_size, _text_pattern.c_str(), frame_rate); + snprintf(buffer, buffer_size, _text_pattern.c_str(), frame_rate, deviation); #endif nassertv(strlen(buffer) < buffer_size); diff --git a/panda/src/putil/clockObject.cxx b/panda/src/putil/clockObject.cxx index f047d32417..f78e6ff1d9 100644 --- a/panda/src/putil/clockObject.cxx +++ b/panda/src/putil/clockObject.cxx @@ -277,6 +277,41 @@ get_average_frame_rate(Thread *current_thread) const { } } +//////////////////////////////////////////////////////////////////// +// Function: ClockObject::calc_frame_time_deviation +// Access: Published +// Description: Returns the standard deviation of the frame times of +// the frames rendered over the past +// get_average_frame_rate_interval() seconds. This +// number gives an estimate of the chugginess of the +// frame rate; if it is large, there is a large +// variation in the frame rate; if is small, all of the +// frames are consistent in length. +// +// A large value might also represent just a recent +// change in frame rate, for instance, because the +// camera has just rotated from looking at a simple +// scene to looking at a more complex scene. +//////////////////////////////////////////////////////////////////// +double ClockObject:: +calc_frame_rate_deviation(Thread *current_thread) const { + CDStageReader cdata(_cycler, 0, current_thread); + if (_ticks.size() <= 1) { + return 0.0; + } else { + double mean = (_ticks.back() - _ticks.front()) / (_ticks.size() - 1); + size_t i; + double sum_squares = 0.0; + for (i = 0; i < _ticks.size() - 1; ++i) { + double delta = _ticks[i + 1] - _ticks[i]; + double diff = (delta - mean); + sum_squares += (diff * diff); + } + double deviation_2 = sum_squares / (_ticks.size() - 1); + return sqrt(deviation_2); + } +} + //////////////////////////////////////////////////////////////////// // Function: ClockObject::tick // Access: Published diff --git a/panda/src/putil/clockObject.h b/panda/src/putil/clockObject.h index 3b9951638f..6caad2b14e 100644 --- a/panda/src/putil/clockObject.h +++ b/panda/src/putil/clockObject.h @@ -108,6 +108,7 @@ PUBLISHED: INLINE void set_average_frame_rate_interval(double time); INLINE double get_average_frame_rate_interval() const; double get_average_frame_rate(Thread *current_thread = Thread::get_current_thread()) const; + double calc_frame_rate_deviation(Thread *current_thread = Thread::get_current_thread()) const; void tick(Thread *current_thread = Thread::get_current_thread()); void sync_frame_time(Thread *current_thread = Thread::get_current_thread());