Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://visualizationlibrary.org */ 00005 /* */ 00006 /* Copyright (c) 2005-2010, Michele Bosi */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without modification, */ 00010 /* are permitted provided that the following conditions are met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, this */ 00013 /* list of conditions and the following disclaimer. */ 00014 /* */ 00015 /* - Redistributions in binary form must reproduce the above copyright notice, this */ 00016 /* list of conditions and the following disclaimer in the documentation and/or */ 00017 /* other materials provided with the distribution. */ 00018 /* */ 00019 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ 00020 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ 00021 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ 00022 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ 00023 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ 00024 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ 00025 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ 00026 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 00027 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ 00028 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00029 /* */ 00030 /**************************************************************************************/ 00031 00032 #ifndef CatmullRomInterpolator_INCLUDE_ONCE 00033 #define CatmullRomInterpolator_INCLUDE_ONCE 00034 00035 #include <vlCore/Interpolator.hpp> 00036 00037 namespace vl 00038 { 00045 template<typename T> 00046 class CatmullRomInterpolator: public Object 00047 { 00048 VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolator<typename T>, Object) 00049 00050 public: 00051 CatmullRomInterpolator() 00052 { 00053 VL_DEBUG_SET_OBJECT_NAME() 00054 } 00055 00056 CatmullRomInterpolator(const std::vector<T>& path): mPath(path) {} 00057 00059 void setupEndPoints(bool is_loop) 00060 { 00061 VL_CHECK(mPath.size()>=2) 00062 if (mPath.size()<2) 00063 return; 00064 00065 mCatmullRomSpline = mPath; 00066 00067 /* 00068 D-------C 00069 . | 00070 . | 00071 . | 00072 A-------B 00073 */ 00074 00075 if (is_loop) 00076 { 00077 T a = mCatmullRomSpline[0]; 00078 T b = mCatmullRomSpline[1]; 00079 T d = mCatmullRomSpline[mCatmullRomSpline.size()-1]; 00080 00081 mCatmullRomSpline.insert(mCatmullRomSpline.begin(),d); 00082 mCatmullRomSpline.push_back(a); 00083 mCatmullRomSpline.push_back(b); 00084 } 00085 else 00086 { 00087 T a = mCatmullRomSpline[0] + (mCatmullRomSpline[0] - mCatmullRomSpline[1]); 00088 T b = mCatmullRomSpline[mCatmullRomSpline.size()-1] + (mCatmullRomSpline[mCatmullRomSpline.size()-1] - mCatmullRomSpline[mCatmullRomSpline.size()-2]); 00089 mCatmullRomSpline.insert(mCatmullRomSpline.begin(),a); 00090 mCatmullRomSpline.push_back(b); 00091 } 00092 00093 } 00094 00096 T computePoint(float t) const 00097 { 00098 VL_CHECK(mCatmullRomSpline.size() >= 4) 00099 size_t size = mCatmullRomSpline.size()-2; 00100 t = clamp(t, 0.0f, 1.0f); 00101 if (t == 0.0f) 00102 return mCatmullRomSpline[1]; 00103 else 00104 if (t == 1.0f) 00105 return mCatmullRomSpline[ mCatmullRomSpline.size()-1-1 ]; 00106 else 00107 { 00108 int i = 1 + (int)((size-1)*t); 00109 int i0 = i-1; 00110 int i1 = i; 00111 int i2 = i+1; 00112 int i3 = i+2; 00113 VL_CHECK(i3<(int)mCatmullRomSpline.size()) 00114 float tt = (size-1)*t - int((size-1)*t); // frac generates rounding errors 00115 T p0 = mCatmullRomSpline[i0]; 00116 T p1 = mCatmullRomSpline[i1]; 00117 T p2 = mCatmullRomSpline[i2]; 00118 T p3 = mCatmullRomSpline[i3]; 00119 T p = ( (p1 * 2.0f) + (-p0 + p2) * tt + 00120 ( p0*2.0f - p1*5.0f + p2*4.0f - p3) * tt*tt + 00121 ( p0*-1 + p1*3.0f - p2*3.0f + p3) * tt*tt*tt ) * 0.5f; 00122 return p; 00123 } 00124 } 00125 00130 void setPath(const std::vector<T>& path) { mPath = path; } 00131 00133 const std::vector<T>& path() const { return mPath; } 00134 00136 std::vector<T>& path() { return mPath; } 00137 00138 protected: 00139 std::vector<T> mPath; 00140 std::vector<T> mCatmullRomSpline; 00141 }; 00142 00143 typedef CatmullRomInterpolator<float> CatmullRomInterpolatorFloat_T; 00144 typedef CatmullRomInterpolator<fvec2> CatmullRomInterpolatorFVec2_T; 00145 typedef CatmullRomInterpolator<fvec3> CatmullRomInterpolatorFVec3_T; 00146 typedef CatmullRomInterpolator<fvec4> CatmullRomInterpolatorFVec4_T; 00147 typedef CatmullRomInterpolator<double> CatmullRomInterpolatorDouble_T; 00148 typedef CatmullRomInterpolator<dvec2> CatmullRomInterpolatorDVec2_T; 00149 typedef CatmullRomInterpolator<dvec3> CatmullRomInterpolatorDVec3_T; 00150 typedef CatmullRomInterpolator<dvec4> CatmullRomInterpolatorDVec4_T; 00151 00153 class CatmullRomInterpolatorFVec4: public InterpolatorFVec4 00154 { 00155 VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorFVec4, InterpolatorFVec4) 00156 public: 00157 CatmullRomInterpolatorFVec4(): mInterpolator( new CatmullRomInterpolatorFVec4_T ) {} 00158 CatmullRomInterpolatorFVec4(const std::vector<fvec4>& path): mInterpolator( new CatmullRomInterpolatorFVec4_T(path) ) {} 00159 fvec4 computePoint(float t) const { return interpolator()->computePoint(t); } 00160 CatmullRomInterpolatorFVec4_T* interpolator() { return mInterpolator.get(); } 00161 const CatmullRomInterpolatorFVec4_T* interpolator() const { return mInterpolator.get(); } 00162 void setInterpolator(CatmullRomInterpolatorFVec4_T* interpolator) { mInterpolator = interpolator; } 00163 protected: 00164 ref<CatmullRomInterpolatorFVec4_T> mInterpolator; 00165 }; 00167 class CatmullRomInterpolatorFVec3: public InterpolatorFVec3 00168 { 00169 VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorFVec3, InterpolatorFVec3) 00170 public: 00171 CatmullRomInterpolatorFVec3(): mInterpolator( new CatmullRomInterpolatorFVec3_T ) {} 00172 CatmullRomInterpolatorFVec3(const std::vector<fvec3>& path): mInterpolator( new CatmullRomInterpolatorFVec3_T(path) ) {} 00173 fvec3 computePoint(float t) const { return interpolator()->computePoint(t); } 00174 CatmullRomInterpolatorFVec3_T* interpolator() { return mInterpolator.get(); } 00175 const CatmullRomInterpolatorFVec3_T* interpolator() const { return mInterpolator.get(); } 00176 void setInterpolator(CatmullRomInterpolatorFVec3_T* interpolator) { mInterpolator = interpolator; } 00177 protected: 00178 ref<CatmullRomInterpolatorFVec3_T> mInterpolator; 00179 }; 00181 class CatmullRomInterpolatorFVec2: public InterpolatorFVec2 00182 { 00183 VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorFVec2, InterpolatorFVec2) 00184 public: 00185 CatmullRomInterpolatorFVec2(): mInterpolator( new CatmullRomInterpolatorFVec2_T ) {} 00186 CatmullRomInterpolatorFVec2(const std::vector<fvec2>& path): mInterpolator( new CatmullRomInterpolatorFVec2_T(path) ) {} 00187 fvec2 computePoint(float t) const { return interpolator()->computePoint(t); } 00188 CatmullRomInterpolatorFVec2_T* interpolator() { return mInterpolator.get(); } 00189 const CatmullRomInterpolatorFVec2_T* interpolator() const { return mInterpolator.get(); } 00190 void setInterpolator(CatmullRomInterpolatorFVec2_T* interpolator) { mInterpolator = interpolator; } 00191 protected: 00192 ref<CatmullRomInterpolatorFVec2_T> mInterpolator; 00193 }; 00195 class CatmullRomInterpolatorFloat: public InterpolatorFloat 00196 { 00197 VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorFloat, InterpolatorFloat) 00198 public: 00199 CatmullRomInterpolatorFloat(): mInterpolator( new CatmullRomInterpolatorFloat_T ) {} 00200 CatmullRomInterpolatorFloat(const std::vector<float>& path): mInterpolator( new CatmullRomInterpolatorFloat_T(path) ) {} 00201 float computePoint(float t) const { return interpolator()->computePoint(t); } 00202 CatmullRomInterpolatorFloat_T* interpolator() { return mInterpolator.get(); } 00203 const CatmullRomInterpolatorFloat_T* interpolator() const { return mInterpolator.get(); } 00204 void setInterpolator(CatmullRomInterpolatorFloat_T* interpolator) { mInterpolator = interpolator; } 00205 protected: 00206 ref<CatmullRomInterpolatorFloat_T> mInterpolator; 00207 }; 00209 class CatmullRomInterpolatorDVec4: public InterpolatorDVec4 00210 { 00211 VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorDVec4, InterpolatorDVec4) 00212 public: 00213 CatmullRomInterpolatorDVec4(): mInterpolator( new CatmullRomInterpolatorDVec4_T ) {} 00214 CatmullRomInterpolatorDVec4(const std::vector<dvec4>& path): mInterpolator( new CatmullRomInterpolatorDVec4_T(path) ) {} 00215 dvec4 computePoint(float t) const { return interpolator()->computePoint(t); } 00216 CatmullRomInterpolatorDVec4_T* interpolator() { return mInterpolator.get(); } 00217 const CatmullRomInterpolatorDVec4_T* interpolator() const { return mInterpolator.get(); } 00218 void setInterpolator(CatmullRomInterpolatorDVec4_T* interpolator) { mInterpolator = interpolator; } 00219 protected: 00220 ref<CatmullRomInterpolatorDVec4_T> mInterpolator; 00221 }; 00223 class CatmullRomInterpolatorDVec3: public InterpolatorDVec3 00224 { 00225 VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorDVec3, InterpolatorDVec3) 00226 public: 00227 CatmullRomInterpolatorDVec3(): mInterpolator( new CatmullRomInterpolatorDVec3_T ) {} 00228 CatmullRomInterpolatorDVec3(const std::vector<dvec3>& path): mInterpolator( new CatmullRomInterpolatorDVec3_T(path) ) {} 00229 dvec3 computePoint(float t) const { return interpolator()->computePoint(t); } 00230 CatmullRomInterpolatorDVec3_T* interpolator() { return mInterpolator.get(); } 00231 const CatmullRomInterpolatorDVec3_T* interpolator() const { return mInterpolator.get(); } 00232 void setInterpolator(CatmullRomInterpolatorDVec3_T* interpolator) { mInterpolator = interpolator; } 00233 protected: 00234 ref<CatmullRomInterpolatorDVec3_T> mInterpolator; 00235 }; 00237 class CatmullRomInterpolatorDVec2: public InterpolatorDVec2 00238 { 00239 VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorDVec2, InterpolatorDVec2) 00240 public: 00241 CatmullRomInterpolatorDVec2(): mInterpolator( new CatmullRomInterpolatorDVec2_T ) {} 00242 CatmullRomInterpolatorDVec2(const std::vector<dvec2>& path): mInterpolator( new CatmullRomInterpolatorDVec2_T(path) ) {} 00243 dvec2 computePoint(float t) const { return interpolator()->computePoint(t); } 00244 CatmullRomInterpolatorDVec2_T* interpolator() { return mInterpolator.get(); } 00245 const CatmullRomInterpolatorDVec2_T* interpolator() const { return mInterpolator.get(); } 00246 void setInterpolator(CatmullRomInterpolatorDVec2_T* interpolator) { mInterpolator = interpolator; } 00247 protected: 00248 ref<CatmullRomInterpolatorDVec2_T> mInterpolator; 00249 }; 00251 class CatmullRomInterpolatorDouble: public InterpolatorDouble 00252 { 00253 VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorDouble, InterpolatorDouble) 00254 public: 00255 CatmullRomInterpolatorDouble(): mInterpolator( new CatmullRomInterpolatorDouble_T ) {} 00256 CatmullRomInterpolatorDouble(const std::vector<double>& path): mInterpolator( new CatmullRomInterpolatorDouble_T(path) ) {} 00257 double computePoint(float t) const { return interpolator()->computePoint(t); } 00258 CatmullRomInterpolatorDouble_T* interpolator() { return mInterpolator.get(); } 00259 const CatmullRomInterpolatorDouble_T* interpolator() const { return mInterpolator.get(); } 00260 void setInterpolator(CatmullRomInterpolatorDouble_T* interpolator) { mInterpolator = interpolator; } 00261 protected: 00262 ref<CatmullRomInterpolatorDouble_T> mInterpolator; 00263 }; 00264 } 00265 00266 #endif