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

©2005-2013 Laurent Ribon