reprap: Delete mongoose
[simavr] / examples / board_reprap / src / c3 / c3arcball.c
1 /*
2         c3arcball.c
3
4         Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
5
6         This file is part of simavr.
7
8         simavr is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 3 of the License, or
11         (at your option) any later version.
12
13         simavr is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with simavr.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <math.h>
23 #include "c3/c3arcball.h"
24
25
26 /**************************************** c3arcball_init_mat4() ****/
27 /* Takes as argument a c3mat4 to use instead of the internal rot  */
28
29 void
30 c3arcball_init_mat4(
31                 c3arcballp a,
32                 c3mat4p mtx )
33 {
34     c3arcball_init(a);
35     a->rot_ptr = mtx;
36 }
37
38
39 /**************************************** c3arcball_init_center() ****/
40 /* A constructor that accepts the screen center and arcball radius*/
41
42 void
43 c3arcball_init_center(
44                 c3arcballp a,
45                 const c3vec2 center,
46                 c3f radius )
47 {
48     c3arcball_init(a);
49     c3arcball_set_params(a, center, radius);
50 }
51
52
53 /************************************** c3arcball_set_params() ****/
54
55 void
56 c3arcball_set_params(
57                 c3arcballp a,
58                 const c3vec2 center,
59                 c3f radius)
60 {
61     a->center      = center;
62     a->radius      = radius;
63 }
64
65 /*************************************** c3arcball_init() **********/
66
67 void
68 c3arcball_init(
69                 c3arcballp a )
70 {
71     a->center = c3vec2f( 0.0, 0.0 );
72     a->radius         = 1.0;
73     a->q_now          = c3quat_identity();
74     a->rot_ptr          = &a->rot;
75     a->rot              = identity3D();
76     a->q_increment    = c3quat_identity();
77     a->rot_increment  = identity3D();
78     a->is_mouse_down  = false;
79     a->is_spinning    = false;
80     a->damp_factor    = 0.0;
81     a->zero_increment = true;
82 }
83
84 /*********************************** c3arcball_mouse_to_sphere() ****/
85
86 c3vec3
87 c3arcball_mouse_to_sphere(
88                 c3arcballp a,
89                 const c3vec2 p)
90 {
91     c3f mag;
92     c3vec2  v2 = c3vec2_divf(c3vec2_sub(p, a->center), a->radius);
93     c3vec3  v3 = c3vec3f( v2.n[0], v2.n[1], 0.0 );
94
95     mag = c3vec2_dot(v2, v2);
96
97     if ( mag > 1.0 )
98         v3 = c3vec3_normalize(v3);
99     else
100         v3.n[VZ] = (c3f) sqrt( 1.0 - mag );
101
102     /* Now we add constraints - X takes precedence over Y */
103     if ( a->constraint_x ) {
104         v3 = c3arcball_constrain_vector( v3, c3vec3f( 1.0, 0.0, 0.0 ));
105     } else if ( a->constraint_y ) {
106         v3 = c3arcball_constrain_vector( v3, c3vec3f( 0.0, 1.0, 0.0 ));
107         }
108
109     return v3;
110 }
111
112
113 /************************************ c3arcball_constrain_vector() ****/
114
115 c3vec3
116 c3arcball_constrain_vector(
117                 const c3vec3 vector,
118                 const c3vec3 axis)
119 {
120 //    return (vector - (vector * axis) * axis).normalize();
121     return vector;
122 }
123
124 /************************************ c3arcball_mouse_down() **********/
125
126 void
127 c3arcball_mouse_down(
128                 c3arcballp a,
129                 int x,
130                 int y)
131 {
132     a->down_pt = c3vec2f( (c3f)x, (c3f) y );
133     a->is_mouse_down = true;
134
135     a->q_increment   = c3quat_identity();
136     a->rot_increment = identity3D();
137     a->zero_increment = true;
138 }
139
140
141 /************************************ c3arcball_mouse_up() **********/
142
143 void
144 c3arcball_mouse_up(
145                 c3arcballp a)
146 {
147     a->q_now = c3quat_mul(a->q_drag, a->q_now);
148     a->is_mouse_down = false;
149 }
150
151
152 /********************************** c3arcball_mouse_motion() **********/
153
154 void
155 c3arcball_mouse_motion(
156                 c3arcballp a,
157                 int x,
158                 int y,
159                 int shift,
160                 int ctrl,
161                 int alt)
162 {
163     /* Set the X constraint if CONTROL key is pressed, Y if ALT key */
164         c3arcball_set_constraints(a, ctrl != 0, alt != 0 );
165
166     c3vec2 new_pt = c3vec2f( (c3f)x, (c3f) y );
167     c3vec3 v0 = c3arcball_mouse_to_sphere(a, a->down_pt );
168     c3vec3 v1 = c3arcball_mouse_to_sphere(a, new_pt );
169
170     c3vec3 cross = c3vec3_cross(v0, v1);
171
172     a->q_drag = c3quat_vec3(cross, c3vec3_dot(v0, v1));
173
174     //    *rot_ptr = (q_drag * q_now).to_mat4();
175     c3mat4 temp = c3quat_to_mat4(a->q_drag);
176     *a->rot_ptr = c3mat4_mul(a->rot_ptr, &temp);
177
178     a->down_pt = new_pt;
179
180     /* We keep a copy of the current incremental rotation (= q_drag) */
181     a->q_increment   = a->q_drag;
182     a->rot_increment = c3quat_to_mat4(a->q_increment);
183
184     c3arcball_set_constraints(a, false, false);
185
186         if (a->q_increment.s < .999999) {
187                 a->is_spinning = true;
188                 a->zero_increment = false;
189         } else {
190                 a->is_spinning = false;
191                 a->zero_increment = true;
192         }
193 }
194
195
196 /********************************** c3arcball_mouse_motion() **********/
197 #if 0
198 void
199 c3arcball_mouse_motion(
200                 c3arcballp a,
201                 int x,
202                 int y)
203 {
204     mouse_motion(x, y, 0, 0, 0);
205 }
206 #endif
207
208 /***************************** c3arcball_set_constraints() **********/
209
210 void
211 c3arcball_set_constraints(
212                 c3arcballp a,
213                 bool _constraint_x,
214                 bool _constraint_y)
215 {
216     a->constraint_x = _constraint_x;
217     a->constraint_y = _constraint_y;
218 }
219
220 /***************************** c3arcball_idle() *********************/
221
222 void
223 c3arcball_idle(
224                 c3arcballp a)
225 {
226         if (a->is_mouse_down) {
227                 a->is_spinning = false;
228                 a->zero_increment = true;
229         }
230
231         if (a->damp_factor < 1.0f)
232                 c3quat_scale_angle(&a->q_increment, 1.0f - a->damp_factor);
233
234         a->rot_increment = c3quat_to_mat4(a->q_increment);
235
236         if (a->q_increment.s >= .999999f) {
237                 a->is_spinning = false;
238                 a->zero_increment = true;
239         }
240 }
241
242
243 /************************ c3arcball_set_damping() *********************/
244
245 void
246 c3arcball_set_damping(
247                 c3arcballp a,
248                 c3f d)
249 {
250     a->damp_factor = d;
251 }
252
253
254