added 3dengfx into the repo, probably not the correct version for this
[summerhack] / src / 3dengfx / src / gfx / controller.cpp
1 /*
2 This file is part of the graphics core library.
3
4 Copyright (c) 2004, 2005 John Tsiombikas <nuclear@siggraph.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 /* motion controllers (part of the animation system)
22  *
23  * Author: John Tsiombikas 2004
24  */
25
26 #include "3dengfx_config.h"
27
28 #include "controller.hpp"
29
30 MotionController::MotionController(ControllerClass ctype, TimelineMode mode) {
31         start_time = end_time = 0;
32         curve = 0;
33         time_mode = mode;
34         ctrl_type = ctype;
35
36         freq = ampl = 1.0f;
37         freq_func = ampl_func = 0;
38
39         slope = Vector3(1, 1, 1);
40
41         axis_flags = CTRL_XYZ;
42 }
43
44 MotionController::MotionController(Curve *curve, unsigned long start, unsigned long end, TimelineMode mode) {
45         this->curve = curve;
46         start_time = start;
47         end_time = end;
48         time_mode = mode;
49
50         ctrl_type = CTRL_CURVE;
51         freq = ampl = 1.0f;
52         freq_func = ampl_func = 0;
53
54         slope = Vector3(1, 1, 1);
55
56         axis_flags = CTRL_XYZ;
57 }
58
59 void MotionController::set_curve(Curve *curve) {
60         this->curve = curve;
61 }
62
63 void MotionController::set_sin_func(scalar_t freq, scalar_t ampl, scalar_t phase) {
64         this->freq = freq;
65         this->ampl = ampl;
66         this->phase = phase;
67 }
68
69 void MotionController::set_sin_func(scalar_t (*freq_func)(scalar_t), scalar_t (*ampl_func)(scalar_t)) {
70         this->freq_func = freq_func;
71         this->ampl_func = ampl_func;
72 }
73
74 void MotionController::set_origin(scalar_t orig) {
75         this->orig = Vector3(orig, orig, orig);
76 }
77
78 void MotionController::set_origin(const Vector3 &orig_vec) {
79         orig = orig_vec;
80 }
81
82 void MotionController::set_slope(scalar_t slope) {
83         this->slope = Vector3(slope, slope, slope);
84 }
85
86 void MotionController::set_slope(const Vector3 &slope_vec) {
87         slope = slope_vec;
88 }
89
90 void MotionController::set_timing(unsigned long start, unsigned long end) {
91         start_time = start;
92         end_time = end;
93 }
94
95 void MotionController::set_timeline_mode(TimelineMode tmode) {
96         time_mode = tmode;
97 }
98
99 void MotionController::set_controller_type(ControllerClass ctype) {
100         ctrl_type = ctype;
101 }
102
103 void MotionController::set_control_axis(unsigned int axis_flags) {
104         this->axis_flags = axis_flags;
105 }
106
107 Curve *MotionController::get_curve() {
108         return curve;
109 }
110
111 unsigned long MotionController::get_start_time() const {
112         return start_time;
113 }
114
115 unsigned long MotionController::get_end_time() const {
116         return end_time;
117 }
118
119 TimelineMode MotionController::get_timeline_mode() const {
120         return time_mode;
121 }
122
123 unsigned int MotionController::get_control_axis() const {
124         return axis_flags;
125 }
126
127
128 Vector3 MotionController::operator ()(unsigned long time) const {
129         time = get_timeline_time(time, start_time, end_time, time_mode);
130
131         double (*sinusoidal)(double);
132         sinusoidal = sin;
133         
134         switch(ctrl_type) {
135         case CTRL_CURVE:
136                 {
137                         scalar_t t = (scalar_t)(time - start_time) / (scalar_t)(end_time - start_time);
138                         Vector3 vec = (*curve)(t);
139                         if(!(axis_flags & CTRL_X)) vec.x = 0;
140                         if(!(axis_flags & CTRL_Y)) vec.y = 0;
141                         if(!(axis_flags & CTRL_Z)) vec.z = 0;
142                         return vec;
143                 }
144
145         case CTRL_COS:
146                 sinusoidal = cos;
147         case CTRL_SIN:
148                 {
149                         scalar_t t = (scalar_t)time / 1000.0f;
150                         scalar_t frequency = freq_func ? freq_func(t) : freq;
151                         scalar_t amplitude = ampl_func ? ampl_func(t) : ampl;
152                         scalar_t result = sinusoidal((phase + t) * frequency) * amplitude;
153
154                         Vector3 vec(0, 0, 0);
155                         if(axis_flags & CTRL_X) vec.x = result;
156                         if(axis_flags & CTRL_Y) vec.y = result;
157                         if(axis_flags & CTRL_Z) vec.z = result;
158                         return vec;
159                 }
160
161         case CTRL_LIN:
162                 {
163                         scalar_t t = (scalar_t)time / 1000.0f;
164                         Vector3 result = orig + slope * t;
165                         
166                         Vector3 vec(0, 0, 0);
167                         if(axis_flags & CTRL_X) vec.x = result.x;
168                         if(axis_flags & CTRL_Y) vec.y = result.y;
169                         if(axis_flags & CTRL_Z) vec.z = result.z;
170                         return vec;
171                 }
172         }
173         return Vector3();       // Should not happen
174 }