1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3*c2c66affSColin Finck * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4*c2c66affSColin Finck *
5*c2c66affSColin Finck * Permission is hereby granted, free of charge, to any person obtaining a
6*c2c66affSColin Finck * copy of this software and associated documentation files (the "Software"),
7*c2c66affSColin Finck * to deal in the Software without restriction, including without limitation
8*c2c66affSColin Finck * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*c2c66affSColin Finck * and/or sell copies of the Software, and to permit persons to whom the
10*c2c66affSColin Finck * Software is furnished to do so, subject to the following conditions:
11*c2c66affSColin Finck *
12*c2c66affSColin Finck * The above copyright notice including the dates of first publication and
13*c2c66affSColin Finck * either this permission notice or a reference to
14*c2c66affSColin Finck * http://oss.sgi.com/projects/FreeB/
15*c2c66affSColin Finck * shall be included in all copies or substantial portions of the Software.
16*c2c66affSColin Finck *
17*c2c66affSColin Finck * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18*c2c66affSColin Finck * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*c2c66affSColin Finck * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20*c2c66affSColin Finck * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21*c2c66affSColin Finck * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22*c2c66affSColin Finck * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23*c2c66affSColin Finck * SOFTWARE.
24*c2c66affSColin Finck *
25*c2c66affSColin Finck * Except as contained in this notice, the name of Silicon Graphics, Inc.
26*c2c66affSColin Finck * shall not be used in advertising or otherwise to promote the sale, use or
27*c2c66affSColin Finck * other dealings in this Software without prior written authorization from
28*c2c66affSColin Finck * Silicon Graphics, Inc.
29*c2c66affSColin Finck */
30*c2c66affSColin Finck
31*c2c66affSColin Finck #include "gluos.h"
32*c2c66affSColin Finck #include <math.h>
33*c2c66affSColin Finck #include <GL/gl.h>
34*c2c66affSColin Finck //#include <GL/glu.h>
35*c2c66affSColin Finck #include "gluint.h"
36*c2c66affSColin Finck
37*c2c66affSColin Finck /*
38*c2c66affSColin Finck ** Make m an identity matrix
39*c2c66affSColin Finck */
__gluMakeIdentityd(GLdouble m[16])40*c2c66affSColin Finck static void __gluMakeIdentityd(GLdouble m[16])
41*c2c66affSColin Finck {
42*c2c66affSColin Finck m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
43*c2c66affSColin Finck m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
44*c2c66affSColin Finck m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
45*c2c66affSColin Finck m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
46*c2c66affSColin Finck }
47*c2c66affSColin Finck
__gluMakeIdentityf(GLfloat m[16])48*c2c66affSColin Finck static void __gluMakeIdentityf(GLfloat m[16])
49*c2c66affSColin Finck {
50*c2c66affSColin Finck m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
51*c2c66affSColin Finck m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
52*c2c66affSColin Finck m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
53*c2c66affSColin Finck m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
54*c2c66affSColin Finck }
55*c2c66affSColin Finck
56*c2c66affSColin Finck void GLAPIENTRY
gluOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top)57*c2c66affSColin Finck gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
58*c2c66affSColin Finck {
59*c2c66affSColin Finck glOrtho(left, right, bottom, top, -1, 1);
60*c2c66affSColin Finck }
61*c2c66affSColin Finck
62*c2c66affSColin Finck #define __glPi 3.14159265358979323846
63*c2c66affSColin Finck
64*c2c66affSColin Finck void GLAPIENTRY
gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar)65*c2c66affSColin Finck gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
66*c2c66affSColin Finck {
67*c2c66affSColin Finck GLdouble m[4][4];
68*c2c66affSColin Finck double sine, cotangent, deltaZ;
69*c2c66affSColin Finck double radians = fovy / 2 * __glPi / 180;
70*c2c66affSColin Finck
71*c2c66affSColin Finck deltaZ = zFar - zNear;
72*c2c66affSColin Finck sine = sin(radians);
73*c2c66affSColin Finck if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
74*c2c66affSColin Finck return;
75*c2c66affSColin Finck }
76*c2c66affSColin Finck cotangent = COS(radians) / sine;
77*c2c66affSColin Finck
78*c2c66affSColin Finck __gluMakeIdentityd(&m[0][0]);
79*c2c66affSColin Finck m[0][0] = cotangent / aspect;
80*c2c66affSColin Finck m[1][1] = cotangent;
81*c2c66affSColin Finck m[2][2] = -(zFar + zNear) / deltaZ;
82*c2c66affSColin Finck m[2][3] = -1;
83*c2c66affSColin Finck m[3][2] = -2 * zNear * zFar / deltaZ;
84*c2c66affSColin Finck m[3][3] = 0;
85*c2c66affSColin Finck glMultMatrixd(&m[0][0]);
86*c2c66affSColin Finck }
87*c2c66affSColin Finck
normalize(float v[3])88*c2c66affSColin Finck static void normalize(float v[3])
89*c2c66affSColin Finck {
90*c2c66affSColin Finck float r;
91*c2c66affSColin Finck
92*c2c66affSColin Finck r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
93*c2c66affSColin Finck if (r == 0.0) return;
94*c2c66affSColin Finck
95*c2c66affSColin Finck v[0] /= r;
96*c2c66affSColin Finck v[1] /= r;
97*c2c66affSColin Finck v[2] /= r;
98*c2c66affSColin Finck }
99*c2c66affSColin Finck
cross(float v1[3],float v2[3],float result[3])100*c2c66affSColin Finck static void cross(float v1[3], float v2[3], float result[3])
101*c2c66affSColin Finck {
102*c2c66affSColin Finck result[0] = v1[1]*v2[2] - v1[2]*v2[1];
103*c2c66affSColin Finck result[1] = v1[2]*v2[0] - v1[0]*v2[2];
104*c2c66affSColin Finck result[2] = v1[0]*v2[1] - v1[1]*v2[0];
105*c2c66affSColin Finck }
106*c2c66affSColin Finck
107*c2c66affSColin Finck void GLAPIENTRY
gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz)108*c2c66affSColin Finck gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
109*c2c66affSColin Finck GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
110*c2c66affSColin Finck GLdouble upz)
111*c2c66affSColin Finck {
112*c2c66affSColin Finck float forward[3], side[3], up[3];
113*c2c66affSColin Finck GLfloat m[4][4];
114*c2c66affSColin Finck
115*c2c66affSColin Finck forward[0] = centerx - eyex;
116*c2c66affSColin Finck forward[1] = centery - eyey;
117*c2c66affSColin Finck forward[2] = centerz - eyez;
118*c2c66affSColin Finck
119*c2c66affSColin Finck up[0] = upx;
120*c2c66affSColin Finck up[1] = upy;
121*c2c66affSColin Finck up[2] = upz;
122*c2c66affSColin Finck
123*c2c66affSColin Finck normalize(forward);
124*c2c66affSColin Finck
125*c2c66affSColin Finck /* Side = forward x up */
126*c2c66affSColin Finck cross(forward, up, side);
127*c2c66affSColin Finck normalize(side);
128*c2c66affSColin Finck
129*c2c66affSColin Finck /* Recompute up as: up = side x forward */
130*c2c66affSColin Finck cross(side, forward, up);
131*c2c66affSColin Finck
132*c2c66affSColin Finck __gluMakeIdentityf(&m[0][0]);
133*c2c66affSColin Finck m[0][0] = side[0];
134*c2c66affSColin Finck m[1][0] = side[1];
135*c2c66affSColin Finck m[2][0] = side[2];
136*c2c66affSColin Finck
137*c2c66affSColin Finck m[0][1] = up[0];
138*c2c66affSColin Finck m[1][1] = up[1];
139*c2c66affSColin Finck m[2][1] = up[2];
140*c2c66affSColin Finck
141*c2c66affSColin Finck m[0][2] = -forward[0];
142*c2c66affSColin Finck m[1][2] = -forward[1];
143*c2c66affSColin Finck m[2][2] = -forward[2];
144*c2c66affSColin Finck
145*c2c66affSColin Finck glMultMatrixf(&m[0][0]);
146*c2c66affSColin Finck glTranslated(-eyex, -eyey, -eyez);
147*c2c66affSColin Finck }
148*c2c66affSColin Finck
__gluMultMatrixVecd(const GLdouble matrix[16],const GLdouble in[4],GLdouble out[4])149*c2c66affSColin Finck static void __gluMultMatrixVecd(const GLdouble matrix[16], const GLdouble in[4],
150*c2c66affSColin Finck GLdouble out[4])
151*c2c66affSColin Finck {
152*c2c66affSColin Finck int i;
153*c2c66affSColin Finck
154*c2c66affSColin Finck for (i=0; i<4; i++) {
155*c2c66affSColin Finck out[i] =
156*c2c66affSColin Finck in[0] * matrix[0*4+i] +
157*c2c66affSColin Finck in[1] * matrix[1*4+i] +
158*c2c66affSColin Finck in[2] * matrix[2*4+i] +
159*c2c66affSColin Finck in[3] * matrix[3*4+i];
160*c2c66affSColin Finck }
161*c2c66affSColin Finck }
162*c2c66affSColin Finck
163*c2c66affSColin Finck /*
164*c2c66affSColin Finck ** Invert 4x4 matrix.
165*c2c66affSColin Finck ** Contributed by David Moore (See Mesa bug #6748)
166*c2c66affSColin Finck */
__gluInvertMatrixd(const GLdouble m[16],GLdouble invOut[16])167*c2c66affSColin Finck static int __gluInvertMatrixd(const GLdouble m[16], GLdouble invOut[16])
168*c2c66affSColin Finck {
169*c2c66affSColin Finck double inv[16], det;
170*c2c66affSColin Finck int i;
171*c2c66affSColin Finck
172*c2c66affSColin Finck inv[0] = m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15]
173*c2c66affSColin Finck + m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10];
174*c2c66affSColin Finck inv[4] = -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15]
175*c2c66affSColin Finck - m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10];
176*c2c66affSColin Finck inv[8] = m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15]
177*c2c66affSColin Finck + m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9];
178*c2c66affSColin Finck inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14]
179*c2c66affSColin Finck - m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9];
180*c2c66affSColin Finck inv[1] = -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15]
181*c2c66affSColin Finck - m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10];
182*c2c66affSColin Finck inv[5] = m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15]
183*c2c66affSColin Finck + m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10];
184*c2c66affSColin Finck inv[9] = -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15]
185*c2c66affSColin Finck - m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9];
186*c2c66affSColin Finck inv[13] = m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14]
187*c2c66affSColin Finck + m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9];
188*c2c66affSColin Finck inv[2] = m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15]
189*c2c66affSColin Finck + m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6];
190*c2c66affSColin Finck inv[6] = -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15]
191*c2c66affSColin Finck - m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6];
192*c2c66affSColin Finck inv[10] = m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15]
193*c2c66affSColin Finck + m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5];
194*c2c66affSColin Finck inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14]
195*c2c66affSColin Finck - m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5];
196*c2c66affSColin Finck inv[3] = -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11]
197*c2c66affSColin Finck - m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6];
198*c2c66affSColin Finck inv[7] = m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11]
199*c2c66affSColin Finck + m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6];
200*c2c66affSColin Finck inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11]
201*c2c66affSColin Finck - m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5];
202*c2c66affSColin Finck inv[15] = m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10]
203*c2c66affSColin Finck + m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5];
204*c2c66affSColin Finck
205*c2c66affSColin Finck det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12];
206*c2c66affSColin Finck if (det == 0)
207*c2c66affSColin Finck return GL_FALSE;
208*c2c66affSColin Finck
209*c2c66affSColin Finck det = 1.0 / det;
210*c2c66affSColin Finck
211*c2c66affSColin Finck for (i = 0; i < 16; i++)
212*c2c66affSColin Finck invOut[i] = inv[i] * det;
213*c2c66affSColin Finck
214*c2c66affSColin Finck return GL_TRUE;
215*c2c66affSColin Finck }
216*c2c66affSColin Finck
__gluMultMatricesd(const GLdouble a[16],const GLdouble b[16],GLdouble r[16])217*c2c66affSColin Finck static void __gluMultMatricesd(const GLdouble a[16], const GLdouble b[16],
218*c2c66affSColin Finck GLdouble r[16])
219*c2c66affSColin Finck {
220*c2c66affSColin Finck int i, j;
221*c2c66affSColin Finck
222*c2c66affSColin Finck for (i = 0; i < 4; i++) {
223*c2c66affSColin Finck for (j = 0; j < 4; j++) {
224*c2c66affSColin Finck r[i*4+j] =
225*c2c66affSColin Finck a[i*4+0]*b[0*4+j] +
226*c2c66affSColin Finck a[i*4+1]*b[1*4+j] +
227*c2c66affSColin Finck a[i*4+2]*b[2*4+j] +
228*c2c66affSColin Finck a[i*4+3]*b[3*4+j];
229*c2c66affSColin Finck }
230*c2c66affSColin Finck }
231*c2c66affSColin Finck }
232*c2c66affSColin Finck
233*c2c66affSColin Finck GLint GLAPIENTRY
gluProject(GLdouble objx,GLdouble objy,GLdouble objz,const GLdouble modelMatrix[16],const GLdouble projMatrix[16],const GLint viewport[4],GLdouble * winx,GLdouble * winy,GLdouble * winz)234*c2c66affSColin Finck gluProject(GLdouble objx, GLdouble objy, GLdouble objz,
235*c2c66affSColin Finck const GLdouble modelMatrix[16],
236*c2c66affSColin Finck const GLdouble projMatrix[16],
237*c2c66affSColin Finck const GLint viewport[4],
238*c2c66affSColin Finck GLdouble *winx, GLdouble *winy, GLdouble *winz)
239*c2c66affSColin Finck {
240*c2c66affSColin Finck double in[4];
241*c2c66affSColin Finck double out[4];
242*c2c66affSColin Finck
243*c2c66affSColin Finck in[0]=objx;
244*c2c66affSColin Finck in[1]=objy;
245*c2c66affSColin Finck in[2]=objz;
246*c2c66affSColin Finck in[3]=1.0;
247*c2c66affSColin Finck __gluMultMatrixVecd(modelMatrix, in, out);
248*c2c66affSColin Finck __gluMultMatrixVecd(projMatrix, out, in);
249*c2c66affSColin Finck if (in[3] == 0.0) return(GL_FALSE);
250*c2c66affSColin Finck in[0] /= in[3];
251*c2c66affSColin Finck in[1] /= in[3];
252*c2c66affSColin Finck in[2] /= in[3];
253*c2c66affSColin Finck /* Map x, y and z to range 0-1 */
254*c2c66affSColin Finck in[0] = in[0] * 0.5 + 0.5;
255*c2c66affSColin Finck in[1] = in[1] * 0.5 + 0.5;
256*c2c66affSColin Finck in[2] = in[2] * 0.5 + 0.5;
257*c2c66affSColin Finck
258*c2c66affSColin Finck /* Map x,y to viewport */
259*c2c66affSColin Finck in[0] = in[0] * viewport[2] + viewport[0];
260*c2c66affSColin Finck in[1] = in[1] * viewport[3] + viewport[1];
261*c2c66affSColin Finck
262*c2c66affSColin Finck *winx=in[0];
263*c2c66affSColin Finck *winy=in[1];
264*c2c66affSColin Finck *winz=in[2];
265*c2c66affSColin Finck return(GL_TRUE);
266*c2c66affSColin Finck }
267*c2c66affSColin Finck
268*c2c66affSColin Finck GLint GLAPIENTRY
gluUnProject(GLdouble winx,GLdouble winy,GLdouble winz,const GLdouble modelMatrix[16],const GLdouble projMatrix[16],const GLint viewport[4],GLdouble * objx,GLdouble * objy,GLdouble * objz)269*c2c66affSColin Finck gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz,
270*c2c66affSColin Finck const GLdouble modelMatrix[16],
271*c2c66affSColin Finck const GLdouble projMatrix[16],
272*c2c66affSColin Finck const GLint viewport[4],
273*c2c66affSColin Finck GLdouble *objx, GLdouble *objy, GLdouble *objz)
274*c2c66affSColin Finck {
275*c2c66affSColin Finck double finalMatrix[16];
276*c2c66affSColin Finck double in[4];
277*c2c66affSColin Finck double out[4];
278*c2c66affSColin Finck
279*c2c66affSColin Finck __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix);
280*c2c66affSColin Finck if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);
281*c2c66affSColin Finck
282*c2c66affSColin Finck in[0]=winx;
283*c2c66affSColin Finck in[1]=winy;
284*c2c66affSColin Finck in[2]=winz;
285*c2c66affSColin Finck in[3]=1.0;
286*c2c66affSColin Finck
287*c2c66affSColin Finck /* Map x and y from window coordinates */
288*c2c66affSColin Finck in[0] = (in[0] - viewport[0]) / viewport[2];
289*c2c66affSColin Finck in[1] = (in[1] - viewport[1]) / viewport[3];
290*c2c66affSColin Finck
291*c2c66affSColin Finck /* Map to range -1 to 1 */
292*c2c66affSColin Finck in[0] = in[0] * 2 - 1;
293*c2c66affSColin Finck in[1] = in[1] * 2 - 1;
294*c2c66affSColin Finck in[2] = in[2] * 2 - 1;
295*c2c66affSColin Finck
296*c2c66affSColin Finck __gluMultMatrixVecd(finalMatrix, in, out);
297*c2c66affSColin Finck if (out[3] == 0.0) return(GL_FALSE);
298*c2c66affSColin Finck out[0] /= out[3];
299*c2c66affSColin Finck out[1] /= out[3];
300*c2c66affSColin Finck out[2] /= out[3];
301*c2c66affSColin Finck *objx = out[0];
302*c2c66affSColin Finck *objy = out[1];
303*c2c66affSColin Finck *objz = out[2];
304*c2c66affSColin Finck return(GL_TRUE);
305*c2c66affSColin Finck }
306*c2c66affSColin Finck
307*c2c66affSColin Finck GLint GLAPIENTRY
gluUnProject4(GLdouble winx,GLdouble winy,GLdouble winz,GLdouble clipw,const GLdouble modelMatrix[16],const GLdouble projMatrix[16],const GLint viewport[4],GLclampd nearVal,GLclampd farVal,GLdouble * objx,GLdouble * objy,GLdouble * objz,GLdouble * objw)308*c2c66affSColin Finck gluUnProject4(GLdouble winx, GLdouble winy, GLdouble winz, GLdouble clipw,
309*c2c66affSColin Finck const GLdouble modelMatrix[16],
310*c2c66affSColin Finck const GLdouble projMatrix[16],
311*c2c66affSColin Finck const GLint viewport[4],
312*c2c66affSColin Finck GLclampd nearVal, GLclampd farVal,
313*c2c66affSColin Finck GLdouble *objx, GLdouble *objy, GLdouble *objz,
314*c2c66affSColin Finck GLdouble *objw)
315*c2c66affSColin Finck {
316*c2c66affSColin Finck double finalMatrix[16];
317*c2c66affSColin Finck double in[4];
318*c2c66affSColin Finck double out[4];
319*c2c66affSColin Finck
320*c2c66affSColin Finck __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix);
321*c2c66affSColin Finck if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);
322*c2c66affSColin Finck
323*c2c66affSColin Finck in[0]=winx;
324*c2c66affSColin Finck in[1]=winy;
325*c2c66affSColin Finck in[2]=winz;
326*c2c66affSColin Finck in[3]=clipw;
327*c2c66affSColin Finck
328*c2c66affSColin Finck /* Map x and y from window coordinates */
329*c2c66affSColin Finck in[0] = (in[0] - viewport[0]) / viewport[2];
330*c2c66affSColin Finck in[1] = (in[1] - viewport[1]) / viewport[3];
331*c2c66affSColin Finck in[2] = (in[2] - nearVal) / (farVal - nearVal);
332*c2c66affSColin Finck
333*c2c66affSColin Finck /* Map to range -1 to 1 */
334*c2c66affSColin Finck in[0] = in[0] * 2 - 1;
335*c2c66affSColin Finck in[1] = in[1] * 2 - 1;
336*c2c66affSColin Finck in[2] = in[2] * 2 - 1;
337*c2c66affSColin Finck
338*c2c66affSColin Finck __gluMultMatrixVecd(finalMatrix, in, out);
339*c2c66affSColin Finck if (out[3] == 0.0) return(GL_FALSE);
340*c2c66affSColin Finck *objx = out[0];
341*c2c66affSColin Finck *objy = out[1];
342*c2c66affSColin Finck *objz = out[2];
343*c2c66affSColin Finck *objw = out[3];
344*c2c66affSColin Finck return(GL_TRUE);
345*c2c66affSColin Finck }
346*c2c66affSColin Finck
347*c2c66affSColin Finck void GLAPIENTRY
gluPickMatrix(GLdouble x,GLdouble y,GLdouble deltax,GLdouble deltay,GLint viewport[4])348*c2c66affSColin Finck gluPickMatrix(GLdouble x, GLdouble y, GLdouble deltax, GLdouble deltay,
349*c2c66affSColin Finck GLint viewport[4])
350*c2c66affSColin Finck {
351*c2c66affSColin Finck if (deltax <= 0 || deltay <= 0) {
352*c2c66affSColin Finck return;
353*c2c66affSColin Finck }
354*c2c66affSColin Finck
355*c2c66affSColin Finck /* Translate and scale the picked region to the entire window */
356*c2c66affSColin Finck glTranslatef((viewport[2] - 2 * (x - viewport[0])) / deltax,
357*c2c66affSColin Finck (viewport[3] - 2 * (y - viewport[1])) / deltay, 0);
358*c2c66affSColin Finck glScalef(viewport[2] / deltax, viewport[3] / deltay, 1.0);
359*c2c66affSColin Finck }
360