summaryrefslogtreecommitdiffstats
path: root/src/glu/sgi/libutil/project.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/glu/sgi/libutil/project.c')
-rw-r--r--src/glu/sgi/libutil/project.c762
1 files changed, 381 insertions, 381 deletions
diff --git a/src/glu/sgi/libutil/project.c b/src/glu/sgi/libutil/project.c
index 4d9819471b6..348bd7e40cc 100644
--- a/src/glu/sgi/libutil/project.c
+++ b/src/glu/sgi/libutil/project.c
@@ -1,381 +1,381 @@
-/*
-** License Applicability. Except to the extent portions of this file are
-** made subject to an alternative license as permitted in the SGI Free
-** Software License B, Version 1.1 (the "License"), the contents of this
-** file are subject only to the provisions of the License. You may not use
-** this file except in compliance with the License. You may obtain a copy
-** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
-** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
-**
-** http://oss.sgi.com/projects/FreeB
-**
-** Note that, as provided in the License, the Software is distributed on an
-** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
-** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
-** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
-** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
-**
-** Original Code. The Original Code is: OpenGL Sample Implementation,
-** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
-** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
-** Copyright in any portions created by third parties is as indicated
-** elsewhere herein. All Rights Reserved.
-**
-** Additional Notice Provisions: The application programming interfaces
-** established by SGI in conjunction with the Original Code are The
-** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
-** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
-** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
-** Window System(R) (Version 1.3), released October 19, 1998. This software
-** was created using the OpenGL(R) version 1.2.1 Sample Implementation
-** published by SGI, but has not been independently verified as being
-** compliant with the OpenGL(R) version 1.2.1 Specification.
-**
-** $Date: 2001/09/14 22:19:19 $ $Revision: 1.3 $
-** $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libutil/project.c,v 1.3 2001/09/14 22:19:19 brianp Exp $
-*/
-
-#include "gluos.h"
-#include <math.h>
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include "gluint.h"
-
-/*
-** Make m an identity matrix
-*/
-static void __gluMakeIdentityd(GLdouble m[16])
-{
- m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
- m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
- m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
- m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
-}
-
-static void __gluMakeIdentityf(GLfloat m[16])
-{
- m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
- m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
- m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
- m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
-}
-
-void GLAPIENTRY
-gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
-{
- glOrtho(left, right, bottom, top, -1, 1);
-}
-
-#define __glPi 3.14159265358979323846
-
-void GLAPIENTRY
-gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
-{
- GLdouble m[4][4];
- double sine, cotangent, deltaZ;
- double radians = fovy / 2 * __glPi / 180;
-
- deltaZ = zFar - zNear;
- sine = sin(radians);
- if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
- return;
- }
- cotangent = COS(radians) / sine;
-
- __gluMakeIdentityd(&m[0][0]);
- m[0][0] = cotangent / aspect;
- m[1][1] = cotangent;
- m[2][2] = -(zFar + zNear) / deltaZ;
- m[2][3] = -1;
- m[3][2] = -2 * zNear * zFar / deltaZ;
- m[3][3] = 0;
- glMultMatrixd(&m[0][0]);
-}
-
-static void normalize(float v[3])
-{
- float r;
-
- r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
- if (r == 0.0) return;
-
- v[0] /= r;
- v[1] /= r;
- v[2] /= r;
-}
-
-static void cross(float v1[3], float v2[3], float result[3])
-{
- result[0] = v1[1]*v2[2] - v1[2]*v2[1];
- result[1] = v1[2]*v2[0] - v1[0]*v2[2];
- result[2] = v1[0]*v2[1] - v1[1]*v2[0];
-}
-
-void GLAPIENTRY
-gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
- GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
- GLdouble upz)
-{
- int i;
- float forward[3], side[3], up[3];
- GLfloat m[4][4];
-
- forward[0] = centerx - eyex;
- forward[1] = centery - eyey;
- forward[2] = centerz - eyez;
-
- up[0] = upx;
- up[1] = upy;
- up[2] = upz;
-
- normalize(forward);
-
- /* Side = forward x up */
- cross(forward, up, side);
- normalize(side);
-
- /* Recompute up as: up = side x forward */
- cross(side, forward, up);
-
- __gluMakeIdentityf(&m[0][0]);
- m[0][0] = side[0];
- m[1][0] = side[1];
- m[2][0] = side[2];
-
- m[0][1] = up[0];
- m[1][1] = up[1];
- m[2][1] = up[2];
-
- m[0][2] = -forward[0];
- m[1][2] = -forward[1];
- m[2][2] = -forward[2];
-
- glMultMatrixf(&m[0][0]);
- glTranslated(-eyex, -eyey, -eyez);
-}
-
-static void __gluMultMatrixVecd(const GLdouble matrix[16], const GLdouble in[4],
- GLdouble out[4])
-{
- int i;
-
- for (i=0; i<4; i++) {
- out[i] =
- in[0] * matrix[0*4+i] +
- in[1] * matrix[1*4+i] +
- in[2] * matrix[2*4+i] +
- in[3] * matrix[3*4+i];
- }
-}
-
-/*
-** inverse = invert(src)
-*/
-static int __gluInvertMatrixd(const GLdouble src[16], GLdouble inverse[16])
-{
- int i, j, k, swap;
- double t;
- GLdouble temp[4][4];
-
- for (i=0; i<4; i++) {
- for (j=0; j<4; j++) {
- temp[i][j] = src[i*4+j];
- }
- }
- __gluMakeIdentityd(inverse);
-
- for (i = 0; i < 4; i++) {
- /*
- ** Look for largest element in column
- */
- swap = i;
- for (j = i + 1; j < 4; j++) {
- if (fabs(temp[j][i]) > fabs(temp[i][i])) {
- swap = j;
- }
- }
-
- if (swap != i) {
- /*
- ** Swap rows.
- */
- for (k = 0; k < 4; k++) {
- t = temp[i][k];
- temp[i][k] = temp[swap][k];
- temp[swap][k] = t;
-
- t = inverse[i*4+k];
- inverse[i*4+k] = inverse[swap*4+k];
- inverse[swap*4+k] = t;
- }
- }
-
- if (temp[i][i] == 0) {
- /*
- ** No non-zero pivot. The matrix is singular, which shouldn't
- ** happen. This means the user gave us a bad matrix.
- */
- return GL_FALSE;
- }
-
- t = temp[i][i];
- for (k = 0; k < 4; k++) {
- temp[i][k] /= t;
- inverse[i*4+k] /= t;
- }
- for (j = 0; j < 4; j++) {
- if (j != i) {
- t = temp[j][i];
- for (k = 0; k < 4; k++) {
- temp[j][k] -= temp[i][k]*t;
- inverse[j*4+k] -= inverse[i*4+k]*t;
- }
- }
- }
- }
- return GL_TRUE;
-}
-
-static void __gluMultMatricesd(const GLdouble a[16], const GLdouble b[16],
- GLdouble r[16])
-{
- int i, j;
-
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- r[i*4+j] =
- a[i*4+0]*b[0*4+j] +
- a[i*4+1]*b[1*4+j] +
- a[i*4+2]*b[2*4+j] +
- a[i*4+3]*b[3*4+j];
- }
- }
-}
-
-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)
-{
- double in[4];
- double out[4];
-
- in[0]=objx;
- in[1]=objy;
- in[2]=objz;
- in[3]=1.0;
- __gluMultMatrixVecd(modelMatrix, in, out);
- __gluMultMatrixVecd(projMatrix, out, in);
- if (in[3] == 0.0) return(GL_FALSE);
- in[0] /= in[3];
- in[1] /= in[3];
- in[2] /= in[3];
- /* Map x, y and z to range 0-1 */
- in[0] = in[0] * 0.5 + 0.5;
- in[1] = in[1] * 0.5 + 0.5;
- in[2] = in[2] * 0.5 + 0.5;
-
- /* Map x,y to viewport */
- in[0] = in[0] * viewport[2] + viewport[0];
- in[1] = in[1] * viewport[3] + viewport[1];
-
- *winx=in[0];
- *winy=in[1];
- *winz=in[2];
- return(GL_TRUE);
-}
-
-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)
-{
- double finalMatrix[16];
- double in[4];
- double out[4];
-
- __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix);
- if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);
-
- in[0]=winx;
- in[1]=winy;
- in[2]=winz;
- in[3]=1.0;
-
- /* Map x and y from window coordinates */
- in[0] = (in[0] - viewport[0]) / viewport[2];
- in[1] = (in[1] - viewport[1]) / viewport[3];
-
- /* Map to range -1 to 1 */
- in[0] = in[0] * 2 - 1;
- in[1] = in[1] * 2 - 1;
- in[2] = in[2] * 2 - 1;
-
- __gluMultMatrixVecd(finalMatrix, in, out);
- if (out[3] == 0.0) return(GL_FALSE);
- out[0] /= out[3];
- out[1] /= out[3];
- out[2] /= out[3];
- *objx = out[0];
- *objy = out[1];
- *objz = out[2];
- return(GL_TRUE);
-}
-
-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)
-{
- double finalMatrix[16];
- double in[4];
- double out[4];
-
- __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix);
- if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);
-
- in[0]=winx;
- in[1]=winy;
- in[2]=winz;
- in[3]=clipw;
-
- /* Map x and y from window coordinates */
- in[0] = (in[0] - viewport[0]) / viewport[2];
- in[1] = (in[1] - viewport[1]) / viewport[3];
- in[2] = (in[2] - nearVal) / (farVal - nearVal);
-
- /* Map to range -1 to 1 */
- in[0] = in[0] * 2 - 1;
- in[1] = in[1] * 2 - 1;
- in[2] = in[2] * 2 - 1;
-
- __gluMultMatrixVecd(finalMatrix, in, out);
- if (out[3] == 0.0) return(GL_FALSE);
- *objx = out[0];
- *objy = out[1];
- *objz = out[2];
- *objw = out[3];
- return(GL_TRUE);
-}
-
-void GLAPIENTRY
-gluPickMatrix(GLdouble x, GLdouble y, GLdouble deltax, GLdouble deltay,
- GLint viewport[4])
-{
- if (deltax <= 0 || deltay <= 0) {
- return;
- }
-
- /* Translate and scale the picked region to the entire window */
- glTranslatef((viewport[2] - 2 * (x - viewport[0])) / deltax,
- (viewport[3] - 2 * (y - viewport[1])) / deltay, 0);
- glScalef(viewport[2] / deltax, viewport[3] / deltay, 1.0);
-}
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** $Date: 2001/09/18 16:39:38 $ $Revision: 1.4 $
+** $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libutil/project.c,v 1.4 2001/09/18 16:39:38 kschultz Exp $
+*/
+
+#include "gluos.h"
+#include <math.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include "gluint.h"
+
+/*
+** Make m an identity matrix
+*/
+static void __gluMakeIdentityd(GLdouble m[16])
+{
+ m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
+ m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
+ m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
+ m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
+}
+
+static void __gluMakeIdentityf(GLfloat m[16])
+{
+ m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
+ m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
+ m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
+ m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
+}
+
+void GLAPIENTRY
+gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
+{
+ glOrtho(left, right, bottom, top, -1, 1);
+}
+
+#define __glPi 3.14159265358979323846
+
+void GLAPIENTRY
+gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
+{
+ GLdouble m[4][4];
+ double sine, cotangent, deltaZ;
+ double radians = fovy / 2 * __glPi / 180;
+
+ deltaZ = zFar - zNear;
+ sine = sin(radians);
+ if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
+ return;
+ }
+ cotangent = COS(radians) / sine;
+
+ __gluMakeIdentityd(&m[0][0]);
+ m[0][0] = cotangent / aspect;
+ m[1][1] = cotangent;
+ m[2][2] = -(zFar + zNear) / deltaZ;
+ m[2][3] = -1;
+ m[3][2] = -2 * zNear * zFar / deltaZ;
+ m[3][3] = 0;
+ glMultMatrixd(&m[0][0]);
+}
+
+static void normalize(float v[3])
+{
+ float r;
+
+ r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
+ if (r == 0.0) return;
+
+ v[0] /= r;
+ v[1] /= r;
+ v[2] /= r;
+}
+
+static void cross(float v1[3], float v2[3], float result[3])
+{
+ result[0] = v1[1]*v2[2] - v1[2]*v2[1];
+ result[1] = v1[2]*v2[0] - v1[0]*v2[2];
+ result[2] = v1[0]*v2[1] - v1[1]*v2[0];
+}
+
+void GLAPIENTRY
+gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
+ GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
+ GLdouble upz)
+{
+ int i;
+ float forward[3], side[3], up[3];
+ GLfloat m[4][4];
+
+ forward[0] = centerx - eyex;
+ forward[1] = centery - eyey;
+ forward[2] = centerz - eyez;
+
+ up[0] = upx;
+ up[1] = upy;
+ up[2] = upz;
+
+ normalize(forward);
+
+ /* Side = forward x up */
+ cross(forward, up, side);
+ normalize(side);
+
+ /* Recompute up as: up = side x forward */
+ cross(side, forward, up);
+
+ __gluMakeIdentityf(&m[0][0]);
+ m[0][0] = side[0];
+ m[1][0] = side[1];
+ m[2][0] = side[2];
+
+ m[0][1] = up[0];
+ m[1][1] = up[1];
+ m[2][1] = up[2];
+
+ m[0][2] = -forward[0];
+ m[1][2] = -forward[1];
+ m[2][2] = -forward[2];
+
+ glMultMatrixf(&m[0][0]);
+ glTranslated(-eyex, -eyey, -eyez);
+}
+
+static void __gluMultMatrixVecd(const GLdouble matrix[16], const GLdouble in[4],
+ GLdouble out[4])
+{
+ int i;
+
+ for (i=0; i<4; i++) {
+ out[i] =
+ in[0] * matrix[0*4+i] +
+ in[1] * matrix[1*4+i] +
+ in[2] * matrix[2*4+i] +
+ in[3] * matrix[3*4+i];
+ }
+}
+
+/*
+** inverse = invert(src)
+*/
+static int __gluInvertMatrixd(const GLdouble src[16], GLdouble inverse[16])
+{
+ int i, j, k, swap;
+ double t;
+ GLdouble temp[4][4];
+
+ for (i=0; i<4; i++) {
+ for (j=0; j<4; j++) {
+ temp[i][j] = src[i*4+j];
+ }
+ }
+ __gluMakeIdentityd(inverse);
+
+ for (i = 0; i < 4; i++) {
+ /*
+ ** Look for largest element in column
+ */
+ swap = i;
+ for (j = i + 1; j < 4; j++) {
+ if (fabs(temp[j][i]) > fabs(temp[i][i])) {
+ swap = j;
+ }
+ }
+
+ if (swap != i) {
+ /*
+ ** Swap rows.
+ */
+ for (k = 0; k < 4; k++) {
+ t = temp[i][k];
+ temp[i][k] = temp[swap][k];
+ temp[swap][k] = t;
+
+ t = inverse[i*4+k];
+ inverse[i*4+k] = inverse[swap*4+k];
+ inverse[swap*4+k] = t;
+ }
+ }
+
+ if (temp[i][i] == 0) {
+ /*
+ ** No non-zero pivot. The matrix is singular, which shouldn't
+ ** happen. This means the user gave us a bad matrix.
+ */
+ return GL_FALSE;
+ }
+
+ t = temp[i][i];
+ for (k = 0; k < 4; k++) {
+ temp[i][k] /= t;
+ inverse[i*4+k] /= t;
+ }
+ for (j = 0; j < 4; j++) {
+ if (j != i) {
+ t = temp[j][i];
+ for (k = 0; k < 4; k++) {
+ temp[j][k] -= temp[i][k]*t;
+ inverse[j*4+k] -= inverse[i*4+k]*t;
+ }
+ }
+ }
+ }
+ return GL_TRUE;
+}
+
+static void __gluMultMatricesd(const GLdouble a[16], const GLdouble b[16],
+ GLdouble r[16])
+{
+ int i, j;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ r[i*4+j] =
+ a[i*4+0]*b[0*4+j] +
+ a[i*4+1]*b[1*4+j] +
+ a[i*4+2]*b[2*4+j] +
+ a[i*4+3]*b[3*4+j];
+ }
+ }
+}
+
+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)
+{
+ double in[4];
+ double out[4];
+
+ in[0]=objx;
+ in[1]=objy;
+ in[2]=objz;
+ in[3]=1.0;
+ __gluMultMatrixVecd(modelMatrix, in, out);
+ __gluMultMatrixVecd(projMatrix, out, in);
+ if (in[3] == 0.0) return(GL_FALSE);
+ in[0] /= in[3];
+ in[1] /= in[3];
+ in[2] /= in[3];
+ /* Map x, y and z to range 0-1 */
+ in[0] = in[0] * 0.5 + 0.5;
+ in[1] = in[1] * 0.5 + 0.5;
+ in[2] = in[2] * 0.5 + 0.5;
+
+ /* Map x,y to viewport */
+ in[0] = in[0] * viewport[2] + viewport[0];
+ in[1] = in[1] * viewport[3] + viewport[1];
+
+ *winx=in[0];
+ *winy=in[1];
+ *winz=in[2];
+ return(GL_TRUE);
+}
+
+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)
+{
+ double finalMatrix[16];
+ double in[4];
+ double out[4];
+
+ __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix);
+ if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);
+
+ in[0]=winx;
+ in[1]=winy;
+ in[2]=winz;
+ in[3]=1.0;
+
+ /* Map x and y from window coordinates */
+ in[0] = (in[0] - viewport[0]) / viewport[2];
+ in[1] = (in[1] - viewport[1]) / viewport[3];
+
+ /* Map to range -1 to 1 */
+ in[0] = in[0] * 2 - 1;
+ in[1] = in[1] * 2 - 1;
+ in[2] = in[2] * 2 - 1;
+
+ __gluMultMatrixVecd(finalMatrix, in, out);
+ if (out[3] == 0.0) return(GL_FALSE);
+ out[0] /= out[3];
+ out[1] /= out[3];
+ out[2] /= out[3];
+ *objx = out[0];
+ *objy = out[1];
+ *objz = out[2];
+ return(GL_TRUE);
+}
+
+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)
+{
+ double finalMatrix[16];
+ double in[4];
+ double out[4];
+
+ __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix);
+ if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);
+
+ in[0]=winx;
+ in[1]=winy;
+ in[2]=winz;
+ in[3]=clipw;
+
+ /* Map x and y from window coordinates */
+ in[0] = (in[0] - viewport[0]) / viewport[2];
+ in[1] = (in[1] - viewport[1]) / viewport[3];
+ in[2] = (in[2] - nearVal) / (farVal - nearVal);
+
+ /* Map to range -1 to 1 */
+ in[0] = in[0] * 2 - 1;
+ in[1] = in[1] * 2 - 1;
+ in[2] = in[2] * 2 - 1;
+
+ __gluMultMatrixVecd(finalMatrix, in, out);
+ if (out[3] == 0.0) return(GL_FALSE);
+ *objx = out[0];
+ *objy = out[1];
+ *objz = out[2];
+ *objw = out[3];
+ return(GL_TRUE);
+}
+
+void GLAPIENTRY
+gluPickMatrix(GLdouble x, GLdouble y, GLdouble deltax, GLdouble deltay,
+ GLint viewport[4])
+{
+ if (deltax <= 0 || deltay <= 0) {
+ return;
+ }
+
+ /* Translate and scale the picked region to the entire window */
+ glTranslatef((viewport[2] - 2 * (x - viewport[0])) / deltax,
+ (viewport[3] - 2 * (y - viewport[1])) / deltay, 0);
+ glScalef(viewport[2] / deltax, viewport[3] / deltay, 1.0);
+}