aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/src/quat.c
diff options
context:
space:
mode:
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.c176
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
43EAPI
44gboolean 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
56EAPI
57gboolean 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
70EAPI
71gboolean 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
92static 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
104EAPI
105gboolean 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
132EAPI
133gboolean 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
152EAPI
153gboolean 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}