2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
38 ** Make m an identity matrix
40 static void __gluMakeIdentityd(GLdouble m
[16])
42 m
[0+4*0] = 1; m
[0+4*1] = 0; m
[0+4*2] = 0; m
[0+4*3] = 0;
43 m
[1+4*0] = 0; m
[1+4*1] = 1; m
[1+4*2] = 0; m
[1+4*3] = 0;
44 m
[2+4*0] = 0; m
[2+4*1] = 0; m
[2+4*2] = 1; m
[2+4*3] = 0;
45 m
[3+4*0] = 0; m
[3+4*1] = 0; m
[3+4*2] = 0; m
[3+4*3] = 1;
48 static void __gluMakeIdentityf(GLfloat m
[16])
50 m
[0+4*0] = 1; m
[0+4*1] = 0; m
[0+4*2] = 0; m
[0+4*3] = 0;
51 m
[1+4*0] = 0; m
[1+4*1] = 1; m
[1+4*2] = 0; m
[1+4*3] = 0;
52 m
[2+4*0] = 0; m
[2+4*1] = 0; m
[2+4*2] = 1; m
[2+4*3] = 0;
53 m
[3+4*0] = 0; m
[3+4*1] = 0; m
[3+4*2] = 0; m
[3+4*3] = 1;
57 gluOrtho2D(GLdouble left
, GLdouble right
, GLdouble bottom
, GLdouble top
)
59 glOrtho(left
, right
, bottom
, top
, -1, 1);
62 #define __glPi 3.14159265358979323846
65 gluPerspective(GLdouble fovy
, GLdouble aspect
, GLdouble zNear
, GLdouble zFar
)
68 double sine
, cotangent
, deltaZ
;
69 double radians
= fovy
/ 2 * __glPi
/ 180;
71 deltaZ
= zFar
- zNear
;
73 if ((deltaZ
== 0) || (sine
== 0) || (aspect
== 0)) {
76 cotangent
= COS(radians
) / sine
;
78 __gluMakeIdentityd(&m
[0][0]);
79 m
[0][0] = cotangent
/ aspect
;
81 m
[2][2] = -(zFar
+ zNear
) / deltaZ
;
83 m
[3][2] = -2 * zNear
* zFar
/ deltaZ
;
85 glMultMatrixd(&m
[0][0]);
88 static void normalize(float v
[3])
92 r
= sqrt( v
[0]*v
[0] + v
[1]*v
[1] + v
[2]*v
[2] );
100 static void cross(float v1
[3], float v2
[3], float result
[3])
102 result
[0] = v1
[1]*v2
[2] - v1
[2]*v2
[1];
103 result
[1] = v1
[2]*v2
[0] - v1
[0]*v2
[2];
104 result
[2] = v1
[0]*v2
[1] - v1
[1]*v2
[0];
108 gluLookAt(GLdouble eyex
, GLdouble eyey
, GLdouble eyez
, GLdouble centerx
,
109 GLdouble centery
, GLdouble centerz
, GLdouble upx
, GLdouble upy
,
112 float forward
[3], side
[3], up
[3];
115 forward
[0] = centerx
- eyex
;
116 forward
[1] = centery
- eyey
;
117 forward
[2] = centerz
- eyez
;
125 /* Side = forward x up */
126 cross(forward
, up
, side
);
129 /* Recompute up as: up = side x forward */
130 cross(side
, forward
, up
);
132 __gluMakeIdentityf(&m
[0][0]);
141 m
[0][2] = -forward
[0];
142 m
[1][2] = -forward
[1];
143 m
[2][2] = -forward
[2];
145 glMultMatrixf(&m
[0][0]);
146 glTranslated(-eyex
, -eyey
, -eyez
);
149 static void __gluMultMatrixVecd(const GLdouble matrix
[16], const GLdouble in
[4],
154 for (i
=0; i
<4; i
++) {
156 in
[0] * matrix
[0*4+i
] +
157 in
[1] * matrix
[1*4+i
] +
158 in
[2] * matrix
[2*4+i
] +
159 in
[3] * matrix
[3*4+i
];
164 ** Invert 4x4 matrix.
165 ** Contributed by David Moore (See Mesa bug #6748)
167 static int __gluInvertMatrixd(const GLdouble m
[16], GLdouble invOut
[16])
172 inv
[0] = m
[5]*m
[10]*m
[15] - m
[5]*m
[11]*m
[14] - m
[9]*m
[6]*m
[15]
173 + m
[9]*m
[7]*m
[14] + m
[13]*m
[6]*m
[11] - m
[13]*m
[7]*m
[10];
174 inv
[4] = -m
[4]*m
[10]*m
[15] + m
[4]*m
[11]*m
[14] + m
[8]*m
[6]*m
[15]
175 - m
[8]*m
[7]*m
[14] - m
[12]*m
[6]*m
[11] + m
[12]*m
[7]*m
[10];
176 inv
[8] = m
[4]*m
[9]*m
[15] - m
[4]*m
[11]*m
[13] - m
[8]*m
[5]*m
[15]
177 + m
[8]*m
[7]*m
[13] + m
[12]*m
[5]*m
[11] - m
[12]*m
[7]*m
[9];
178 inv
[12] = -m
[4]*m
[9]*m
[14] + m
[4]*m
[10]*m
[13] + m
[8]*m
[5]*m
[14]
179 - m
[8]*m
[6]*m
[13] - m
[12]*m
[5]*m
[10] + m
[12]*m
[6]*m
[9];
180 inv
[1] = -m
[1]*m
[10]*m
[15] + m
[1]*m
[11]*m
[14] + m
[9]*m
[2]*m
[15]
181 - m
[9]*m
[3]*m
[14] - m
[13]*m
[2]*m
[11] + m
[13]*m
[3]*m
[10];
182 inv
[5] = m
[0]*m
[10]*m
[15] - m
[0]*m
[11]*m
[14] - m
[8]*m
[2]*m
[15]
183 + m
[8]*m
[3]*m
[14] + m
[12]*m
[2]*m
[11] - m
[12]*m
[3]*m
[10];
184 inv
[9] = -m
[0]*m
[9]*m
[15] + m
[0]*m
[11]*m
[13] + m
[8]*m
[1]*m
[15]
185 - m
[8]*m
[3]*m
[13] - m
[12]*m
[1]*m
[11] + m
[12]*m
[3]*m
[9];
186 inv
[13] = m
[0]*m
[9]*m
[14] - m
[0]*m
[10]*m
[13] - m
[8]*m
[1]*m
[14]
187 + m
[8]*m
[2]*m
[13] + m
[12]*m
[1]*m
[10] - m
[12]*m
[2]*m
[9];
188 inv
[2] = m
[1]*m
[6]*m
[15] - m
[1]*m
[7]*m
[14] - m
[5]*m
[2]*m
[15]
189 + m
[5]*m
[3]*m
[14] + m
[13]*m
[2]*m
[7] - m
[13]*m
[3]*m
[6];
190 inv
[6] = -m
[0]*m
[6]*m
[15] + m
[0]*m
[7]*m
[14] + m
[4]*m
[2]*m
[15]
191 - m
[4]*m
[3]*m
[14] - m
[12]*m
[2]*m
[7] + m
[12]*m
[3]*m
[6];
192 inv
[10] = m
[0]*m
[5]*m
[15] - m
[0]*m
[7]*m
[13] - m
[4]*m
[1]*m
[15]
193 + m
[4]*m
[3]*m
[13] + m
[12]*m
[1]*m
[7] - m
[12]*m
[3]*m
[5];
194 inv
[14] = -m
[0]*m
[5]*m
[14] + m
[0]*m
[6]*m
[13] + m
[4]*m
[1]*m
[14]
195 - m
[4]*m
[2]*m
[13] - m
[12]*m
[1]*m
[6] + m
[12]*m
[2]*m
[5];
196 inv
[3] = -m
[1]*m
[6]*m
[11] + m
[1]*m
[7]*m
[10] + m
[5]*m
[2]*m
[11]
197 - m
[5]*m
[3]*m
[10] - m
[9]*m
[2]*m
[7] + m
[9]*m
[3]*m
[6];
198 inv
[7] = m
[0]*m
[6]*m
[11] - m
[0]*m
[7]*m
[10] - m
[4]*m
[2]*m
[11]
199 + m
[4]*m
[3]*m
[10] + m
[8]*m
[2]*m
[7] - m
[8]*m
[3]*m
[6];
200 inv
[11] = -m
[0]*m
[5]*m
[11] + m
[0]*m
[7]*m
[9] + m
[4]*m
[1]*m
[11]
201 - m
[4]*m
[3]*m
[9] - m
[8]*m
[1]*m
[7] + m
[8]*m
[3]*m
[5];
202 inv
[15] = m
[0]*m
[5]*m
[10] - m
[0]*m
[6]*m
[9] - m
[4]*m
[1]*m
[10]
203 + m
[4]*m
[2]*m
[9] + m
[8]*m
[1]*m
[6] - m
[8]*m
[2]*m
[5];
205 det
= m
[0]*inv
[0] + m
[1]*inv
[4] + m
[2]*inv
[8] + m
[3]*inv
[12];
211 for (i
= 0; i
< 16; i
++)
212 invOut
[i
] = inv
[i
] * det
;
217 static void __gluMultMatricesd(const GLdouble a
[16], const GLdouble b
[16],
222 for (i
= 0; i
< 4; i
++) {
223 for (j
= 0; j
< 4; j
++) {
234 gluProject(GLdouble objx
, GLdouble objy
, GLdouble objz
,
235 const GLdouble modelMatrix
[16],
236 const GLdouble projMatrix
[16],
237 const GLint viewport
[4],
238 GLdouble
*winx
, GLdouble
*winy
, GLdouble
*winz
)
247 __gluMultMatrixVecd(modelMatrix
, in
, out
);
248 __gluMultMatrixVecd(projMatrix
, out
, in
);
249 if (in
[3] == 0.0) return(GL_FALSE
);
253 /* Map x, y and z to range 0-1 */
254 in
[0] = in
[0] * 0.5 + 0.5;
255 in
[1] = in
[1] * 0.5 + 0.5;
256 in
[2] = in
[2] * 0.5 + 0.5;
258 /* Map x,y to viewport */
259 in
[0] = in
[0] * viewport
[2] + viewport
[0];
260 in
[1] = in
[1] * viewport
[3] + viewport
[1];
269 gluUnProject(GLdouble winx
, GLdouble winy
, GLdouble winz
,
270 const GLdouble modelMatrix
[16],
271 const GLdouble projMatrix
[16],
272 const GLint viewport
[4],
273 GLdouble
*objx
, GLdouble
*objy
, GLdouble
*objz
)
275 double finalMatrix
[16];
279 __gluMultMatricesd(modelMatrix
, projMatrix
, finalMatrix
);
280 if (!__gluInvertMatrixd(finalMatrix
, finalMatrix
)) return(GL_FALSE
);
287 /* Map x and y from window coordinates */
288 in
[0] = (in
[0] - viewport
[0]) / viewport
[2];
289 in
[1] = (in
[1] - viewport
[1]) / viewport
[3];
291 /* Map to range -1 to 1 */
292 in
[0] = in
[0] * 2 - 1;
293 in
[1] = in
[1] * 2 - 1;
294 in
[2] = in
[2] * 2 - 1;
296 __gluMultMatrixVecd(finalMatrix
, in
, out
);
297 if (out
[3] == 0.0) return(GL_FALSE
);
308 gluUnProject4(GLdouble winx
, GLdouble winy
, GLdouble winz
, GLdouble clipw
,
309 const GLdouble modelMatrix
[16],
310 const GLdouble projMatrix
[16],
311 const GLint viewport
[4],
312 GLclampd nearVal
, GLclampd farVal
,
313 GLdouble
*objx
, GLdouble
*objy
, GLdouble
*objz
,
316 double finalMatrix
[16];
320 __gluMultMatricesd(modelMatrix
, projMatrix
, finalMatrix
);
321 if (!__gluInvertMatrixd(finalMatrix
, finalMatrix
)) return(GL_FALSE
);
328 /* Map x and y from window coordinates */
329 in
[0] = (in
[0] - viewport
[0]) / viewport
[2];
330 in
[1] = (in
[1] - viewport
[1]) / viewport
[3];
331 in
[2] = (in
[2] - nearVal
) / (farVal
- nearVal
);
333 /* Map to range -1 to 1 */
334 in
[0] = in
[0] * 2 - 1;
335 in
[1] = in
[1] * 2 - 1;
336 in
[2] = in
[2] * 2 - 1;
338 __gluMultMatrixVecd(finalMatrix
, in
, out
);
339 if (out
[3] == 0.0) return(GL_FALSE
);
348 gluPickMatrix(GLdouble x
, GLdouble y
, GLdouble deltax
, GLdouble deltay
,
351 if (deltax
<= 0 || deltay
<= 0) {
355 /* Translate and scale the picked region to the entire window */
356 glTranslatef((viewport
[2] - 2 * (x
- viewport
[0])) / deltax
,
357 (viewport
[3] - 2 * (y
- viewport
[1])) / deltay
, 0);
358 glScalef(viewport
[2] / deltax
, viewport
[3] / deltay
, 1.0);