#
root/OpenSceneGraph/trunk/include/osgAnimation/Interpolator
@
11009

Revision 11009, 9.2 kB (checked in by robert, 4 years ago) |
---|

Rev | Line | |
---|---|---|

[9093] | 1 | /* -*-c++-*- |

[10527] | 2 | * Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net> |

[9093] | 3 | * |

4 | * This library is open source and may be redistributed and/or modified under | |

5 | * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or | |

6 | * (at your option) any later version. The full license is in LICENSE file | |

7 | * included with this distribution, and on the openscenegraph.org website. | |

8 | * | |

9 | * This library is distributed in the hope that it will be useful, | |

10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |

11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |

12 | * OpenSceneGraph Public License for more details. | |

[10527] | 13 | * |

14 | * Authors: | |

15 | * Cedric Pinson <cedric.pinson@plopbyte.net> | |

16 | * Michael Platings <mplatings@pixelpower.com> | |

17 | */ | |

[9093] | 18 | |

[10877] | 19 | #ifndef OSGANIMATION_INTERPOLATOR |

20 | #define OSGANIMATION_INTERPOLATOR 1 | |

[9093] | 21 | |

[9531] | 22 | #include <osg/Notify> |

[9093] | 23 | #include <osgAnimation/Keyframe> |

24 | ||

25 | namespace osgAnimation | |

26 | { | |

27 | ||

28 | template <class TYPE, class KEY> | |

29 | class TemplateInterpolatorBase | |

30 | { | |

31 | public: | |

32 | typedef KEY KeyframeType; | |

33 | typedef TYPE UsingType; | |

34 | ||

35 | public: | |

36 | mutable int _lastKeyAccess; | |

37 | ||

38 | TemplateInterpolatorBase() : _lastKeyAccess(-1) {} | |

39 | ||

40 | void reset() { _lastKeyAccess = -1; } | |

41 | int getKeyIndexFromTime(const TemplateKeyframeContainer<KEY>& keys, float time) const | |

42 | { | |

43 | // todo use a cache | |

44 | int key_size = keys.size(); | |

[9531] | 45 | if (!key_size) { |

46 | osg::notify(osg::WARN) << "TemplateInterpolatorBase::getKeyIndexFromTime the container is empty, impossible to get key index from time" << std::endl;; | |

47 | return -1; | |

48 | } | |

[9093] | 49 | const TemplateKeyframe<KeyframeType>* keysVector = &keys.front(); |

[9531] | 50 | for (int i = 0; i < key_size-1; i++) |

[9093] | 51 | { |

52 | float time0 = keysVector[i].getTime(); | |

53 | float time1 = keysVector[i+1].getTime(); | |

[9456] | 54 | |

[9093] | 55 | if ( time >= time0 && time < time1 ) |

56 | { | |

57 | _lastKeyAccess = i; | |

58 | return i; | |

59 | } | |

60 | } | |

[9531] | 61 | osg::notify(osg::WARN) << time << " first key " << keysVector[0].getTime() << " last key " << keysVector[key_size-1].getTime() << std::endl; |

[9093] | 62 | return -1; |

63 | } | |

64 | }; | |

65 | ||

66 | ||

67 | template <class TYPE, class KEY=TYPE> | |

[10527] | 68 | class TemplateStepInterpolator : public TemplateInterpolatorBase<TYPE,KEY> |

69 | { | |

70 | public: | |

71 | ||

72 | TemplateStepInterpolator() {} | |

73 | void getValue(const TemplateKeyframeContainer<KEY>& keyframes, float time, TYPE& result) const | |

74 | { | |

75 | ||

76 | if (time >= keyframes.back().getTime()) | |

77 | { | |

78 | result = keyframes.back().getValue(); | |

79 | return; | |

80 | } | |

81 | else if (time <= keyframes.front().getTime()) | |

82 | { | |

83 | result = keyframes.front().getValue(); | |

84 | return; | |

85 | } | |

86 | ||

87 | int i = getKeyIndexFromTime(keyframes,time); | |

[10552] | 88 | result = keyframes[i].getValue(); |

[10527] | 89 | } |

90 | }; | |

91 | ||

92 | ||

93 | template <class TYPE, class KEY=TYPE> | |

[9093] | 94 | class TemplateLinearInterpolator : public TemplateInterpolatorBase<TYPE,KEY> |

95 | { | |

96 | public: | |

97 | ||

98 | TemplateLinearInterpolator() {} | |

99 | void getValue(const TemplateKeyframeContainer<KEY>& keyframes, float time, TYPE& result) const | |

100 | { | |

101 | ||

102 | if (time >= keyframes.back().getTime()) | |

103 | { | |

104 | result = keyframes.back().getValue(); | |

105 | return; | |

106 | } | |

107 | else if (time <= keyframes.front().getTime()) | |

108 | { | |

109 | result = keyframes.front().getValue(); | |

110 | return; | |

111 | } | |

112 | ||

113 | int i = getKeyIndexFromTime(keyframes,time); | |

114 | float blend = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() - keyframes[i].getTime()); | |

115 | const TYPE& v1 = keyframes[i].getValue(); | |

116 | const TYPE& v2 = keyframes[i+1].getValue(); | |

117 | result = v1*(1-blend) + v2*blend; | |

118 | } | |

119 | }; | |

120 | ||

121 | ||

122 | template <class TYPE, class KEY=TYPE> | |

123 | class TemplateSphericalLinearInterpolator : public TemplateInterpolatorBase<TYPE,KEY> | |

124 | { | |

125 | public: | |

126 | TemplateSphericalLinearInterpolator() {} | |

127 | void getValue(const TemplateKeyframeContainer<KEY>& keyframes, float time, TYPE& result) const | |

128 | { | |

129 | if (time >= keyframes.back().getTime()) | |

130 | { | |

131 | result = keyframes.back().getValue(); | |

132 | return; | |

133 | } | |

134 | else if (time <= keyframes.front().getTime()) | |

135 | { | |

136 | result = keyframes.front().getValue(); | |

137 | return; | |

138 | } | |

139 | ||

140 | int i = getKeyIndexFromTime(keyframes,time); | |

141 | float blend = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() - keyframes[i].getTime()); | |

142 | const TYPE& q1 = keyframes[i].getValue(); | |

143 | const TYPE& q2 = keyframes[i+1].getValue(); | |

144 | result.slerp(blend,q1,q2); | |

145 | } | |

146 | }; | |

147 | ||

148 | ||

149 | template <class TYPE, class KEY> | |

150 | class TemplateLinearPackedInterpolator : public TemplateInterpolatorBase<TYPE,KEY> | |

151 | { | |

152 | public: | |

153 | ||

154 | TemplateLinearPackedInterpolator() {} | |

155 | void getValue(const TemplateKeyframeContainer<KEY>& keyframes, float time, TYPE& result) const | |

156 | { | |

157 | if (time >= keyframes.back().getTime()) | |

158 | { | |

159 | keyframes.back().getValue().uncompress(keyframes.mScale, keyframes.mMin, result); | |

160 | return; | |

161 | } | |

162 | else if (time <= keyframes.front().getTime()) | |

163 | { | |

164 | keyframes.front().getValue().uncompress(keyframes.mScale, keyframes.mMin, result); | |

165 | return; | |

166 | } | |

167 | ||

168 | int i = getKeyIndexFromTime(keyframes,time); | |

169 | float blend = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() - keyframes[i].getTime()); | |

170 | TYPE v1,v2; | |

171 | keyframes[i].getValue().uncompress(keyframes.mScale, keyframes.mMin, v1); | |

172 | keyframes[i+1].getValue().uncompress(keyframes.mScale, keyframes.mMin, v2); | |

173 | result = v1*(1-blend) + v2*blend; | |

174 | } | |

175 | }; | |

176 | ||

177 | ||

178 | // http://en.wikipedia.org/wiki/B%C3%A9zier_curve | |

179 | template <class TYPE, class KEY=TYPE> | |

180 | class TemplateCubicBezierInterpolator : public TemplateInterpolatorBase<TYPE,KEY> | |

181 | { | |

182 | public: | |

183 | ||

184 | TemplateCubicBezierInterpolator() {} | |

185 | void getValue(const TemplateKeyframeContainer<KEY>& keyframes, float time, TYPE& result) const | |

186 | { | |

187 | ||

188 | if (time >= keyframes.back().getTime()) | |

189 | { | |

190 | result = keyframes.back().getValue().getPosition(); | |

191 | return; | |

192 | } | |

193 | else if (time <= keyframes.front().getTime()) | |

194 | { | |

195 | result = keyframes.front().getValue().getPosition(); | |

196 | return; | |

197 | } | |

198 | ||

199 | int i = getKeyIndexFromTime(keyframes,time); | |

200 | ||

201 | float t = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() - keyframes[i].getTime()); | |

202 | float one_minus_t = 1.0-t; | |

203 | float one_minus_t2 = one_minus_t * one_minus_t; | |

204 | float one_minus_t3 = one_minus_t2 * one_minus_t; | |

205 | float t2 = t * t; | |

206 | ||

207 | TYPE v0 = keyframes[i].getValue().getPosition() * one_minus_t3; | |

[11009] | 208 | TYPE v1 = keyframes[i].getValue().getControlPointIn() * (3.0 * t * one_minus_t2); |

209 | TYPE v2 = keyframes[i].getValue().getControlPointOut() * (3.0 * t2 * one_minus_t); | |

[9093] | 210 | TYPE v3 = keyframes[i+1].getValue().getPosition() * (t2 * t); |

211 | ||

212 | result = v0 + v1 + v2 + v3; | |

213 | } | |

214 | }; | |

215 | ||

[10527] | 216 | typedef TemplateStepInterpolator<double, double> DoubleStepInterpolator; |

217 | typedef TemplateStepInterpolator<float, float> FloatStepInterpolator; | |

218 | typedef TemplateStepInterpolator<osg::Vec2, osg::Vec2> Vec2StepInterpolator; | |

219 | typedef TemplateStepInterpolator<osg::Vec3, osg::Vec3> Vec3StepInterpolator; | |

220 | typedef TemplateStepInterpolator<osg::Vec3, Vec3Packed> Vec3PackedStepInterpolator; | |

221 | typedef TemplateStepInterpolator<osg::Vec4, osg::Vec4> Vec4StepInterpolator; | |

222 | typedef TemplateStepInterpolator<osg::Quat, osg::Quat> QuatStepInterpolator; | |

223 | ||

[9093] | 224 | typedef TemplateLinearInterpolator<double, double> DoubleLinearInterpolator; |

225 | typedef TemplateLinearInterpolator<float, float> FloatLinearInterpolator; | |

226 | typedef TemplateLinearInterpolator<osg::Vec2, osg::Vec2> Vec2LinearInterpolator; | |

227 | typedef TemplateLinearInterpolator<osg::Vec3, osg::Vec3> Vec3LinearInterpolator; | |

228 | typedef TemplateLinearInterpolator<osg::Vec3, Vec3Packed> Vec3PackedLinearInterpolator; | |

229 | typedef TemplateLinearInterpolator<osg::Vec4, osg::Vec4> Vec4LinearInterpolator; | |

230 | typedef TemplateSphericalLinearInterpolator<osg::Quat, osg::Quat> QuatSphericalLinearInterpolator; | |

[11009] | 231 | typedef TemplateLinearInterpolator<osg::Matrixf, osg::Matrixf> MatrixLinearInterpolator; |

[9093] | 232 | |

233 | typedef TemplateCubicBezierInterpolator<float, FloatCubicBezier > FloatCubicBezierInterpolator; | |

234 | typedef TemplateCubicBezierInterpolator<double, DoubleCubicBezier> DoubleCubicBezierInterpolator; | |

235 | typedef TemplateCubicBezierInterpolator<osg::Vec2, Vec2CubicBezier> Vec2CubicBezierInterpolator; | |

236 | typedef TemplateCubicBezierInterpolator<osg::Vec3, Vec3CubicBezier> Vec3CubicBezierInterpolator; | |

237 | typedef TemplateCubicBezierInterpolator<osg::Vec4, Vec4CubicBezier> Vec4CubicBezierInterpolator; | |

238 | ||

239 | } | |

240 | #endif |

**Note:**See TracBrowser for help on using the browser.