322 lines
7.5 KiB
C
322 lines
7.5 KiB
C
|
/*
|
||
|
** Copyright 1992, Silicon Graphics, Inc.
|
||
|
** All Rights Reserved.
|
||
|
**
|
||
|
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
|
||
|
** the contents of this file may not be disclosed to third parties, copied or
|
||
|
** duplicated in any form, in whole or in part, without the prior written
|
||
|
** permission of Silicon Graphics, Inc.
|
||
|
**
|
||
|
** RESTRICTED RIGHTS LEGEND:
|
||
|
** Use, duplication or disclosure by the Government is subject to restrictions
|
||
|
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
|
||
|
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
|
||
|
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
|
||
|
** rights reserved under the Copyright Laws of the United States.
|
||
|
**
|
||
|
** $Revision: 1.2 $
|
||
|
** $Date: 1995/06/23 21:27:54 $
|
||
|
*/
|
||
|
#ifdef NT
|
||
|
#include <glos.h>
|
||
|
#endif
|
||
|
#include <math.h>
|
||
|
#include <GL/gl.h>
|
||
|
#include <GL/glu.h>
|
||
|
#include "gluint.h"
|
||
|
|
||
|
/*
|
||
|
** Make m an identity matrix
|
||
|
*/
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
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 APIENTRY gluOrtho2D(GLdouble left, GLdouble right,
|
||
|
GLdouble bottom, GLdouble top)
|
||
|
|
||
|
{
|
||
|
glOrtho(left, right, bottom, top, -1, 1);
|
||
|
}
|
||
|
|
||
|
#define __glPi 3.14159265358979323846
|
||
|
|
||
|
void APIENTRY 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 APIENTRY 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);
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
*/
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
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 APIENTRY 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 APIENTRY 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);
|
||
|
}
|
||
|
|
||
|
void APIENTRY 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);
|
||
|
}
|