JK2eA
 All Classes Functions Variables
ControllerPriorityMixer.h
00001 #pragma once
00002 
00003 
00004 #include "Controller.h"
00005 #include <vector>
00006 #include <utility>
00007 #include <algorithm>
00008 
00017 template<class CntType, class ParamType>
00018 class CControllerPriorityMixer : public CController {
00019 protected:
00023         struct MIX_NODE {
00024                 CntType* controller;    
00025                 float*   weight;                
00026                 char     priority;              
00027 
00028                 bool operator>(const MIX_NODE& rNode) const 
00029                 {
00030                         return priority > rNode.priority;
00031                 }
00032                 bool operator<(const MIX_NODE& rNode) const 
00033                 {
00034                         return priority < rNode.priority;
00035                 }
00036                 bool operator==(const MIX_NODE& rNode) const 
00037                 {
00038                         return priority == rNode.priority;
00039                 }
00040         };
00041 
00042         std::vector<MIX_NODE> m_controllers;                    
00043         ParamType                         m_accumulated_param;          
00044                         
00045 
00046         
00047 public:
00052         CControllerPriorityMixer(const std::string& name);
00056         virtual ~CControllerPriorityMixer(void);
00061         inline bool IsEmpty();
00072         void RegisterController(CntType* cnt, float* weight, char priority);
00077         void UnRegisterController(CntType* cnt);
00081         void Normalize();
00082 
00087         inline ParamType* GetParameter();
00094         virtual void Update(float dt);
00095 
00096         CNTRL_CLASS_NAME(CControllerMixer);
00097 };
00098 
00099 template<class CntType, class ParamType>
00100 CControllerPriorityMixer<CntType, ParamType>::CControllerPriorityMixer(const std::string& name) : CController(name)
00101 {
00102 }
00103 
00104 template<class CntType, class ParamType>
00105 CControllerPriorityMixer<CntType, ParamType>::~CControllerPriorityMixer()
00106 {
00107 }
00108 
00109 template<class CntType, class ParamType>
00110 void CControllerPriorityMixer<CntType, ParamType>::RegisterController(CntType* cnt, float* weight, char priority)
00111 {
00112         if(!m_controllers.empty()) {
00113                 if(cnt->GetParameter() != m_controllers[0].controller->GetParameter()) {
00114                         LOGErr("CControllerPriorityMixer::RegisterController - parameters don't match");
00115                         return;
00116                 }
00117         }
00118 
00119         MIX_NODE new_node;
00120         cnt->SetPassive(true);
00121         new_node.controller = cnt;
00122         new_node.weight         = weight;
00123         new_node.priority       = priority;
00124 
00125         m_controllers.push_back(new_node);
00126 
00127         std::sort(m_controllers.begin(), m_controllers.end(), std::greater<MIX_NODE>());
00128 }
00129 template<class CntType, class ParamType>
00130 void CControllerPriorityMixer<CntType, ParamType>::UnRegisterController(CntType* cnt)
00131 {
00132         for(size_t i = 0; i < m_controllers.size(); i++) {
00133                 if(m_controllers[i].controller == cnt) {
00134                         cnt->SetPassive(false);
00135                         m_controllers.erase(m_controllers.begin() + i);
00136                         break;
00137                 }
00138         }
00139 }
00140 
00141 template<class CntType, class ParamType>
00142 void CControllerPriorityMixer<CntType, ParamType>::Normalize() 
00143 {
00144         float nTotalWeight = 0.0f;
00145         for(size_t i = 0; i < m_controllers.size(); i++) {
00146                 nTotalWeight += *m_controllers[i].first;
00147         }
00148 
00149         // Normalize
00150         for(size_t i = 0; i < m_controllers.size(); i++) {
00151                 *m_controllers[i].first /= nTotalWeight;
00152         }
00153 }
00154 
00155 template<class CntType, class ParamType>
00156 bool CControllerPriorityMixer<CntType, ParamType>::IsEmpty() 
00157 {
00158         return m_controllers.empty();
00159 }
00160 
00161 template<class CntType, class ParamType>
00162 ParamType* CControllerPriorityMixer<CntType, ParamType>::GetParameter()
00163 {
00164         return &m_accumulated_param;
00165 }
00166 
00167 /*
00168         Inherited
00169 */
00170 template<class CntType, class ParamType>
00171 void CControllerPriorityMixer<CntType, ParamType>::Update(float dt)
00172 {
00173         float weight_remaining = 1.0f;  // zbyvajici vaha, pokud nektery controller vypotrebuje vsechno (z 1.0f), na ostatni se jiz nedostane
00174         bool first = true;
00175         float curr_weight;
00176         
00177 
00178         for(size_t i = 0; i < m_controllers.size(); i++) {
00179                 if(weight_remaining < 0.0f) break;
00180 
00181                 MIX_NODE& curr = m_controllers[i];
00182 
00183                 // celkova vaha nesmi prekrocit 1
00184                 if(weight_remaining - *curr.weight < 0.0f) {
00185                         curr_weight = weight_remaining;
00186                 } else {
00187                         curr_weight = *curr.weight;
00188                 }
00189                 weight_remaining -= *curr.weight;
00190                 //
00191                 
00192                 if((*curr.weight) <= 0.0f) continue;
00193         
00194                 curr.controller->Update(dt);
00195                 
00196                 if(first) {     
00197                         m_accumulated_param = (*curr.controller->GetParameter()) * (curr_weight);
00198                         first = false;
00199                 } else {
00200                         m_accumulated_param += (*curr.controller->GetParameter()) * (curr_weight);
00201                 }
00202         }
00203         if(!m_controllers.empty() && first == false) {
00204                 *m_controllers[0].controller->GetParameter() = m_accumulated_param;
00205         }
00206 }
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217