diff options
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/src/quat.c')
-rw-r--r-- | src/others/mimesh/libg3d-0.0.8/src/quat.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/src/quat.c b/src/others/mimesh/libg3d-0.0.8/src/quat.c new file mode 100644 index 0000000..384b956 --- /dev/null +++ b/src/others/mimesh/libg3d-0.0.8/src/quat.c | |||
@@ -0,0 +1,176 @@ | |||
1 | /* $Id:$ */ | ||
2 | |||
3 | /* | ||
4 | libg3d - 3D object loading library | ||
5 | |||
6 | Copyright (C) 2005-2009 Markus Dahms <mad@automagically.de> | ||
7 | |||
8 | This library is free software; you can redistribute it and/or | ||
9 | modify it under the terms of the GNU Lesser General Public | ||
10 | License as published by the Free Software Foundation; either | ||
11 | version 2.1 of the License, or (at your option) any later version. | ||
12 | |||
13 | This library 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 GNU | ||
16 | Lesser General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU Lesser General Public | ||
19 | License along with this library; if not, write to the Free Software | ||
20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * some parts based on "trackball.c" | ||
25 | * | ||
26 | * (c) Copyright 1993, 1994, Silicon Graphics, Inc. | ||
27 | * ALL RIGHTS RESERVED | ||
28 | * Permission to use, copy, modify, and distribute this software for | ||
29 | * any purpose and without fee is hereby granted, provided that the above | ||
30 | * copyright notice appear in all copies and that both the copyright notice | ||
31 | * and this permission notice appear in supporting documentation, and that | ||
32 | * the name of Silicon Graphics, Inc. not be used in advertising | ||
33 | * or publicity pertaining to distribution of the software without specific, | ||
34 | * written prior permission. | ||
35 | */ | ||
36 | |||
37 | #include <math.h> | ||
38 | |||
39 | #include <g3d/types.h> | ||
40 | #include <g3d/vector.h> | ||
41 | #include <g3d/matrix.h> | ||
42 | |||
43 | EAPI | ||
44 | gboolean g3d_quat_rotate(G3DQuat *q, G3DVector *axis, G3DFloat angle) | ||
45 | { | ||
46 | gint32 i; | ||
47 | |||
48 | g3d_vector_unify(axis + 0, axis + 1, axis + 2); | ||
49 | for(i = 0; i < 3; i ++) | ||
50 | q[i] = axis[i] * sin(angle / 2.0); | ||
51 | q[3] = cos(angle / 2.0); | ||
52 | |||
53 | return TRUE; | ||
54 | } | ||
55 | |||
56 | EAPI | ||
57 | gboolean g3d_quat_normalize(G3DQuat *q) | ||
58 | { | ||
59 | gint32 i; | ||
60 | G3DDouble div = 0; | ||
61 | |||
62 | for(i = 0; i < 4; i ++) | ||
63 | div += (q[i] * q[i]); | ||
64 | for(i = 0; i < 4; i ++) | ||
65 | q[i] /= div; | ||
66 | |||
67 | return TRUE; | ||
68 | } | ||
69 | |||
70 | EAPI | ||
71 | gboolean g3d_quat_add(G3DQuat *qr, G3DQuat *q1, G3DQuat *q2) | ||
72 | { | ||
73 | gint32 i; | ||
74 | G3DQuat tr[4], t1[4], t2[4], t3[4]; | ||
75 | |||
76 | for(i = 0; i < 3; i ++) | ||
77 | t1[i] = q1[i] * q2[3]; | ||
78 | for(i = 0; i < 3; i ++) | ||
79 | t2[i] = q2[i] * q1[3]; | ||
80 | g3d_vector_normal(q2[0], q2[1], q2[2], q1[0], q1[1], q1[2], | ||
81 | t3, t3 + 1, t3 + 2); | ||
82 | for(i = 0; i < 3; i ++) | ||
83 | tr[i] = t1[i] + t2[i] + t3[i]; | ||
84 | tr[3] = q1[3] * q2[3] - | ||
85 | (q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2]); | ||
86 | for(i = 0; i < 4; i ++) | ||
87 | qr[i] = tr[i]; | ||
88 | |||
89 | return TRUE; | ||
90 | } | ||
91 | |||
92 | static inline G3DVector trackball_projection(G3DVector x, G3DVector y, | ||
93 | G3DFloat r) | ||
94 | { | ||
95 | G3DDouble d, t; | ||
96 | |||
97 | d = sqrt(x * x + y * y); | ||
98 | if(d < (r * 0.70710678118654752440)) | ||
99 | return sqrt(r * r - d * d); | ||
100 | t = r / 1.41421356237309504880; | ||
101 | return t * t / d; | ||
102 | } | ||
103 | |||
104 | EAPI | ||
105 | gboolean g3d_quat_trackball(G3DQuat *q, G3DFloat x1, G3DFloat y1, | ||
106 | G3DFloat x2, G3DFloat y2, G3DFloat r) | ||
107 | { | ||
108 | G3DVector axis[3], z1, z2, dx, dy, dz; | ||
109 | G3DDouble angle, t; | ||
110 | |||
111 | if((x1 == x2) && (y1 == y2)) { | ||
112 | q[0] = q[1] = q[2] = 0.0; | ||
113 | q[3] = 1.0; | ||
114 | return TRUE; | ||
115 | } | ||
116 | |||
117 | z1 = trackball_projection(x1, y1, r); | ||
118 | z2 = trackball_projection(x2, y2, r); | ||
119 | |||
120 | g3d_vector_normal(x2, y2, z2, x1, y1, z1, axis, axis + 1, axis + 2); | ||
121 | |||
122 | dx = x1 - x2; | ||
123 | dy = y1 - y2; | ||
124 | dz = z1 - z2; | ||
125 | t = sqrt(dx * dx + dy * dy + dz * dz) / (2.0 * r); | ||
126 | t = CLAMP(t, -1.0, 1.0); | ||
127 | angle = 2.0 * asin(t); | ||
128 | |||
129 | return g3d_quat_rotate(q, axis, angle); | ||
130 | } | ||
131 | |||
132 | EAPI | ||
133 | gboolean g3d_quat_to_matrix(G3DQuat *q, G3DMatrix *matrix) | ||
134 | { | ||
135 | g3d_matrix_identity(matrix); | ||
136 | |||
137 | matrix[0 * 4 + 0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]); | ||
138 | matrix[0 * 4 + 1] = 2.0 * (q[0] * q[1] - q[2] * q[3]); | ||
139 | matrix[0 * 4 + 2] = 2.0 * (q[2] * q[0] + q[1] * q[3]); | ||
140 | |||
141 | matrix[1 * 4 + 0] = 2.0 * (q[0] * q[1] + q[2] * q[3]); | ||
142 | matrix[1 * 4 + 1] = 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]); | ||
143 | matrix[1 * 4 + 2] = 2.0 * (q[1] * q[2] - q[0] * q[3]); | ||
144 | |||
145 | matrix[2 * 4 + 0] = 2.0 * (q[2] * q[0] - q[1] * q[3]); | ||
146 | matrix[2 * 4 + 1] = 2.0 * (q[1] * q[2] + q[0] * q[3]); | ||
147 | matrix[2 * 4 + 2] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]); | ||
148 | |||
149 | return TRUE; | ||
150 | } | ||
151 | |||
152 | EAPI | ||
153 | gboolean g3d_quat_to_rotation_xyz(G3DQuat *q, G3DFloat *rx, G3DFloat *ry, | ||
154 | G3DFloat *rz) | ||
155 | { | ||
156 | G3DFloat t; | ||
157 | |||
158 | /* rx */ | ||
159 | t = 1 - 2 * (q[1] * q[1] + q[2] * q[2]); | ||
160 | if(t != 0) | ||
161 | *rx = atan(2 * (q[0] * q[1] + q[2] * q[3]) / t); | ||
162 | else | ||
163 | *rx = 0.0; | ||
164 | |||
165 | /* ry */ | ||
166 | *ry = asin(2 * (q[0] * q[2] - q[1] * q[3])); | ||
167 | |||
168 | /* rz */ | ||
169 | t = 1 - 2 * (q[2] * q[2] + q[3] * q[3]); | ||
170 | if(t != 0) | ||
171 | *rz = atan(2 * (q[0] * q[3] + q[1] * q[2]) / t); | ||
172 | else | ||
173 | *rz = 0.0; | ||
174 | |||
175 | return TRUE; | ||
176 | } | ||