source: trunk/src/opengl/glu/util/project.c

Last change on this file was 2945, checked in by sandervl, 26 years ago

compile fixes

File size: 9.8 KB
Line 
1/* $Id: project.c,v 1.2 2000-02-29 13:56:50 sandervl Exp $ */
2/*
3** License Applicability. Except to the extent portions of this file are
4** made subject to an alternative license as permitted in the SGI Free
5** Software License B, Version 1.0 (the "License"), the contents of this
6** file are subject only to the provisions of the License. You may not use
7** this file except in compliance with the License. You may obtain a copy
8** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
9** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10**
11** http://oss.sgi.com/projects/FreeB
12**
13** Note that, as provided in the License, the Software is distributed on an
14** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
15** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
16** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
17** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18**
19** Original Code. The Original Code is: OpenGL Sample Implementation,
20** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
21** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
22** Copyright in any portions created by third parties is as indicated
23** elsewhere herein. All Rights Reserved.
24**
25** Additional Notice Provisions: The application programming interfaces
26** established by SGI in conjunction with the Original Code are The
27** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
28** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
29** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
30** Window System(R) (Version 1.3), released October 19, 1998. This software
31** was created using the OpenGL(R) version 1.2.1 Sample Implementation
32** published by SGI, but has not been independently verified as being
33** compliant with the OpenGL(R) version 1.2.1 Specification.
34**
35** $Date: 2000-02-29 13:56:50 $ $Revision: 1.2 $
36** $Header: /home/ktk/tmp/odin/2007/netlabs.cvs/odin32/src/opengl/glu/util/project.c,v 1.2 2000-02-29 13:56:50 sandervl Exp $
37*/
38
39#include "gluos.h"
40#include <math.h>
41#include "gl.h"
42#include "glu.h"
43#include "gluint.h"
44
45/*
46** Make m an identity matrix
47*/
48void __gluMakeIdentityd(GLdouble m[16])
49{
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;
54}
55
56void __gluMakeIdentityf(GLfloat m[16])
57{
58 m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
59 m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
60 m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
61 m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
62}
63
64void GLAPI
65gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
66{
67 glOrtho(left, right, bottom, top, -1, 1);
68}
69
70#define __glPi 3.14159265358979323846
71
72void GLAPI
73gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
74{
75 GLdouble m[4][4];
76 double sine, cotangent, deltaZ;
77 double radians = fovy / 2 * __glPi / 180;
78
79 deltaZ = zFar - zNear;
80 sine = sin(radians);
81 if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
82 return;
83 }
84 cotangent = COS(radians) / sine;
85
86 __gluMakeIdentityd(&m[0][0]);
87 m[0][0] = cotangent / aspect;
88 m[1][1] = cotangent;
89 m[2][2] = -(zFar + zNear) / deltaZ;
90 m[2][3] = -1;
91 m[3][2] = -2 * zNear * zFar / deltaZ;
92 m[3][3] = 0;
93 glMultMatrixd(&m[0][0]);
94}
95
96static void normalize(float v[3])
97{
98 float r;
99
100 r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
101 if (r == 0.0) return;
102
103 v[0] /= r;
104 v[1] /= r;
105 v[2] /= r;
106}
107
108static void cross(float v1[3], float v2[3], float result[3])
109{
110 result[0] = v1[1]*v2[2] - v1[2]*v2[1];
111 result[1] = v1[2]*v2[0] - v1[0]*v2[2];
112 result[2] = v1[0]*v2[1] - v1[1]*v2[0];
113}
114
115void GLAPI
116gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
117 GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
118 GLdouble upz)
119{
120 int i;
121 float forward[3], side[3], up[3];
122 GLfloat m[4][4];
123
124 forward[0] = centerx - eyex;
125 forward[1] = centery - eyey;
126 forward[2] = centerz - eyez;
127
128 up[0] = upx;
129 up[1] = upy;
130 up[2] = upz;
131
132 normalize(forward);
133
134 /* Side = forward x up */
135 cross(forward, up, side);
136 normalize(side);
137
138 /* Recompute up as: up = side x forward */
139 cross(side, forward, up);
140
141 __gluMakeIdentityf(&m[0][0]);
142 m[0][0] = side[0];
143 m[1][0] = side[1];
144 m[2][0] = side[2];
145
146 m[0][1] = up[0];
147 m[1][1] = up[1];
148 m[2][1] = up[2];
149
150 m[0][2] = -forward[0];
151 m[1][2] = -forward[1];
152 m[2][2] = -forward[2];
153
154 glMultMatrixf(&m[0][0]);
155 glTranslated(-eyex, -eyey, -eyez);
156}
157
158void __gluMultMatrixVecd(const GLdouble matrix[16], const GLdouble in[4],
159 GLdouble out[4])
160{
161 int i;
162
163 for (i=0; i<4; i++) {
164 out[i] =
165 in[0] * matrix[0*4+i] +
166 in[1] * matrix[1*4+i] +
167 in[2] * matrix[2*4+i] +
168 in[3] * matrix[3*4+i];
169 }
170}
171
172/*
173** inverse = invert(src)
174*/
175int __gluInvertMatrixd(const GLdouble src[16], GLdouble inverse[16])
176{
177 int i, j, k, swap;
178 double t;
179 GLdouble temp[4][4];
180
181 for (i=0; i<4; i++) {
182 for (j=0; j<4; j++) {
183 temp[i][j] = src[i*4+j];
184 }
185 }
186 __gluMakeIdentityd(inverse);
187
188 for (i = 0; i < 4; i++) {
189 /*
190 ** Look for largest element in column
191 */
192 swap = i;
193 for (j = i + 1; j < 4; j++) {
194 if (fabs(temp[j][i]) > fabs(temp[i][i])) {
195 swap = j;
196 }
197 }
198
199 if (swap != i) {
200 /*
201 ** Swap rows.
202 */
203 for (k = 0; k < 4; k++) {
204 t = temp[i][k];
205 temp[i][k] = temp[swap][k];
206 temp[swap][k] = t;
207
208 t = inverse[i*4+k];
209 inverse[i*4+k] = inverse[swap*4+k];
210 inverse[swap*4+k] = t;
211 }
212 }
213
214 if (temp[i][i] == 0) {
215 /*
216 ** No non-zero pivot. The matrix is singular, which shouldn't
217 ** happen. This means the user gave us a bad matrix.
218 */
219 return GL_FALSE;
220 }
221
222 t = temp[i][i];
223 for (k = 0; k < 4; k++) {
224 temp[i][k] /= t;
225 inverse[i*4+k] /= t;
226 }
227 for (j = 0; j < 4; j++) {
228 if (j != i) {
229 t = temp[j][i];
230 for (k = 0; k < 4; k++) {
231 temp[j][k] -= temp[i][k]*t;
232 inverse[j*4+k] -= inverse[i*4+k]*t;
233 }
234 }
235 }
236 }
237 return GL_TRUE;
238}
239
240void __gluMultMatricesd(const GLdouble a[16], const GLdouble b[16], GLdouble r[16])
241{
242 int i, j;
243
244 for (i = 0; i < 4; i++) {
245 for (j = 0; j < 4; j++) {
246 r[i*4+j] =
247 a[i*4+0]*b[0*4+j] +
248 a[i*4+1]*b[1*4+j] +
249 a[i*4+2]*b[2*4+j] +
250 a[i*4+3]*b[3*4+j];
251 }
252 }
253}
254
255GLint GLAPI
256gluProject(GLdouble objx, GLdouble objy, GLdouble objz,
257 const GLdouble modelMatrix[16],
258 const GLdouble projMatrix[16],
259 const GLint viewport[4],
260 GLdouble *winx, GLdouble *winy, GLdouble *winz)
261{
262 double in[4];
263 double out[4];
264
265 in[0]=objx;
266 in[1]=objy;
267 in[2]=objz;
268 in[3]=1.0;
269 __gluMultMatrixVecd(modelMatrix, in, out);
270 __gluMultMatrixVecd(projMatrix, out, in);
271 if (in[3] == 0.0) return(GL_FALSE);
272 in[0] /= in[3];
273 in[1] /= in[3];
274 in[2] /= in[3];
275 /* Map x, y and z to range 0-1 */
276 in[0] = in[0] * 0.5 + 0.5;
277 in[1] = in[1] * 0.5 + 0.5;
278 in[2] = in[2] * 0.5 + 0.5;
279
280 /* Map x,y to viewport */
281 in[0] = in[0] * viewport[2] + viewport[0];
282 in[1] = in[1] * viewport[3] + viewport[1];
283
284 *winx=in[0];
285 *winy=in[1];
286 *winz=in[2];
287 return(GL_TRUE);
288}
289
290GLint GLAPI
291gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz,
292 const GLdouble modelMatrix[16],
293 const GLdouble projMatrix[16],
294 const GLint viewport[4],
295 GLdouble *objx, GLdouble *objy, GLdouble *objz)
296{
297 double finalMatrix[16];
298 double in[4];
299 double out[4];
300
301 __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix);
302 if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);
303
304 in[0]=winx;
305 in[1]=winy;
306 in[2]=winz;
307 in[3]=1.0;
308
309 /* Map x and y from window coordinates */
310 in[0] = (in[0] - viewport[0]) / viewport[2];
311 in[1] = (in[1] - viewport[1]) / viewport[3];
312
313 /* Map to range -1 to 1 */
314 in[0] = in[0] * 2 - 1;
315 in[1] = in[1] * 2 - 1;
316 in[2] = in[2] * 2 - 1;
317
318 __gluMultMatrixVecd(finalMatrix, in, out);
319 if (out[3] == 0.0) return(GL_FALSE);
320 out[0] /= out[3];
321 out[1] /= out[3];
322 out[2] /= out[3];
323 *objx = out[0];
324 *objy = out[1];
325 *objz = out[2];
326 return(GL_TRUE);
327}
328
329GLint GLAPI
330gluUnProject4(GLdouble winx, GLdouble winy, GLdouble winz, GLdouble clipw,
331 const GLdouble modelMatrix[16],
332 const GLdouble projMatrix[16],
333 const GLint viewport[4],
334 GLclampd near, GLclampd far,
335 GLdouble *objx, GLdouble *objy, GLdouble *objz,
336 GLdouble *objw)
337{
338 double finalMatrix[16];
339 double in[4];
340 double out[4];
341
342 __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix);
343 if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);
344
345 in[0]=winx;
346 in[1]=winy;
347 in[2]=winz;
348 in[3]=clipw;
349
350 /* Map x and y from window coordinates */
351 in[0] = (in[0] - viewport[0]) / viewport[2];
352 in[1] = (in[1] - viewport[1]) / viewport[3];
353 in[2] = (in[2] - near) / (far - near);
354
355 /* Map to range -1 to 1 */
356 in[0] = in[0] * 2 - 1;
357 in[1] = in[1] * 2 - 1;
358 in[2] = in[2] * 2 - 1;
359
360 __gluMultMatrixVecd(finalMatrix, in, out);
361 if (out[3] == 0.0) return(GL_FALSE);
362 *objx = out[0];
363 *objy = out[1];
364 *objz = out[2];
365 *objw = out[3];
366 return(GL_TRUE);
367}
368
369GLUAPI void GLAPIENTRY gluPickMatrix(GLdouble x, GLdouble y, GLdouble deltax, GLdouble deltay,
370 const GLint viewport[4])
371{
372 if (deltax <= 0 || deltay <= 0) {
373 return;
374 }
375
376 /* Translate and scale the picked region to the entire window */
377 glTranslatef((viewport[2] - 2 * (x - viewport[0])) / deltax,
378 (viewport[3] - 2 * (y - viewport[1])) / deltay, 0);
379 glScalef(viewport[2] / deltax, viewport[3] / deltay, 1.0);
380}
Note: See TracBrowser for help on using the repository browser.