OSGInterpolationHelper.inl

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *           Copyright (C) 2008 by the OpenSG Forum                          *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038
00039 OSG_BEGIN_NAMESPACE
00040
00041 template<class KeyFieldT, class KeyValueFieldT, class ValueFieldT> inline
00042 void InterpolationHelper<KeyFieldT,
00043                          KeyValueFieldT,
00044                          ValueFieldT>::copyFirstValue(
00045                              const KeyFieldT      &,
00046                              const KeyValueFieldT &mfKeyValues,
00047                                    ValueFieldT    &fValue     )
00048 {
00049     fValue.setValue(mfKeyValues.front());
00050 }
00051
00052 template<class KeyFieldT, class KeyValueFieldT, class ValueFieldT> inline
00053 void InterpolationHelper<KeyFieldT,
00054                          KeyValueFieldT,
00055                          ValueFieldT>::copyLastValue (
00056                              const KeyFieldT      &,
00057                              const KeyValueFieldT &mfKeyValues,
00058                                    ValueFieldT    &fValue     )
00059 {
00060     fValue.setValue(mfKeyValues.back());
00061 }
00062
00063 // Orientation
00064
00065 template<> inline
00066 void InterpolationHelper<MFReal32,
00067                          MFQuaternion,
00068                          SFQuaternion>::lerp(
00069                              const UInt32        uiStopIndex,
00070                              const UInt32        uiStartIndex,
00071                              const Real32        rFraction,
00072                              const MFReal32     &mfKeys,
00073                              const MFQuaternion &mfKeyValues,
00074                                    SFQuaternion &fValue  )
00075 {
00076     if(osgAbs(mfKeys[uiStopIndex] - mfKeys[uiStartIndex]) < Eps)
00077     {
00078         return;
00079     }
00080     else
00081     {
00082         Quaternion result;
00083
00084         Real32 t =
00085             (rFraction           - mfKeys[uiStartIndex]) /
00086             (mfKeys[uiStopIndex] - mfKeys[uiStartIndex]);
00087
00088         result.slerpThis(mfKeyValues[uiStartIndex],
00089                          mfKeyValues[uiStopIndex],
00090                          t);
00091
00092         fValue.setValue(result);
00093     }
00094 }
00095
00096 // Position
00097
00098 template<> inline
00099 void InterpolationHelper<MFReal32,
00100                          MFVec3f,
00101                          SFVec3f>::lerp(
00102                              const UInt32    uiStopIndex,
00103                              const UInt32    uiStartIndex,
00104                              const Real32    rFraction,
00105                              const MFReal32 &mfKeys,
00106                              const MFVec3f  &mfKeyValues,
00107                                    SFVec3f  &fValue  )
00108 {
00109     if(osgAbs(mfKeys[uiStopIndex] - mfKeys[uiStartIndex]) < Eps)
00110     {
00111         return;
00112     }
00113     else
00114     {
00115         Vec3f vResult;
00116
00117         Real32 t =
00118             (rFraction           - mfKeys[uiStartIndex]) /
00119             (mfKeys[uiStopIndex] - mfKeys[uiStartIndex]);
00120
00121         vResult  = mfKeyValues[uiStopIndex ];
00122         vResult -= mfKeyValues[uiStartIndex];
00123         vResult *= t;
00124
00125         vResult += mfKeyValues[uiStartIndex];
00126
00127         fValue.setValue(vResult);
00128     }
00129 }
00130
00131
00132 // Coordinate
00133
00134 template<> inline
00135 void InterpolationHelper<MFReal32,
00136                          MFPnt3f,
00137                          MFPnt3f>::copyFirstValue(
00138                              const MFReal32 &mfKeys,
00139                              const MFPnt3f  &mfKeyValues,
00140                                    MFPnt3f  &fValue     )
00141 {
00142     UInt32 uiNumPoints = UInt32(mfKeyValues.size() / mfKeys.size());
00143
00144     MFPnt3f::const_iterator startIt = mfKeyValues.begin();
00145     MFPnt3f::const_iterator stopIt  = startIt + uiNumPoints;
00146
00147     fValue.clear();
00148     fValue.insert(fValue.begin(), startIt, stopIt);
00149 }
00150
00151 template<> inline
00152 void InterpolationHelper<MFReal32,
00153                          MFPnt3f,
00154                          MFPnt3f>::copyLastValue (
00155                              const MFReal32 &mfKeys,
00156                              const MFPnt3f  &mfKeyValues,
00157                                    MFPnt3f  &fValue     )
00158 {
00159     UInt32 uiNumPoints = UInt32(mfKeyValues.size() / mfKeys.size());
00160
00161     MFPnt3f::const_iterator stopIt  = mfKeyValues.end();
00162     MFPnt3f::const_iterator startIt = stopIt - uiNumPoints;
00163
00164     fValue.clear();
00165     fValue.insert(fValue.begin(), startIt, stopIt);
00166 }
00167
00168 template<> inline
00169 void InterpolationHelper<MFReal32,
00170                          MFPnt3f,
00171                          MFPnt3f>::lerp(
00172                              const UInt32    uiStopIndex,
00173                              const UInt32    uiStartIndex,
00174                              const Real32    rFraction,
00175                              const MFReal32 &mfKeys,
00176                              const MFPnt3f  &mfKeyValues,
00177                                    MFPnt3f  &fValue  )
00178 {
00179     if(osgAbs(mfKeys[uiStopIndex] - mfKeys[uiStartIndex]) < Eps)
00180     {
00181         return;
00182     }
00183     else
00184     {
00185         Pnt3f vResult;
00186
00187         UInt32 uiNumPoints = UInt32(mfKeyValues.size() / mfKeys.size());
00188
00189         Real32 t =
00190             (rFraction           - mfKeys[uiStartIndex]) /
00191             (mfKeys[uiStopIndex] - mfKeys[uiStartIndex]);
00192
00193         UInt32 uiIndex1    = uiStartIndex * uiNumPoints;
00194         UInt32 uiIndex2    = uiStopIndex  * uiNumPoints;
00195
00196         fValue.clear();
00197
00198         for(UInt32 i = 0; i < uiNumPoints; i++)
00199         {
00200             vResult  = mfKeyValues[uiIndex2];
00201             vResult -= mfKeyValues[uiIndex1].subZero();
00202             vResult *= t;
00203
00204             vResult += mfKeyValues[uiIndex1].subZero();
00205
00206             fValue.push_back(vResult);
00207
00208             ++uiIndex1;
00209             ++uiIndex2;
00210         }
00211     }
00212 }
00213
00214
00215 // Scalar
00216
00217 template<> inline
00218 void InterpolationHelper<MFReal32,
00219                          MFReal32,
00220                          SFReal32>::lerp(
00221                              const UInt32    uiStopIndex,
00222                              const UInt32    uiStartIndex,
00223                              const Real32    rFraction,
00224                              const MFReal32 &mfKeys,
00225                              const MFReal32 &mfKeyValues,
00226                                    SFReal32 &fValue  )
00227 {
00228     if(osgAbs(mfKeys[uiStopIndex] - mfKeys[uiStartIndex]) < Eps)
00229     {
00230         return;
00231     }
00232     else
00233     {
00234         Real32 vResult;
00235
00236         Real32 t =
00237             (rFraction           - mfKeys[uiStartIndex]) /
00238             (mfKeys[uiStopIndex] - mfKeys[uiStartIndex]);
00239
00240         vResult  = mfKeyValues[uiStopIndex ];
00241         vResult -= mfKeyValues[uiStartIndex];
00242         vResult *= t;
00243
00244         vResult += mfKeyValues[uiStartIndex];
00245
00246         fValue.setValue(vResult);
00247     }
00248 }
00249
00250
00251 // Interpolate
00252
00253 template<class KeyFieldT, class KeyValueFieldT, class ValueFieldT> inline
00254 void InterpolationHelper<KeyFieldT,
00255                          KeyValueFieldT,
00256                          ValueFieldT>::interpolate(
00257                              const Real32          rFraction,
00258                              const KeyFieldT      &mfKeys,
00259                              const KeyValueFieldT &mfKeyValues,
00260                                    ValueFieldT    &fValue     )
00261 {
00262     typename KeyFieldT::const_iterator keyIt;
00263
00264     if(mfKeys.size() == 0 || mfKeyValues.size() == 0)
00265     {
00266         return;
00267     }
00268
00269     keyIt = lower_bound(mfKeys.begin(),
00270                         mfKeys.end  (),
00271                         rFraction);
00272
00273     if(keyIt != mfKeys.end())
00274     {
00275         if(keyIt == mfKeys.begin())
00276         {
00277             copyFirstValue(mfKeys, mfKeyValues, fValue);
00278         }
00279         else
00280         {
00281             UInt32 uiStopIndex  = keyIt - mfKeys.begin();
00282             UInt32 uiStartIndex = uiStopIndex - 1;
00283
00284             lerp(uiStartIndex,
00285                  uiStopIndex,
00286                  rFraction,
00287                  mfKeys,
00288                  mfKeyValues,
00289                  fValue     );
00290         }
00291     }
00292     else
00293     {
00294         copyLastValue(mfKeys, mfKeyValues, fValue);
00295     }
00296 }
00297
00298 template<class KeyFieldT, class KeyValueFieldT, class ValueFieldT>
00299 template<class ResortIndexTypeT> inline
00300 void InterpolationHelper<KeyFieldT,
00301                          KeyValueFieldT,
00302                          ValueFieldT>::resortKeyValues(
00303                                    UInt32            uiNumKeys,
00304                                    UInt32            uiValuesPerKey,
00305                                    KeyValueFieldT   &mfKeyValues,
00306                              const ResortIndexTypeT &mfResortIndex)
00307 {
00308     KeyValueFieldT tmpKeyValues;
00309
00310     tmpKeyValues.resize(mfKeyValues.size());
00311
00312     UInt32 uiGlobalIdx = 0;
00313
00314     for(UInt32 i = 0; i < uiNumKeys; ++i)
00315     {
00316         UInt32 uiGlobalBase = i * uiValuesPerKey;
00317
00318         for(UInt32 j = 0; j < uiValuesPerKey; ++j, ++uiGlobalIdx)
00319         {
00320             tmpKeyValues[uiGlobalIdx] =
00321                 mfKeyValues[uiGlobalBase + mfResortIndex[j]];
00322         }
00323     }
00324
00325     mfKeyValues = tmpKeyValues;
00326 }
00327
00328 OSG_END_NAMESPACE