JK2eA
 All Classes Functions Variables
CurveGraphBezier3.h
00001 #pragma once
00002 
00003 #include "CurveGraph.h"
00004 #include "Interpolators.h"
00005 
00009 template<class T>
00010 class CCurveGraphBezier3 : public CCurveGraph<T> {
00011 public:
00015         CCurveGraphBezier3()
00016         {
00017         }
00023         virtual T Interpolate(float time)
00024         {
00025                 
00026                 if(m_nodes.size() < 4 ) return m_nodes.back().value;
00027 
00028                 // hledani nod mezi kterymi lezi zadany time
00029                 int curr = -1, last = -1;
00030                 for(size_t i = 0; i < m_nodes.size(); i+=3) {
00031                         if(m_nodes[i].t >= time) {
00032                                 curr = i;
00033                                 break;
00034                         }
00035                         last = i;
00036                 }
00037                 m_currIndex = curr;
00038 
00039                 // interpolace
00040                 if(curr != -1 && last != -1) {
00041                         float local_time = (m_nodes[curr].t - m_nodes[last].t);
00042                         local_time =  (time -  m_nodes[last].t) / local_time;
00043                         local_time = Bezier3InterpolationInverse(time, local_time, 0.01f, m_nodes[last].t, m_nodes[last + 1].t, m_nodes[curr - 1].t, m_nodes[curr].t);
00044 
00045                         return Bezier3Interpolation(local_time, m_nodes[last].value, m_nodes[last + 1].value, m_nodes[curr - 1].value, m_nodes[curr].value);
00046                 
00047                 
00048                 } else if(curr == -1) {
00049                         return  m_nodes.back().value;
00050                 } else if(last == -1) {
00051                         return m_nodes.front().value;
00052                 }
00053 
00054                 
00055                 return T(0.0f);
00056         }
00057 
00066         virtual size_t AddNode(const float t, const T& value)
00067         {
00068                 GRAPH_NODE node;
00069                 GRAPH_NODE control_node;
00070                 node.t = t;
00071                 node.value = value;
00072                 control_node.value = value;
00073 
00074                 if(m_nodes.empty()) { // prvni
00075                         control_node.t = 10;    // random cislo, nezalezi na nem
00076                         m_nodes.push_back(node);
00077                         m_nodes.push_back(control_node);
00078                         return 0;
00079                 }
00080                 // je cas mensi nez u prvni node?
00081                 if(m_nodes.front() > t) {
00082                         node.t = m_nodes.front().t + 0.0001f;
00083                 }
00084                 if(m_nodes.size() == 2) { // posledni
00085                         
00086                         // vzdalenost 1. bodu a posledniho
00087                         float l = (node.t - m_nodes.front().t) / 2;
00088                         
00089                         // uprava control pointu prvni node
00090                         m_nodes[1].t = m_nodes.front().t + l;
00091                         
00092                         // control point posledni node
00093                         control_node.t = node.t - l;
00094                         m_nodes.push_back(control_node);
00095                         m_nodes.push_back(node);
00096                 }
00097 
00098                 // je cas vets nez u posledni node?
00099                 if(m_nodes.back() < t) {
00100                         node.t = m_nodes.back().t - 0.0001f;
00101                 }
00102 
00103                 // najdi misto kam patri (vzdy se vklada nalevo od nalezene nody)
00104                 for(size_t i = 3; i < m_nodes.size(); i+=3) {
00105                         if( node < m_nodes[i]) {
00106                                 /*
00107                                         Zpusob vkladani:
00108 
00109                                         1. vychozi stav
00110                                         (N0) --- (C0r) --- (C1l) --- (N1)
00111                                         2. rozhodneme se vlozit nalevo od N1
00112                                         3. pokud bychom pouzili hodnotu i = 3, vlozili bychom novy node za control point stareho, takze musime vlozit na i - 1
00113                                            coz je za C1l
00114                                         4. Korekce C1l tak, aby melo t = t Nnove 
00115 
00116                                 */
00117                                 float l = node.t - (node.t - m_nodes[i - 3].t) / 2.0f;
00118                                 float r = node.t + (m_nodes[i].t - node.t) / 2.0f; 
00119 
00120                                 // korekce C(i - 1)l
00121                                 if(m_nodes[i - 1].t < node.t) {
00122                                         m_nodes[i - 1].t = node.t + 0.0001f;
00123                                 }
00124                                 // korekce C(i - 2)r
00125                                 if(m_nodes[i - 2].t > node.t) {
00126                                         m_nodes[i - 2].t = node.t - 0.0001f;
00127                                 }
00128 
00129                                 m_nodes.insert(m_nodes.begin() + (i - 1), node);
00130                                 // L
00131                                 control_node.t = l;
00132                                 m_nodes.insert(m_nodes.begin() + (i - 1), control_node);
00133                                 // R
00134                                 control_node.t = r;
00135                                 m_nodes.insert(m_nodes.begin() + (i + 1), control_node);
00136 
00137 
00138                                 return i + 1;            
00139                         }
00140                 }
00141                 
00142 
00143                 return 0;
00144         }
00145 };