1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (C) 2004-2010 by The Allacrost Project
3 // All Rights Reserved
4 //
5 // This code is licensed under the GNU GPL version 2. It is free software
6 // and you may modify it and/or redistribute it under the terms of this license.
7 // See http://www.gnu.org/copyleft/gpl.html for details.
8 ///////////////////////////////////////////////////////////////////////////////
9
10 /** ****************************************************************************
11 *** \file interpolator.h
12 *** \author Raj Sharma, roos@allacrost.org
13 *** \brief Source file for Interpolator class
14 *** ***************************************************************************/
15
16 #include <cassert>
17 #include <cstdarg>
18 #include <math.h>
19
20 #include "video.h"
21
22 using namespace std;
23 using namespace hoa_utils;
24 using namespace hoa_video::private_video;
25
26 namespace hoa_video {
27
28 // Controls how slow the slow transform is. The greater the number, the "slower" it is. Should be greater than 1.0f
29 const float VIDEO_SLOW_TRANSFORM_POWER = 2.0f;
30
31 // Controls how fast the fast transform is. The smaller the number, the "faster" it is. Should be between 0.0f and 1.0f
32 const float VIDEO_FAST_TRANSFORM_POWER = 0.3f;
33
34
35
Interpolator()36 Interpolator::Interpolator() :
37 _method(VIDEO_INTERPOLATE_LINEAR),
38 _a(0.0f),
39 _b(0.0f),
40 _current_time(0),
41 _end_time(0),
42 _current_value(0.0f),
43 _finished(true) // no interpolation is in progress
44 {}
45
46
47
Start(float a,float b,uint32 milliseconds)48 void Interpolator::Start(float a, float b, uint32 milliseconds) {
49 if (_ValidMethod() == false) {
50 if (VIDEO_DEBUG)
51 cerr << "VIDEO WARNING: " << __FUNCTION__ << " was called when an invalid interpolation method was set" << endl;
52 return;
53 }
54
55 _a = a;
56 _b = b;
57
58 _current_time = 0;
59 _end_time = milliseconds;
60 _finished = false;
61
62 Update(0); // Do an initial update so that we have a valid value for GetValue()
63 }
64
65
66
SetMethod(InterpolationMethod method)67 void Interpolator::SetMethod(InterpolationMethod method) {
68 if (_finished == false) {
69 if (VIDEO_DEBUG)
70 cerr << "VIDEO WARNING: " << __FUNCTION__ << " was called when an interpolation was still in progress" << endl;
71 return;
72 }
73
74 _method = method;
75 if (_ValidMethod() == false) {
76 if (VIDEO_DEBUG)
77 cerr << "VIDEO WARNING: " << __FUNCTION__ << " was passed an invalid method argument" << endl;
78 }
79 }
80
81
82
Update(uint32 frame_time)83 void Interpolator::Update(uint32 frame_time) {
84 if (_ValidMethod() == false) {
85 if (VIDEO_DEBUG)
86 cerr << "VIDEO WARNING: " << __FUNCTION__ << " was called when an invalid method was set" << endl;
87 return;
88 }
89
90 // update current time
91 _current_time += frame_time;
92
93 if (_current_time > _end_time) {
94 _current_time = _end_time;
95 _finished = true;
96 }
97
98 // Calculate a value from 0.0f to 1.0f that tells how far we are in the interpolation
99 float progress;
100
101 if (_end_time == 0) {
102 progress = 1.0f;
103 }
104 else {
105 progress = static_cast<float>(_current_time) / static_cast<float>(_end_time);
106 }
107
108 if (progress > 1.0f) {
109 if (VIDEO_DEBUG)
110 cerr << "VIDEO WARNING: " << __FUNCTION__ << " calculated a progress value greater than 1.0" << endl;
111 progress = 1.0f;
112 }
113
114 // Apply a transformation based on the interpolation method
115 switch(_method) {
116 case VIDEO_INTERPOLATE_EASE:
117 progress = _EaseTransform(progress);
118 break;
119 case VIDEO_INTERPOLATE_SRCA:
120 progress = 0.0f;
121 break;
122 case VIDEO_INTERPOLATE_SRCB:
123 progress = 1.0f;
124 break;
125 case VIDEO_INTERPOLATE_FAST:
126 progress = _FastTransform(progress);
127 break;
128 case VIDEO_INTERPOLATE_SLOW:
129 progress = _SlowTransform(progress);
130 break;
131 case VIDEO_INTERPOLATE_LINEAR:
132 // Nothing to do, just use progress value as it is
133 break;
134 default:
135 if (VIDEO_DEBUG)
136 cerr << "VIDEO WARNING: " << __FUNCTION__ << " the current method did not match any supported methods" << endl;
137 return;
138 };
139
140 _current_value = Lerp(progress, _a, _b);
141 } // void Interpolator::Update(uint32 frame_time)
142
143
144
_FastTransform(float initial_value)145 float Interpolator::_FastTransform(float initial_value) {
146 return pow(initial_value, VIDEO_FAST_TRANSFORM_POWER);
147 }
148
149
150
_SlowTransform(float initial_value)151 float Interpolator::_SlowTransform(float initial_value) {
152 return pow(initial_value, VIDEO_SLOW_TRANSFORM_POWER);
153 }
154
155
156
_EaseTransform(float initial_value)157 float Interpolator::_EaseTransform(float initial_value) {
158 return 0.5f * (1.0f + sinf(UTILS_2PI * (initial_value - 0.25f)));
159 }
160
161 } // namespace hoa_video
162