2 ** License Applicability. Except to the extent portions of this file are
3 ** made subject to an alternative license as permitted in the SGI Free
4 ** Software License B, Version 1.1 (the "License"), the contents of this
5 ** file are subject only to the provisions of the License. You may not use
6 ** this file except in compliance with the License. You may obtain a copy
7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10 ** http://oss.sgi.com/projects/FreeB
12 ** Note that, as provided in the License, the Software is distributed on an
13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18 ** Original Code. The Original Code is: OpenGL Sample Implementation,
19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21 ** Copyright in any portions created by third parties is as indicated
22 ** elsewhere herein. All Rights Reserved.
24 ** Additional Notice Provisions: The application programming interfaces
25 ** established by SGI in conjunction with the Original Code are The
26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29 ** Window System(R) (Version 1.3), released October 19, 1998. This software
30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31 ** published by SGI, but has not been independently verified as being
32 ** compliant with the OpenGL(R) version 1.2.1 Specification.
34 ** $Date: 2006/05/01 16:01:17 $ $Revision: 1.6 $
35 ** $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libutil/project.c,v 1.6 2006/05/01 16:01:17 brianp Exp $
45 ** Make m an identity matrix
47 static void __gluMakeIdentityd(GLdouble m
[16])
49 m
[0+4*0] = 1; m
[0+4*1] = 0; m
[0+4*2] = 0; m
[0+4*3] = 0;
50 m
[1+4*0] = 0; m
[1+4*1] = 1; m
[1+4*2] = 0; m
[1+4*3] = 0;
51 m
[2+4*0] = 0; m
[2+4*1] = 0; m
[2+4*2] = 1; m
[2+4*3] = 0;
52 m
[3+4*0] = 0; m
[3+4*1] = 0; m
[3+4*2] = 0; m
[3+4*3] = 1;
55 static void __gluMakeIdentityf(GLfloat m
[16])
57 m
[0+4*0] = 1; m
[0+4*1] = 0; m
[0+4*2] = 0; m
[0+4*3] = 0;
58 m
[1+4*0] = 0; m
[1+4*1] = 1; m
[1+4*2] = 0; m
[1+4*3] = 0;
59 m
[2+4*0] = 0; m
[2+4*1] = 0; m
[2+4*2] = 1; m
[2+4*3] = 0;
60 m
[3+4*0] = 0; m
[3+4*1] = 0; m
[3+4*2] = 0; m
[3+4*3] = 1;
64 gluOrtho2D(GLdouble left
, GLdouble right
, GLdouble bottom
, GLdouble top
)
66 glOrtho(left
, right
, bottom
, top
, -1, 1);
69 #define __glPi 3.14159265358979323846
72 gluPerspective(GLdouble fovy
, GLdouble aspect
, GLdouble zNear
, GLdouble zFar
)
75 double sine
, cotangent
, deltaZ
;
76 double radians
= fovy
/ 2 * __glPi
/ 180;
78 deltaZ
= zFar
- zNear
;
80 if ((deltaZ
== 0) || (sine
== 0) || (aspect
== 0)) {
83 cotangent
= COS(radians
) / sine
;
85 __gluMakeIdentityd(&m
[0][0]);
86 m
[0][0] = cotangent
/ aspect
;
88 m
[2][2] = -(zFar
+ zNear
) / deltaZ
;
90 m
[3][2] = -2 * zNear
* zFar
/ deltaZ
;
92 glMultMatrixd(&m
[0][0]);
95 static void normalize(float v
[3])
99 r
= sqrt( v
[0]*v
[0] + v
[1]*v
[1] + v
[2]*v
[2] );
100 if (r
== 0.0) return;
107 static void cross(float v1
[3], float v2
[3], float result
[3])
109 result
[0] = v1
[1]*v2
[2] - v1
[2]*v2
[1];
110 result
[1] = v1
[2]*v2
[0] - v1
[0]*v2
[2];
111 result
[2] = v1
[0]*v2
[1] - v1
[1]*v2
[0];
115 gluLookAt(GLdouble eyex
, GLdouble eyey
, GLdouble eyez
, GLdouble centerx
,
116 GLdouble centery
, GLdouble centerz
, GLdouble upx
, GLdouble upy
,
119 float forward
[3], side
[3], up
[3];
122 forward
[0] = centerx
- eyex
;
123 forward
[1] = centery
- eyey
;
124 forward
[2] = centerz
- eyez
;
132 /* Side = forward x up */
133 cross(forward
, up
, side
);
136 /* Recompute up as: up = side x forward */
137 cross(side
, forward
, up
);
139 __gluMakeIdentityf(&m
[0][0]);
148 m
[0][2] = -forward
[0];
149 m
[1][2] = -forward
[1];
150 m
[2][2] = -forward
[2];
152 glMultMatrixf(&m
[0][0]);
153 glTranslated(-eyex
, -eyey
, -eyez
);
156 static void __gluMultMatrixVecd(const GLdouble matrix
[16], const GLdouble in
[4],
161 for (i
=0; i
<4; i
++) {
163 in
[0] * matrix
[0*4+i
] +
164 in
[1] * matrix
[1*4+i
] +
165 in
[2] * matrix
[2*4+i
] +
166 in
[3] * matrix
[3*4+i
];
171 ** Invert 4x4 matrix.
172 ** Contributed by David Moore (See Mesa bug #6748)
174 static int __gluInvertMatrixd(const GLdouble m
[16], GLdouble invOut
[16])
179 inv
[0] = m
[5]*m
[10]*m
[15] - m
[5]*m
[11]*m
[14] - m
[9]*m
[6]*m
[15]
180 + m
[9]*m
[7]*m
[14] + m
[13]*m
[6]*m
[11] - m
[13]*m
[7]*m
[10];
181 inv
[4] = -m
[4]*m
[10]*m
[15] + m
[4]*m
[11]*m
[14] + m
[8]*m
[6]*m
[15]
182 - m
[8]*m
[7]*m
[14] - m
[12]*m
[6]*m
[11] + m
[12]*m
[7]*m
[10];
183 inv
[8] = m
[4]*m
[9]*m
[15] - m
[4]*m
[11]*m
[13] - m
[8]*m
[5]*m
[15]
184 + m
[8]*m
[7]*m
[13] + m
[12]*m
[5]*m
[11] - m
[12]*m
[7]*m
[9];
185 inv
[12] = -m
[4]*m
[9]*m
[14] + m
[4]*m
[10]*m
[13] + m
[8]*m
[5]*m
[14]
186 - m
[8]*m
[6]*m
[13] - m
[12]*m
[5]*m
[10] + m
[12]*m
[6]*m
[9];
187 inv
[1] = -m
[1]*m
[10]*m
[15] + m
[1]*m
[11]*m
[14] + m
[9]*m
[2]*m
[15]
188 - m
[9]*m
[3]*m
[14] - m
[13]*m
[2]*m
[11] + m
[13]*m
[3]*m
[10];
189 inv
[5] = m
[0]*m
[10]*m
[15] - m
[0]*m
[11]*m
[14] - m
[8]*m
[2]*m
[15]
190 + m
[8]*m
[3]*m
[14] + m
[12]*m
[2]*m
[11] - m
[12]*m
[3]*m
[10];
191 inv
[9] = -m
[0]*m
[9]*m
[15] + m
[0]*m
[11]*m
[13] + m
[8]*m
[1]*m
[15]
192 - m
[8]*m
[3]*m
[13] - m
[12]*m
[1]*m
[11] + m
[12]*m
[3]*m
[9];
193 inv
[13] = m
[0]*m
[9]*m
[14] - m
[0]*m
[10]*m
[13] - m
[8]*m
[1]*m
[14]
194 + m
[8]*m
[2]*m
[13] + m
[12]*m
[1]*m
[10] - m
[12]*m
[2]*m
[9];
195 inv
[2] = m
[1]*m
[6]*m
[15] - m
[1]*m
[7]*m
[14] - m
[5]*m
[2]*m
[15]
196 + m
[5]*m
[3]*m
[14] + m
[13]*m
[2]*m
[7] - m
[13]*m
[3]*m
[6];
197 inv
[6] = -m
[0]*m
[6]*m
[15] + m
[0]*m
[7]*m
[14] + m
[4]*m
[2]*m
[15]
198 - m
[4]*m
[3]*m
[14] - m
[12]*m
[2]*m
[7] + m
[12]*m
[3]*m
[6];
199 inv
[10] = m
[0]*m
[5]*m
[15] - m
[0]*m
[7]*m
[13] - m
[4]*m
[1]*m
[15]
200 + m
[4]*m
[3]*m
[13] + m
[12]*m
[1]*m
[7] - m
[12]*m
[3]*m
[5];
201 inv
[14] = -m
[0]*m
[5]*m
[14] + m
[0]*m
[6]*m
[13] + m
[4]*m
[1]*m
[14]
202 - m
[4]*m
[2]*m
[13] - m
[12]*m
[1]*m
[6] + m
[12]*m
[2]*m
[5];
203 inv
[3] = -m
[1]*m
[6]*m
[11] + m
[1]*m
[7]*m
[10] + m
[5]*m
[2]*m
[11]
204 - m
[5]*m
[3]*m
[10] - m
[9]*m
[2]*m
[7] + m
[9]*m
[3]*m
[6];
205 inv
[7] = m
[0]*m
[6]*m
[11] - m
[0]*m
[7]*m
[10] - m
[4]*m
[2]*m
[11]
206 + m
[4]*m
[3]*m
[10] + m
[8]*m
[2]*m
[7] - m
[8]*m
[3]*m
[6];
207 inv
[11] = -m
[0]*m
[5]*m
[11] + m
[0]*m
[7]*m
[9] + m
[4]*m
[1]*m
[11]
208 - m
[4]*m
[3]*m
[9] - m
[8]*m
[1]*m
[7] + m
[8]*m
[3]*m
[5];
209 inv
[15] = m
[0]*m
[5]*m
[10] - m
[0]*m
[6]*m
[9] - m
[4]*m
[1]*m
[10]
210 + m
[4]*m
[2]*m
[9] + m
[8]*m
[1]*m
[6] - m
[8]*m
[2]*m
[5];
212 det
= m
[0]*inv
[0] + m
[1]*inv
[4] + m
[2]*inv
[8] + m
[3]*inv
[12];
218 for (i
= 0; i
< 16; i
++)
219 invOut
[i
] = inv
[i
] * det
;
224 static void __gluMultMatricesd(const GLdouble a
[16], const GLdouble b
[16],
229 for (i
= 0; i
< 4; i
++) {
230 for (j
= 0; j
< 4; j
++) {
241 gluProject(GLdouble objx
, GLdouble objy
, GLdouble objz
,
242 const GLdouble modelMatrix
[16],
243 const GLdouble projMatrix
[16],
244 const GLint viewport
[4],
245 GLdouble
*winx
, GLdouble
*winy
, GLdouble
*winz
)
254 __gluMultMatrixVecd(modelMatrix
, in
, out
);
255 __gluMultMatrixVecd(projMatrix
, out
, in
);
256 if (in
[3] == 0.0) return(GL_FALSE
);
260 /* Map x, y and z to range 0-1 */
261 in
[0] = in
[0] * 0.5 + 0.5;
262 in
[1] = in
[1] * 0.5 + 0.5;
263 in
[2] = in
[2] * 0.5 + 0.5;
265 /* Map x,y to viewport */
266 in
[0] = in
[0] * viewport
[2] + viewport
[0];
267 in
[1] = in
[1] * viewport
[3] + viewport
[1];
276 gluUnProject(GLdouble winx
, GLdouble winy
, GLdouble winz
,
277 const GLdouble modelMatrix
[16],
278 const GLdouble projMatrix
[16],
279 const GLint viewport
[4],
280 GLdouble
*objx
, GLdouble
*objy
, GLdouble
*objz
)
282 double finalMatrix
[16];
286 __gluMultMatricesd(modelMatrix
, projMatrix
, finalMatrix
);
287 if (!__gluInvertMatrixd(finalMatrix
, finalMatrix
)) return(GL_FALSE
);
294 /* Map x and y from window coordinates */
295 in
[0] = (in
[0] - viewport
[0]) / viewport
[2];
296 in
[1] = (in
[1] - viewport
[1]) / viewport
[3];
298 /* Map to range -1 to 1 */
299 in
[0] = in
[0] * 2 - 1;
300 in
[1] = in
[1] * 2 - 1;
301 in
[2] = in
[2] * 2 - 1;
303 __gluMultMatrixVecd(finalMatrix
, in
, out
);
304 if (out
[3] == 0.0) return(GL_FALSE
);
315 gluUnProject4(GLdouble winx
, GLdouble winy
, GLdouble winz
, GLdouble clipw
,
316 const GLdouble modelMatrix
[16],
317 const GLdouble projMatrix
[16],
318 const GLint viewport
[4],
319 GLclampd nearVal
, GLclampd farVal
,
320 GLdouble
*objx
, GLdouble
*objy
, GLdouble
*objz
,
323 double finalMatrix
[16];
327 __gluMultMatricesd(modelMatrix
, projMatrix
, finalMatrix
);
328 if (!__gluInvertMatrixd(finalMatrix
, finalMatrix
)) return(GL_FALSE
);
335 /* Map x and y from window coordinates */
336 in
[0] = (in
[0] - viewport
[0]) / viewport
[2];
337 in
[1] = (in
[1] - viewport
[1]) / viewport
[3];
338 in
[2] = (in
[2] - nearVal
) / (farVal
- nearVal
);
340 /* Map to range -1 to 1 */
341 in
[0] = in
[0] * 2 - 1;
342 in
[1] = in
[1] * 2 - 1;
343 in
[2] = in
[2] * 2 - 1;
345 __gluMultMatrixVecd(finalMatrix
, in
, out
);
346 if (out
[3] == 0.0) return(GL_FALSE
);
355 gluPickMatrix(GLdouble x
, GLdouble y
, GLdouble deltax
, GLdouble deltay
,
358 if (deltax
<= 0 || deltay
<= 0) {
362 /* Translate and scale the picked region to the entire window */
363 glTranslatef((viewport
[2] - 2 * (x
- viewport
[0])) / deltax
,
364 (viewport
[3] - 2 * (y
- viewport
[1])) / deltay
, 0);
365 glScalef(viewport
[2] / deltax
, viewport
[3] / deltay
, 1.0);