diff --git a/CMakeLists.txt b/CMakeLists.txt index fde1ffdc5c8..29d75685c71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -892,6 +892,7 @@ set( CGAMELIST ${GAMELOGIC_DIR}/cgame/cg_rocket_dataformatter.cpp ${GAMELOGIC_DIR}/cgame/cg_gameinfo.cpp ${GAMELOGIC_DIR}/cgame/cg_parseutils.cpp + ${GAMELOGIC_DIR}/cgame/Filter.cpp ${ENGINE_DIR}/client/cg_api.h ${ENGINE_DIR}/client/cg_msgdef.h ${ENGINE_DIR}/qcommon/print_translated.h diff --git a/src/gamelogic/cgame/Filter.cpp b/src/gamelogic/cgame/Filter.cpp new file mode 100644 index 00000000000..e5d4d17c7f3 --- /dev/null +++ b/src/gamelogic/cgame/Filter.cpp @@ -0,0 +1,94 @@ +/* +=========================================================================== + +Copyright 2015 Unvanquished Developers + +This file is part of Daemon. + +Daemon is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Daemon is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Daemon. If not, see . + +=========================================================================== +*/ + +#include "cg_local.h" + +template +Filter::Filter( int a_width ) +{ + this->width = a_width; +} + +template +void Filter::Insert( T sample ) +{ + this->samples.remove_if( + [&]( std::pair& sample ) + { + return cg.time - sample.first > width; + } + ); + this->samples.emplace( this->samples.begin( ), cg.time, sample ); +} + +template +void Filter::Reset( ) +{ + this->samples.clear( ); +} + + +template +T MAFilter::Get( ) +{ + T total = 0; + + for( auto s : this->samples ) + total += s.second; + + return total / this->samples.size( ); +} + +template +T CubicMAFilter::Get( ) +{ + T total = 0; + float weight, total_weight = 0; + + for( auto s: this->samples ) + { + weight = 1.0f - (float)( cg.time - s.first ) / this->width; + weight = weight * weight * weight; + total_weight += weight; + total += s.second * weight; + } + + return total / total_weight; +} + +template +T GaussianMAFilter::Get( ) +{ + T total = 0; + float weight, total_weight = 0; + + for( auto s: this->samples ) + { + weight = (float)( cg.time - s.first ) / this->width; + weight = exp( -8.0f * weight * weight ); + total_weight += weight; + total += s.second * weight; + } + + return total / total_weight; +} diff --git a/src/gamelogic/cgame/cg_local.h b/src/gamelogic/cgame/cg_local.h index ae96215346d..f53bbed1a64 100644 --- a/src/gamelogic/cgame/cg_local.h +++ b/src/gamelogic/cgame/cg_local.h @@ -2375,5 +2375,48 @@ float CG_Rocket_ProgressBarValueByName( const char *name ); // cg_gameinfo.c // void CG_LoadArenas(); + +// +// Filter.cpp +// + +template +class Filter +{ +protected: + std::list > samples; + int width; + +public: + Filter( int a_width ); + void Insert( T sample ); + void Reset( ); + virtual T Get( ) = 0; +}; + +template +class MAFilter: public Filter +{ +public: + using Filter::Filter; + T Get( ); +}; + +template +class CubicMAFilter: public Filter +{ +public: + using Filter::Filter; + T Get( ); +}; + +template +class GaussianMAFilter: public Filter +{ +public: + using Filter::Filter; + T Get( ); +}; + #endif