JK2eA
 All Classes Functions Variables
ControllerMixer.h
00001 #pragma once
00002 
00003 
00004 #include "Controller.h"
00005 #include <vector>
00006 #include <utility>
00007 
00008 /*
00009         Slouzi k michani controlleru\n
00010         CntType         = typ controlleru\n
00011         ParamType       = typ parametru\n
00012 */
00013 
00014 template<class CntType, class ParamType>
00015 class CControllerMixer : public CController {
00016 protected:
00017         std::vector<std::pair<float*,CntType*>> m_controllers;  
00018         ParamType                         m_accumulated_param;                          
00019 
00020 public:
00025         CControllerMixer(const std::string& name);
00029         virtual ~CControllerMixer(void);
00034         inline bool IsEmpty();
00043         void RegisterController(CntType* cnt, float* weight);
00048         void UnRegisterController(CntType* cnt);
00049 
00053         void Normalize();
00054 
00059         inline ParamType* GetParameter();
00066         virtual void Update(float dt);
00067 
00068         CNTRL_CLASS_NAME(CControllerMixer);
00069 };
00070 
00071 template<class CntType, class ParamType>
00072 CControllerMixer<CntType, ParamType>::CControllerMixer(const std::string& name) : CController(name)
00073 {
00074 }
00075 
00076 template<class CntType, class ParamType>
00077 CControllerMixer<CntType, ParamType>::~CControllerMixer()
00078 {
00079 }
00080 
00081 template<class CntType, class ParamType>
00082 void CControllerMixer<CntType, ParamType>::RegisterController(CntType* cnt, float* weight)
00083 {
00084         if(!m_controllers.empty()) {
00085                 if(cnt->GetParameter() != m_controllers[0]->GetParameter()) {
00086                         LOGErr("CControllerMixer::RegisterController - parameters don't match");
00087                         return;
00088                 }
00089         }
00090         cnt->SetPassive(true);
00091         m_controllers.push_back(std::make_pair(weight, cnt));
00092 }
00093 template<class CntType, class ParamType>
00094 void CControllerMixer<CntType, ParamType>::UnRegisterController(CntType* cnt)
00095 {
00096         for(size_t i = 0; i < m_controllers.size(); i++) {
00097                 if(m_controllers[i].second == cnt) {
00098                         cnt->SetPassive(false);
00099                         m_controllers.erase(m_controllers.begin() + i);
00100                         break;
00101                 }
00102         }
00103 }
00104 
00105 template<class CntType, class ParamType>
00106 void CControllerMixer<CntType, ParamType>::Normalize() 
00107 {
00108         float nTotalWeight = 0.0f;
00109         for(size_t i = 0; i < m_controllers.size(); i++) {
00110                 nTotalWeight += *m_controllers[i].first;
00111         }
00112 
00113         // Normalize
00114         for(size_t i = 0; i < m_controllers.size(); i++) {
00115                 *m_controllers[i].first /= nTotalWeight;
00116         }
00117 }
00118 
00119 template<class CntType, class ParamType>
00120 bool CControllerMixer<CntType, ParamType>::IsEmpty() 
00121 {
00122         return m_controllers.empty();
00123 }
00124 
00125 template<class CntType, class ParamType>
00126 ParamType* CControllerMixer<CntType, ParamType>::GetParameter()
00127 {
00128         return &m_accumulated_param;
00129 }
00130 
00131 /*
00132         Inherited
00133 */
00134 template<class CntType, class ParamType>
00135 void CControllerMixer<CntType, ParamType>::Update(float dt)
00136 {
00137         float weight_remaining = 1.0f;  // zbyvajici vaha, pokud nektery controller vypotrebuje vsechno (z 1.0f), na ostatni se jiz nedostane
00138         bool first = true;
00139         float curr_weight;
00140 
00141         bool first = true;
00142         for(size_t i = 0; i < m_controllers.size(); i++) {
00143                 if(weight_remaining < 0.0f) break;
00144 
00145                 std::pair<float*,CntType*>& curr = m_controllers[i];
00146 
00147                 // celkova vaha nesmi prekrocit 1
00148                 if(weight_remaining - *curr.first < 0.0f) {
00149                         curr_weight = weight_remaining;
00150                 } else {
00151                         curr_weight = *curr.first;
00152                 }
00153                 weight_remaining -= *curr.first;
00154                 //
00155 
00156                 if((*curr.first) <= 0.0f) continue;
00157                 curr.second->Update(dt);
00158                 
00159 
00160 
00161                 if(first) {     
00162                         m_accumulated_param = (*curr.second->GetParameter()) * (*curr.first);
00163                         first = false;
00164                 } else {
00165                         m_accumulated_param += (*curr.second->GetParameter()) * (*curr.first);
00166                 }
00167 
00168         }
00169         if(!m_controllers.empty() && first == false) {
00170                 *m_controllers[0].second->GetParameter() = m_accumulated_param;
00171         }
00172 }
00173 
00174 
00175 
00176 /*
00177         Private
00178 */
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188