|
JK2eA
|
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 };
1.8.0