1 /****************************************************************************
2 * VCGLib                                                            o o     *
3 * Visual and Computer Graphics Library                            o     o   *
4 *                                                                _   O  _   *
5 * Copyright(C) 2004-2016                                           \/)\/    *
6 * Visual Computing Lab                                            /\/|      *
7 * ISTI - Italian National Research Council                           |      *
8 *                                                                    \      *
9 * All rights reserved.                                                      *
10 *                                                                           *
11 * This program is free software; you can redistribute it and/or modify      *
12 * it under the terms of the GNU General Public License as published by      *
13 * the Free Software Foundation; either version 2 of the License, or         *
14 * (at your option) any later version.                                       *
15 *                                                                           *
16 * This program is distributed in the hope that it will be useful,           *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
20 * for more details.                                                         *
21 *                                                                           *
22 ****************************************************************************/
23 /****************************************************************************
24   History
25 $Log: not supported by cvs2svn $
26 Revision 1.14  2006/12/18 16:02:57  matteodelle
27 minor eroor correction on variable names
28 
29 Revision 1.13  2006/12/18 14:28:07  matteodelle
30 *** empty log message ***
31 
32 Revision 1.12  2006/12/18 09:46:39  callieri
33 camera+shot revamp: changed field names to something with more sense, cleaning of various functions, correction of minor bugs/incongruences, removal of the infamous reference in shot.
34 
35 Revision 1.11  2006/01/10 12:22:34  spinelli
36 add namespace vcg::
37 
38 Revision 1.10  2005/10/24 14:42:57  spinelli
39 add namespace vcg:: to GetFrustum(...)
40 
41 Revision 1.9  2005/06/29 15:02:29  spinelli
42 aggiunto:
43 - static void CavalieriProj( .. )
44 - static void IsometricProj( .. )
45 
46 modificato:
47 - static void TransformGL( .. )
48 - static void SetSubView( .. )
49 
50 Revision 1.8  2005/02/22 10:57:05  tommyfranken
51 corrected some syntax errors in GetFrustum
52 
53 Revision 1.7  2005/02/21 18:11:47  ganovelli
54 GetFrustum moved from gl/camera to math/camera.h
55 
56 Revision 1.6  2004/12/16 14:41:36  ricciodimare
57 *** empty log message ***
58 
59 Revision 1.5  2004/12/16 11:08:35  ricciodimare
60 Cambiato il nome del costruttore era rimasto quello vecchio... e tolti alcune righe di codice commentate
61 
62 Revision 1.4  2004/12/15 18:45:06  tommyfranken
63 *** empty log message ***
64 
65 Revision 1.3  2004/11/03 09:38:21  ganovelli
66 added SetSubView, some comment and put the class back(!)
67 
68 Revision 1.2  2004/10/05 19:04:44  ganovelli
69 changed from classes to functions
70 
71 Revision 1.1  2004/09/15 22:59:13  ganovelli
72 creation
73 
74 ****************************************************************************/
75 
76 
77 #ifndef __GL_CAMERA
78 #define __GL_CAMERA
79 // VCG
80 #include <vcg/math/camera.h>
81 
82 // opengl
83 #include <GL/glew.h>
84 
85 template <class CameraType>
86 struct GlCamera{
87 
88 	typedef typename CameraType::ScalarType ScalarType;
89 	typedef typename CameraType::ScalarType S;
90 
91 
92 /// returns the OpenGL 4x4 PROJECTION matrix that describes the camera (intrinsics)
93 static vcg::Matrix44<ScalarType>
MatrixGLGlCamera94 MatrixGL(vcg::Camera<S> & cam, vcg::Matrix44<S> &m)
95 {
96 	glPushAttrib(GL_TRANSFORM_BIT);
97 	glMatrixMode(GL_PROJECTION);
98 	glPushMatrix();
99 	glLoadIdentity();
100 	TransformGL(cam);
101 	glGetv(GL_PROJECTION_MATRIX,&m[0][0]);
102 	glPopMatrix();
103 	glPopAttrib();
104 	return m;
105 }
106 
107 /// set the OpenGL PROJECTION matrix for the Cavalieri projection
SetGLCavalieriProjGlCamera108 static void SetGLCavalieriProj(float x1, float x2, float y1, float y2, float z1, float z2)
109 {
110 	GLfloat cavalieri[16];
111 
112 	cavalieri[0]  = 2.0f/(x2-x1);                   cavalieri[4] = 0;
113 	cavalieri[8]  = (0.707106f * -2.0f)/(x2-x1);    cavalieri[12] = (x2+x1)/(x2-x1);
114 	cavalieri[1]  = 0;                              cavalieri[5] = 2.0/(y2-y1);
115 	cavalieri[9]  = (0.707106f * -2.0f)/(y2-y1);    cavalieri[13] = (y2+y1)/(y2-y1);
116 	cavalieri[2]  = 0;                              cavalieri[6] = 0;
117 	cavalieri[10] = -2.0f/(z2-z1);                  cavalieri[14] = (z2+z1)/(z2-z1);
118 	cavalieri[3]  = 0;                              cavalieri[7] = 0;
119 	cavalieri[11] = 0;                              cavalieri[15] = 1.0f;
120 
121 	glLoadMatrixf(cavalieri);
122 }
123 
124 /// set the OpenGL PROJECTION matrix for the Isometric projection
SetGLIsometricProjGlCamera125 static void SetGLIsometricProj(float x1, float x2, float y1, float y2, float z1, float z2)
126 {
127 	GLfloat isometric[16];
128 
129 	isometric[0]  = 1.6f/(x2-x1);     isometric[4]  = 0;
130 	isometric[8]  = -1.6f/(x2-x1);    isometric[12] = (x2+x1)/(x2-x1);
131 	isometric[1]  = -1.0f/(y2-y1);    isometric[5]  = 2.0f/(y2-y1);
132 	isometric[9]  = -1.0f/(y2-y1);    isometric[13] = (y2+y1)/(y2-y1);
133 	isometric[2]  = 0;                isometric[6]  = 0;
134 	isometric[10] = -2.0f/(z2-z1);    isometric[14] = (z2+z1)/(z2-z1);
135 	isometric[3]  = 0;                isometric[7]  = 0;
136 	isometric[11] = 0;                isometric[15] = 1.0f;
137 
138 	glLoadMatrixf(isometric);
139 }
140 
141 /// get OpenGL-like frustum from a vcg camera (intrinsics)
GetFrustumGlCamera142 static void GetFrustum(vcg::Camera<S> & intrinsics, S & sx,S & dx,S & bt,S & tp,S & f)
143 {
144 	intrinsics.GetFrustum(sx,dx,bt,tp,f);
145 }
146 
147 /// set the OpenGL PROJECTION matrix to match the camera (intrinsics). requires near and far plane
TransformGLGlCamera148 static void TransformGL(vcg::Camera<S> & camera, S nearDist, S farDist )
149 {
150 	S sx,dx,bt,tp,nr;
151 	camera.GetFrustum(sx,dx,bt,tp,nr);
152 
153   if(camera.cameraType == CameraType::PERSPECTIVE) {
154     S ratio = nearDist/nr;
155     sx *= ratio;
156     dx *= ratio;
157     bt *= ratio;
158     tp *= ratio;
159   }
160 
161 	assert(glGetError()==0);
162 
163 	switch(camera.cameraType)
164 	{
165    case CameraType::PERSPECTIVE: glFrustum(sx,dx,bt,tp,nearDist,farDist);	break;
166    case CameraType::ORTHO:       glOrtho(sx,dx,bt,tp,nearDist,farDist); break;
167    case CameraType::ISOMETRIC:   SetGLIsometricProj(sx,dx,bt,tp,nearDist,farDist); 	break;
168    case CameraType::CAVALIERI:   SetGLCavalieriProj(sx,dx,bt,tp,nearDist,farDist); 	break;
169 	}
170 
171 	assert(glGetError()==0);
172 };
173 
174 
GetViewSizeGlCamera175 static void GetViewSize(vcg::Camera<S> & camera, S &width, S &height) {
176 	S sx,dx,bt,tp,nr,fr;
177 	GetFrustum(camera,sx,dx,bt,tp,nr,fr);
178 	width = dx-sx;	//right - left = width
179 	height = tp-bt;  //top - bottom = height
180 };
181 
182 
SetSubViewGlCamera183 static void SetSubView(vcg::Camera<S> & camera,vcg::Point2<S> p0,S nearDist, S farDist,vcg::Point2<S> p1){
184 	//typedef typename CameraType::ScalarType S;
185 	S sx,dx,bt,tp,f;
186 	GetFrustum(camera,sx,dx,bt,tp,f);
187 	S width = dx-sx;	//right - left = width
188 	S height = tp-bt;  //top - bottom = height
189 	/*glFrustum(
190 				width* p0[0]+ sx, width* p1[0]+ sx,
191 				height* p0[1]+ bt, height* p1[1]+ bt,
192 				nr,fr);*/
193 
194 
195 
196 	switch(camera.cameraType)
197 	{
198    case CameraType::PERSPECTIVE: glFrustum(	width* p0[0]+ sx, width* p1[0]+ sx,		height* p0[1]+ bt, height* p1[1]+bt,nearDist,farDist);	break;
199    case CameraType::ORTHO:       glOrtho(width* p0[0]+sx, width* p1[0]+sx,			height* p0[1]+ bt, height* p1[1]+bt,nearDist,farDist); break;
200 	 //case vcg::ISOMETRIC:   IsometricProj(dx-width* p1[0], dx-width* p0[0],		tp-height* p1[1], tp-height* p0[1],nearDist,farDist);	break;
201 	 //case vcg::CAVALIERI:   CavalieriProj(dx-width* p1[0], dx-width* p0[0],		tp-height* p1[1], tp-height* p0[1],nearDist,farDist);	break;
202 	}
203 
204 
205 	assert(glGetError()==0);
206 };
207 };
208 #endif
209 
210 
211 
212 
213 
214 
215 //private:
216 //
217 //	static inline S SQRT( S x) { return sqrt(fabs(x)); }
218 //	static inline S CBRT ( S x )
219 //	{
220 //		if (x == 0) return 0;
221 //		else if (x > 0) return pow (x, 1.0 / 3.0);
222 //		else return -pow (-x, 1.0 / 3.0);
223 //	}
224 //	static inline void SINCOS( S x, S & s, S & c)
225 //	{
226 //		s=sin(x);
227 //		c=cos(x);
228 //	}
229 //	static inline void SINCOSd( double x, double & s, double & c)
230 //	{
231 //		s=sin(x);
232 //		c=cos(x);
233 //	}
234 //	static inline S CUB( S x ) { return x*x*x; }
235 //	static inline S SQR( S x ) { return x*x; }
236 //
237 //public:
238 //	void undistorted_to_distorted_sensor_coord (S Xu, S Yu, S & Xd, S & Yd) const
239 //	{
240 //		const S SQRT3 = S(1.732050807568877293527446341505872366943);
241 //		S Ru,Rd,lambda,c,d,Q,R,D,S,T,sinT,cosT;
242 //
243 //		if((Xu==0 && Yu==0) || k[0] == 0)
244 //		{
245 //			Xd = Xu;
246 //			Yd = Yu;
247 //			return;
248 //		}
249 //
250 //		Ru = hypot (Xu, Yu);	/* SQRT(Xu*Xu+Yu*Yu) */
251 //		c = 1 / k[0];
252 //		d = -c * Ru;
253 //
254 //		Q = c / 3;
255 //		R = -d / 2;
256 //		D = CUB (Q) + SQR (R);
257 //
258 //		if (D >= 0)		/* one real root */
259 //		{
260 //			D = SQRT (D);
261 //			S = CBRT (R + D);
262 //			T = CBRT (R - D);
263 //			Rd = S + T;
264 //
265 //			if (Rd < 0)
266 //				Rd = SQRT (-1 / (3 * k[0]));
267 //		}
268 //		else			/* three real roots */
269 //		{
270 //			D = SQRT (-D);
271 //			S = CBRT (hypot (R, D));
272 //			T = atan2 (D, R) / 3;
273 //			SINCOS (T, sinT, cosT);
274 //
275 //			/* the larger positive root is    2*S*cos(T)                   */
276 //			/* the smaller positive root is   -S*cos(T) + SQRT(3)*S*sin(T) */
277 //			/* the negative root is           -S*cos(T) - SQRT(3)*S*sin(T) */
278 //			Rd = -S * cosT + SQRT3 * S * sinT;	/* use the smaller positive root */
279 //		}
280 //
281 //		lambda = Rd / Ru;
282 //
283 //		Xd = Xu * lambda;
284 //		Yd = Yu * lambda;
285 //	}
286 //
287 //
288 //void correction(double k, float i, float j, float &disi, float &disj)
289 //{
290 //	// (i,j)		punto nell'immagine distorta
291 //	// (disi,disj)	punto nell'immagine corretta (undistorted)
292 //	float hyp;
293 //	float I,J,ni,nj;
294 //	float ratio = 1;
295 //
296 //	ni = i-viewport[0]/2;
297 //	nj = j-viewport[1]/2;
298 //	hyp = ni*ni + nj*nj;
299 //
300 //	I = ni * (1+ k * hyp);
301 //	J = nj * (1+ k * hyp);
302 //
303 //	disi = (I*ratio+viewport[0]/2);
304 //	disj = (J*ratio+viewport[1]/2);
305 //}
306 //
307 //
308 //
309 //void distorsion( float k ,float i, float j,double & disi, double &disj)
310 //{
311 //		// (i,j)		punto nell'immagine corretta (undistorted)
312 //	// (disi,disj)	punto nell'immagine distorta
313 //	float hyp;
314 //	int _I,_J;
315 //	float I,J,ni,nj;
316 //	I = i-viewport[0]/2;
317 //	J = j-viewport[1]/2;
318 //	hyp = sqrt(I*I + J*J);
319 //	if((k==0.0) || (hyp <0.001))
320 //		{
321 //		disi = i;
322 //		disj = j;
323 //		}
324 //	else
325 //		{
326 //		undistorted_to_distorted_sensor_coord (I, J, disi, disj);
327 //		disi += viewport[0]/2;
328 //		disj += viewport[1]/2;
329 //
330 //
331 ////	hyp = (viewport[0]*viewport[0] + viewport[1]*viewport[1])/4;
332 ////	ni = SX/2 + SX/2 * cam.k[0] * hyp;
333 /////	nj = SY/2 + SY/2 * cam.k[0] * hyp;
334 ////	float ratio = sqrt(hyp/(ni*ni + nj*nj));
335 //	float ratio=1;
336 //
337 //
338 //
339 //	//----------- Maple
340 //	//  float t0,t1,t2,sol;
341 //
342 //	//t0 = 1/k*pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k,0.3333333333333333)/6.0-2.0/pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k,0.3333333333333333);
343 //
344 //
345 //	//t1 = -1/k*pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k,0.3333333333333333)/12.0+1/pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*
346 //	//hyp*k)/k))*k*k,0.3333333333333333)+sqrt(-1.0)*sqrt(3.0)*(1/k*pow((108.0*hyp+
347 //	//12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k,0.3333333333333333)/6.0+2.0/
348 //	//pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k,
349 //	//0.3333333333333333))/2.0;
350 //
351 //	//t2 = -1/k*pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k,0.3333333333333333)/12.0+1/pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*
352 //	//hyp*k)/k))*k*k,0.3333333333333333)-sqrt(-1.0)*sqrt(3.0)*(1/k*pow((108.0*hyp+
353 //	//12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k,0.3333333333333333)/6.0+2.0/
354 //	//pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k,
355 //	//0.3333333333333333))/2.0;
356 //
357 //	//sol = (t0>t1)?t0:t1;
358 //	//sol = (sol<t2)?t2:sol;
359 //	//sol = t0;
360 //	//ni = sol*I/hyp;
361 //	//nj = sol*J/hyp;
362 //	////-----------
363 //
364 //	//disi = (ni*ratio+viewport[0]/2);
365 //	//disj = (nj*ratio+viewport[1]/2);
366 //		}
367 //}
368 //	void ResizeGridMap(const int & si,const int & sj ){
369 //			int j;
370 //			gridMap.resize(sj+1);
371 //			for(j=0; j < sj+1; j++)
372 //					gridMap[j].resize(si+1);
373 //		}
374 //	void UpdateGridMap(){
375 //		int sj = gridMap.size();
376 //		int si = gridMap[0].size();
377 //		int i,j;
378 //		for(j=0; j < sj; j++)
379 //			for(i=0; i < gridMap[0].size(); i++)
380 //			//		gridMap[i][j] = Point2<scalar> (i/(double)(si-1),j/(double)(sj-1));
381 //				{
382 //					double disi,disj;
383 //					distorsion( k[0] ,(i/(double)(si-1))*viewport[0], (j/(double)(sj-1))*viewport[1],disi,disj);
384 //					gridMap[i][j] = Point2<scalar> (disi/viewport[0],disj/viewport[1]);
385 //				}
386 //		}
387 //
388 //	inline Camera()
389 //	{
390 //		k[0]=k[1]=k[2]=k[3]=0.0;
391 //		valid = false;
392 //		ortho = false;
393 //		ResizeGridMap(100,100);// da spostare altrove
394 //	}
395 //
396 //	inline bool IsValid()
397 //	{
398 //		return valid;
399 //	}
400 //
401 //	inline bool IsOrtho() const
402 //	{
403 //		return ortho;
404 //	}
405 //
406 //	inline void SetInvalid()
407 //	{
408 //		valid = false;
409 //	}
410 //
411 //	inline void SetOrtho(bool isOrtho=true)
412 //	{
413 //		ortho = isOrtho;
414 //	}
415 //
416 //		// Genera una camera standard
417 //	void Standard()
418 //	{
419 //		valid = true;
420 //		ortho = false;
421 //		view_p  = vectorial(0,0,0);
422 //		x_axis  = vectorial(1,0,0);
423 //		y_axis  = vectorial(0,1,0);
424 //		z_axis  = vectorial(0,0,1);
425 //		f       = 25.75;
426 //		s       = Point2<S>(0.0074,0.0074);
427 //		c       = Point2<S>(320,240);
428 //		viewport[0] = 640;
429 //		viewport[1] = 480;
430 //		k[0]    = 0;
431 //		k[1]    = 0;
432 //		k[2]    = 0;
433 //		k[3]    = 0;
434 //	}
435 //
436 //		// Trasla la camera (world coordinate)
437 //	inline void Translate( const vectorial & t )
438 //	{
439 //		view_p += t;
440 //	}
441 //
442 //		// Trasla la camera (camera coordinate)
443 //	inline void Move( const vectorial & t )
444 //	{
445 //		view_p+= x_axis * t[0]+y_axis * t[1] + z_axis * t[2];
446 //	}
447 //
448 //	// scala la camera
449 //	inline void Scale(const scalar & sc){
450 //		view_p *=sc;
451 //		s[0]*=sc;
452 //		s[1]*=sc;
453 //		f*=sc;
454 //		//printf("sc\n");
455 //	}
456 //
457 //
458 //
459 //		// NOTA funziona solo se l'ultima colonna di m e' 0,0,0,1
460 //	void Apply( const Matrix44<S> & m )
461 //	{
462 //			// Passo 1: calcolo pseudo inversa di m
463 //		S s11,s12,s13;
464 //		S s21,s22,s23;
465 //		S s31,s32,s33;
466 //		S s41,s42,s43;
467 //
468 //		{
469 //			S t4  = m[0][0]*m[1][1];
470 //			S t6  = m[0][0]*m[2][1];
471 //			S t8  = m[1][0]*m[0][1];
472 //			S t10 = m[1][0]*m[2][1];
473 //			S t12 = m[2][0]*m[0][1];
474 //			S t14 = m[2][0]*m[1][1];
475 //			S t17 = 1/(t4*m[2][2]-t6*m[1][2]-t8*m[2][2]+t10*m[0][2]+t12*m[1][2]-t14*m[0][2]);
476 //			S t27 = m[1][0]*m[2][2];
477 //			S t28 = m[2][0]*m[1][2];
478 //			S t31 = m[0][0]*m[2][2];
479 //			S t32 = m[2][0]*m[0][2];
480 //			S t35 = m[0][0]*m[1][2];
481 //			S t36 = m[1][0]*m[0][2];
482 //			S t49 = m[3][0]*m[1][1];
483 //			S t51 = m[3][0]*m[2][1];
484 //			S t59 = m[3][0]*m[0][1];
485 //			s11 = -(-m[1][1]*m[2][2]+m[2][1]*m[1][2])*t17;
486 //			s12 = -( m[0][1]*m[2][2]-m[2][1]*m[0][2])*t17;
487 //			s13 =  ( m[0][1]*m[1][2]-m[1][1]*m[0][2])*t17;
488 //			s21 =  (-t27+t28)*t17;
489 //			s22 = -(-t31+t32)*t17;
490 //			s23 = -( t35-t36)*t17;
491 //			s31 = -(-t10+t14)*t17;
492 //			s32 =  (-t6 +t12)*t17;
493 //			s33 =  ( t4 -t8 )*t17;
494 //			s41 = -(t10*m[3][2]-t27*m[3][1]-t14*m[3][2]+t28*m[3][1]+t49*m[2][2]-t51*m[1][2])*t17;
495 //			s42 = -(-t6*m[3][2]+t31*m[3][1]+t12*m[3][2]-t32*m[3][1]-t59*m[2][2]+t51*m[0][2])*t17;
496 //			s43 =  (-t4*m[3][2]+t35*m[3][1]+t8 *m[3][2]-t36*m[3][1]-t59*m[1][2]+t49*m[0][2])*t17;
497 //			1.0;
498 //		}
499 //
500 //		//Matrix44<S> t2 = tt*m;
501 //		//print(t2);
502 //			// Fase 2: Calcolo nuovo punto di vista
503 //		{
504 //			S t1  = view_p[2]*s31;
505 //			S t3  = view_p[2]*s21;
506 //			S t5  = s43*s21;
507 //			S t7  = s43*s31;
508 //			S t9  = view_p[1]*s31;
509 //			S t11 = view_p[1]*s21;
510 //			S t13 = s42*s31;
511 //			S t15 = s42*s21;
512 //			S t17 = view_p[0]*s32;
513 //			S t19 = view_p[0]*s22;
514 //			S t21 = s41*s32;
515 //			S t23 = s41*s22;
516 //			S t25 = -t1*s22+t3*s32-t5*s32+t7*s22+t9*s23-t11*s33-t13*s23+t15*s33-t17*s23+t19*s33+t21*s23-t23*s33;
517 //			S t39 = 1/(s11*s22*s33-s11*s32*s23-s21*s12*s33+s21*s32*s13+s31*s12*s23-s31*s22*s13);
518 //			S t41 = view_p[0]*s12;
519 //			S t45 = s41*s12;
520 //			S t47 = view_p[2]*s11;
521 //			S t50 = s43*s11;
522 //			S t53 = view_p[1]*s11;
523 //			S t56 = s42*s11;
524 //			S t59 = t41*s33-t17*s13+t21*s13-t45*s33+t47*s32-t1*s12-t50*s32+t7*s12-t53*s33+t9*s13+t56*s33-t13*s13;
525 //			S t73 = t15*s13-t56*s23+t19*s13-t41*s23-t23*s13+t45*s23-t11*s13+t53*s23+t3*s12-t47*s22-t5*s12+t50*s22;
526 //
527 //			view_p[0] =  t25*t39;
528 //			view_p[1] = -t59*t39;
529 //			view_p[2] = -t73*t39;
530 //		}
531 //
532 //			// Fase 3: Calcol nuovo sistema di riferimento
533 //		{
534 //			S A00 = s11*x_axis[0]+s12*x_axis[1]+s13*x_axis[2];
535 //			S A01 = s11*y_axis[0]+s12*y_axis[1]+s13*y_axis[2];
536 //			S A02 = s11*z_axis[0]+s12*z_axis[1]+s13*z_axis[2];
537 //		//	S A03 = 0.0;
538 //			S A10 = s21*x_axis[0]+s22*x_axis[1]+s23*x_axis[2];
539 //			S A11 = s21*y_axis[0]+s22*y_axis[1]+s23*y_axis[2];
540 //			S A12 = s21*z_axis[0]+s22*z_axis[1]+s23*z_axis[2];
541 //		//	S A13 = 0.0;
542 //			S A20 = s31*x_axis[0]+s32*x_axis[1]+s33*x_axis[2];
543 //			S A21 = s31*y_axis[0]+s32*y_axis[1]+s33*y_axis[2];
544 //			S A22 = s31*z_axis[0]+s32*z_axis[1]+s33*z_axis[2];
545 //
546 //			x_axis[0] = A00; x_axis[1] = A10; x_axis[2] = A20;
547 //			y_axis[0] = A01; y_axis[1] = A11; y_axis[2] = A21;
548 //			z_axis[0] = A02; z_axis[1] = A12; z_axis[2] = A22;
549 //		//	S A1[2][3] = 0.0;
550 //		//	S A1[3][0] = 0.0;
551 //		//	S A1[3][1] = 0.0;
552 //		//	S A1[3][2] = 0.0;
553 //		//	S A1[3][3] = 1.0;
554 //		}
555 //	}
556 //
557 //	/*
558 //		// Applica una trasformazione
559 //	void Apply( const Matrix44<S> & m )
560 //	{
561 //		Point3<S> tx = view_p+x_axis;
562 //		Point3<S> ty = view_p+y_axis;
563 //		Point3<S> tz = view_p+z_axis;
564 //
565 //		view_p = m.Apply(view_p);
566 //
567 //		x_axis = m.Apply(tx) - view_p;
568 //		y_axis = m.Apply(ty) - view_p;
569 //		z_axis = m.Apply(tz) - view_p;
570 //	}
571 //
572 //			// Applica una trasformazione ma bene!
573 //	void Stable_Apply( const Matrix44<S> & m )
574 //	{
575 //		Point3<S> tx = view_p+x_axis;
576 //		Point3<S> ty = view_p+y_axis;
577 //		Point3<S> tz = view_p+z_axis;
578 //
579 //		view_p = m.Stable_Apply(view_p);
580 //
581 //		x_axis = m.Stable_Apply(tx) - view_p;
582 //		y_axis = m.Stable_Apply(ty) - view_p;
583 //		z_axis = m.Stable_Apply(tz) - view_p;
584 //	}
585 //
586 //	*/
587 //
588 //	void Project( const vectorial & p, Point2<S> & q ) const
589 //	{
590 //		vectorial dp = p - view_p;
591 //		S  dx = dp*x_axis;
592 //		S  dy = dp*y_axis;
593 //		S  dz = dp*z_axis;
594 //
595 //		S  tx = dx;
596 //		S  ty = -dy;
597 //		S  qx,qy;
598 //
599 //		// nota: per le camere ortogonali viewportM vale 1
600 //		if(!IsOrtho())
601 //		{
602 //			tx *= f/dz;
603 //			ty *= f/dz;
604 //
605 //			undistorted_to_distorted_sensor_coord(tx,ty,qx,qy);
606 //
607 //			q[0] = qx/s[0]+c[0];
608 //			q[1] = qy/s[1]+c[1];
609 //		}
610 //		else
611 //		{
612 //			q[0] = tx/(s[0]*viewportM)+c[0];
613 //			q[1] = ty/(s[1]*viewportM)+c[1];
614 //		}
615 //	}
616 //
617 //#if 1
618 //	void Show( FILE * fp )
619 //	{
620 //		if(valid)
621 //			fprintf(fp,
622 //				"posiz.: %g %g %g\n"
623 //				"x axis: %g %g %g\n"
624 //				"y axis: %g %g %g\n"
625 //				"z axis: %g %g %g\n"
626 //				"focal : %g  scale: %g %g  center: %g %g\n"
627 //				"viewp.: %d %d  distorsion: %g %g %g %g\n"
628 //				,view_p[0],view_p[1],view_p[2]
629 //				,x_axis[0],x_axis[1],x_axis[2]
630 //				,y_axis[0],y_axis[1],y_axis[2]
631 //				,z_axis[0],z_axis[1],z_axis[2]
632 //				,f,s[0],s[1],c[0],c[1]
633 //				,viewport[0],viewport[1],k[0],k[1],k[2],k[3]
634 //			);
635 //		else
636 //			fprintf(fp,"Invalid\n");
637 //	}
638 //#endif
639 //
640 //		// Legge una camera in descrizione tsai binario
641 //	static void load_tsai_bin (FILE *fp, tsai_camera_parameters *cp, tsai_calibration_constants *cc)
642 //	{
643 //		double    sa,
644 //				  ca,
645 //				  sb,
646 //				  cb,
647 //				  sg,
648 //				  cg;
649 //
650 //		fread(&(cp->Ncx),sizeof(double),1,fp);
651 //		fread(&(cp->Nfx),sizeof(double),1,fp);
652 //		fread(&(cp->dx),sizeof(double),1,fp);
653 //		fread(&(cp->dy),sizeof(double),1,fp);
654 //		fread(&(cp->dpx),sizeof(double),1,fp);
655 //		fread(&(cp->dpy),sizeof(double),1,fp);
656 //		fread(&(cp->Cx),sizeof(double),1,fp);
657 //		fread(&(cp->Cy),sizeof(double),1,fp);
658 //		fread(&(cp->sx),sizeof(double),1,fp);
659 //
660 //		fread(&(cc->f),sizeof(double),1,fp);
661 //		fread(&(cc->kappa1),sizeof(double),1,fp);
662 //		fread(&(cc->Tx),sizeof(double),1,fp);
663 //		fread(&(cc->Ty),sizeof(double),1,fp);
664 //		fread(&(cc->Tz),sizeof(double),1,fp);
665 //		fread(&(cc->Rx),sizeof(double),1,fp);
666 //		fread(&(cc->Ry),sizeof(double),1,fp);
667 //		fread(&(cc->Rz),sizeof(double),1,fp);
668 //
669 //
670 //		SINCOSd (cc->Rx, sa, ca);
671 //		SINCOSd (cc->Ry, sb, cb);
672 //		SINCOSd (cc->Rz, sg, cg);
673 //
674 //		cc->r1 = cb * cg;
675 //		cc->r2 = cg * sa * sb - ca * sg;
676 //		cc->r3 = sa * sg + ca * cg * sb;
677 //		cc->r4 = cb * sg;
678 //		cc->r5 = sa * sb * sg + ca * cg;
679 //		cc->r6 = ca * sb * sg - cg * sa;
680 //		cc->r7 = -sb;
681 //		cc->r8 = cb * sa;
682 //		cc->r9 = ca * cb;
683 //
684 //		fread(&(cc->p1),sizeof(double),1,fp);
685 //		fread(&(cc->p2),sizeof(double),1,fp);
686 //	}
687 //
688 //	void load_tsai (FILE *fp, tsai_camera_parameters *cp, tsai_calibration_constants *cc)
689 //	{
690 //		double    sa,
691 //				  ca,
692 //				  sb,
693 //				  cb,
694 //				  sg,
695 //				  cg;
696 //
697 //		fscanf (fp, "%lf", &(cp->Ncx));
698 //		fscanf (fp, "%lf", &(cp->Nfx));
699 //		fscanf (fp, "%lf", &(cp->dx));
700 //		fscanf (fp, "%lf", &(cp->dy));
701 //		fscanf (fp, "%lf", &(cp->dpx));
702 //		fscanf (fp, "%lf", &(cp->dpy));
703 //		fscanf (fp, "%lf", &(cp->Cx));
704 //		fscanf (fp, "%lf", &(cp->Cy));
705 //		fscanf (fp, "%lf", &(cp->sx));
706 //
707 //		fscanf (fp, "%lf", &(cc->f));
708 //		fscanf (fp, "%lf", &(cc->kappa1));
709 //		fscanf (fp, "%lf", &(cc->Tx));
710 //		fscanf (fp, "%lf", &(cc->Ty));
711 //		fscanf (fp, "%lf", &(cc->Tz));
712 //		fscanf (fp, "%lf", &(cc->Rx));
713 //		fscanf (fp, "%lf", &(cc->Ry));
714 //		fscanf (fp, "%lf", &(cc->Rz));
715 //
716 //		SINCOSd (cc->Rx, sa, ca);
717 //		SINCOSd (cc->Ry, sb, cb);
718 //		SINCOSd (cc->Rz, sg, cg);
719 //
720 //		cc->r1 = cb * cg;
721 //		cc->r2 = cg * sa * sb - ca * sg;
722 //		cc->r3 = sa * sg + ca * cg * sb;
723 //		cc->r4 = cb * sg;
724 //		cc->r5 = sa * sb * sg + ca * cg;
725 //		cc->r6 = ca * sb * sg - cg * sa;
726 //		cc->r7 = -sb;
727 //		cc->r8 = cb * sa;
728 //		cc->r9 = ca * cb;
729 //
730 //		fscanf (fp, "%lf", &(cc->p1));
731 //		fscanf (fp, "%lf", &(cc->p2));
732 //	}
733 //
734 //		// Importa una camera dal formato tsai
735 //	void import( const tsai_camera_parameters & cp,
736 //		         const tsai_calibration_constants & cc,
737 //				 const int image_viewport[2]
738 //			   )
739 //	{
740 //		assert(!IsOrtho());
741 //		valid = true;
742 //		x_axis[0] = cc.r1; x_axis[1] = cc.r2; x_axis[2] = cc.r3;
743 //		y_axis[0] = cc.r4; y_axis[1] = cc.r5; y_axis[2] = cc.r6;
744 //		z_axis[0] = cc.r7; z_axis[1] = cc.r8; z_axis[2] = cc.r9;
745 //
746 //		view_p[0] = - (cc.Tx * x_axis[0] + cc.Ty * y_axis[0] + cc.Tz * z_axis[0]);
747 //		view_p[1] = - (cc.Tx * x_axis[1] + cc.Ty * y_axis[1] + cc.Tz * z_axis[1]);
748 //		view_p[2] = - (cc.Tx * x_axis[2] + cc.Ty * y_axis[2] + cc.Tz * z_axis[2]);
749 //
750 //		s[0] = cp.dpx/cp.sx;
751 //		s[1] = cp.dpy;
752 //		c[0] = cp.Cx;
753 //		c[1] = cp.Cy;
754 //
755 //		f = cc.f;
756 //		viewport[0] = image_viewport[0];
757 //		viewport[1] = image_viewport[1];
758 //
759 //		k[0] = cc.kappa1;
760 //		k[1] = cc.kappa1;
761 //		k[2] = 0;
762 //		k[2] = 0;
763 //	}
764 //
765 //		// Esporta una camera in formato tsai
766 //	void export( tsai_camera_parameters & cp,
767 //		         tsai_calibration_constants & cc,
768 //				 int image_viewport[2]
769 //			   )
770 //	{
771 //		assert(!IsOrtho());
772 //		cc.r1 = x_axis[0];  cc.r2 = x_axis[1]; cc.r3= x_axis[2] ;
773 //		cc.r4 = y_axis[0];  cc.r5 = y_axis[1]; cc.r6= y_axis[2] ;
774 //		cc.r7 = z_axis[0];  cc.r8 = z_axis[1]; cc.r9= z_axis[2] ;
775 //
776 //		cc.Tx = - (view_p[0] * x_axis[0] + view_p[1] * x_axis[1] + view_p[2] * x_axis[2]);
777 //		cc.Ty = - (view_p[0] * y_axis[0] + view_p[1] * y_axis[1] + view_p[2] * y_axis[2]);
778 //		cc.Tz = - (view_p[0] * z_axis[0] + view_p[1] * z_axis[1] + view_p[2] * z_axis[2]);
779 //
780 //		cp.dpx = s[0];
781 //		cp.dpy = s[1];
782 //
783 //		cp.Cx=  c[0] ;
784 //		cp.Cy=  c[1] ;
785 //		cp.sx= 1;
786 //
787 //		cc.f= f ;
788 //
789 //		image_viewport[0] = viewport[0];
790 //		image_viewport[1] = viewport[1];
791 //
792 //		cc.kappa1= k[0] ;
793 //		cc.kappa1= k[1] ;
794 //	}
795 //
796 //
797 //	void Save(FILE * out)
798 //	{
799 //		fprintf(out,"VIEW_POINT %f %f %f\n",	view_p[0],view_p[1],view_p[2]);
800 //		fprintf(out,"X_AXIS		%f %f %f\n",	x_axis[0],x_axis[1],x_axis[2]);
801 //		fprintf(out,"Y_AXIS		%f %f %f\n",	y_axis[0],y_axis[1],y_axis[2]);
802 //		fprintf(out,"Z_AXIS		%f %f %f\n",	z_axis[0],z_axis[1],z_axis[2]);
803 //		fprintf(out,"FOCUS_LENGHT  %f \n",	 f);
804 //		fprintf(out,"SCALE  %f %f \n",	 s[0], s[1]);
805 //		fprintf(out,"VIEWPORT  %d %d \n",	 viewport[0], viewport[1]);
806 //		fprintf(out,"VIEWPORTM %f\n",	 viewportM);
807 //		fprintf(out,"RADIAL_DISTORSION %.10g %.10g \n",	 k[0],k[1]);
808 //		fprintf(out,"CENTER  %f %f \n",	 c[0], c[1]);
809 //		fprintf(out,"IS_VALID %d\n", IsValid());
810 //		fprintf(out,"END_CAMERA\n");
811 //	}
812 //
813 //	void Load(FILE * in)
814 //	{
815 //		char row[255];
816 //		Standard();
817 //	while(!feof(in))
818 //			{
819 //				fscanf(in,"%s",row);
820 //				if(strcmp(row,"VIEW_POINT")==0)
821 //	  				fscanf(in,"%lg %lg %lg",&view_p[0],&view_p[1],&view_p[2]);
822 //				else
823 //				if(strcmp(row,"X_AXIS")==0)
824 //					fscanf(in,"%lg %lg %lg",&	x_axis[0],&x_axis[1],&x_axis[2]);
825 //				else
826 //				if(strcmp(row,"Y_AXIS")==0)
827 //					fscanf(in,"%lg %lg %lg",&	y_axis[0],&y_axis[1],&y_axis[2]);
828 //				else
829 //				if(strcmp(row,"Z_AXIS")==0)
830 //					fscanf(in,"%lg %lg %lg",&	z_axis[0],&z_axis[1],&z_axis[2]);
831 //				else
832 //				if(strcmp(row,"FOCUS_LENGHT")==0)
833 //					fscanf(in,"%lg",&f);
834 //				else
835 //				if(strcmp(row,"SCALE")==0)
836 //					fscanf(in,"%lg %lg",&s[0],&s[1]);
837 //				else
838 //				if(strcmp(row,"VIEWPORT")==0)
839 //					fscanf(in,"%d %d",	&viewport[0],&viewport[1]);
840 //				else
841 //				if(strcmp(row,"VIEWPORTM")==0)
842 //					fscanf(in,"%f",	&viewportM);
843 //				else
844 //				if(strcmp(row,"CENTER")==0)
845 //					fscanf(in,"%lg %lg",	&c[0],&c[1]);
846 //				else
847 //				if(strcmp(row,"RADIAL_DISTORSION")==0)
848 //					fscanf(in,"%lg %lg",	&k[0],&k[1]);
849 //				else
850 //				if(strcmp(row,"IS_VALID")==0)
851 //					fscanf(in,"%d",&valid);
852 //				if(strcmp(row,"END_CAMERA")==0)
853 //					break;
854 //			}
855 //	}
856 //
857 //#ifdef __GL_H__
858 //
859 //// Prende in ingresso il bounding box dell'oggetto da inquadrare e setta projection e modelmatrix
860 //// in modo da matchare il piu' possibile quelle della camera. Ovviamente (?) si ignora le distorsioni radiali.
861 //// Nota che bb viene utilizzato solo per settare i near e far plane in maniera sensata.
862 //void SetGL(const Box3<scalar> &bb,scalar subx0=0, scalar subx1=1,scalar suby0=0,scalar suby1=1)
863 //{
864 //	scalar _,__;
865 //	SetGL(_,__,bb,subx0, subx1, suby0, suby1);
866 //
867 //}
868 //
869 //void SetGL(scalar &znear, scalar &zfar,const Box3<scalar> &bb,scalar subx0=0,
870 //		   scalar subx1=1,scalar suby0=0,scalar suby1=1)
871 //{
872 //	glMatrixMode(GL_PROJECTION);
873 //	glLoadIdentity();
874 //	scalar left,right;
875 //	scalar bottom, top;
876 //	scalar w,h;
877 //
878 //	// La lunghezza focale <f> e' la distanza del piano immagine dal centro di proiezione.
879 //	// il che mappa direttamente nella chiamata glFrustum che prende in ingresso
880 //	// le coordinate del piano immagine posto a znear.
881 //
882 //	float imleft   =-c[0]*s[0];
883 //	float imright  =(viewport[0]-c[0])*s[0];
884 //	float imbottom =-c[1]*s[1];
885 //	float imtop    =(viewport[1]-c[1])*s[1];
886 //	znear = Distance(view_p, bb.Center())-bb.Diag();
887 //	zfar  = Distance(view_p, bb.Center())+bb.Diag();
888 //
889 //	w=imright-imleft;
890 //	h=imtop-imbottom;
891 //
892 //	// Quindi il frustum giusto sarebbe questo,
893 //	//            glFrustum(imleft, imright, imbottom, imtop, f, zfar);
894 //  // ma per amor di opengl conviene spostare il near plane fino ad essere vicino all'oggetto da inquadrare.
895 //	// Cambiare f significa amplificare in maniera proporzionale anche i left right ecc.
896 //
897 //	// 8/5/02 Nota che il near plane va spostato verso l'oggetto solo se quello calcolato sopra e' maggiore di 'f'
898 //	// nota che potrebbe anche succedere che znear <0 (viewpoint vicino ad un oggetto con il bb allungato);
899 //	if(znear<f) znear=f;
900 //
901 //	float nof = znear/f;
902 //	if(subx0==0 && subx1 == 1 && suby0==0 && suby1 == 1)
903 //	{
904 //		if(!IsOrtho())
905 //			glFrustum(imleft*nof, imright*nof, imbottom*nof, imtop*nof, znear, zfar);
906 //		else
907 //			glOrtho(imleft*viewportM, imright*viewportM, imbottom*viewportM, imtop*viewportM, znear, zfar);
908 //	}
909 //	else {// nel caso si voglia fare subboxing
910 //		left   = imleft+w*subx0;
911 //		right  = imleft+w*subx1;
912 //		bottom = imbottom +h*suby0;
913 //		top    = imbottom +h*suby1;
914 //		{
915 //		if(!IsOrtho())
916 //			glFrustum(left*nof, right*nof, bottom*nof, top*nof, znear, zfar);
917 //		else
918 //			glOrtho(left*viewportM, right*viewportM, bottom*viewportM, top*viewportM, znear, zfar);
919 //		}
920 //	}
921 //
922 //	glMatrixMode(GL_MODELVIEW);
923 //	glLoadIdentity();
924 //	scalar l=max(scalar(1.0),view_p.Norm());
925 //	gluLookAt(view_p[0], view_p[1], view_p[2],
926 //						view_p[0] + (z_axis[0]*l),
927 //						view_p[1] + (z_axis[1]*l),
928 //						view_p[2] + (z_axis[2]*l),
929 //						y_axis[0],y_axis[1],y_axis[2]);
930 //}
931 //// Sposta la camera a caso di in maniera che l'angolo di variazione rispetto al punt c passato sia inferiore a RadAngle
932 ////
933 //void Jitter(Point3<scalar> c, scalar RadAngle)
934 //{
935 //	Point3<scalar> rnd(1.0 - 2.0*scalar(rand())/RAND_MAX,
936 //		                 1.0 - 2.0*scalar(rand())/RAND_MAX,
937 //										 1.0 - 2.0*scalar(rand())/RAND_MAX);
938 //	rnd.Normalize();
939 //	Matrix44<scalar> m,t0,t1,tr;
940 //	Point3<scalar> axis = rnd ^ (view_p-c).Normalize();
941 //	scalar RadRandAngle=RadAngle*(1.0 - 2.0*scalar(rand())/RAND_MAX);
942 //	t0.Translate(c);
943 //	t1.Translate(-c);
944 //	m.Rotate(ToDeg(RadRandAngle),axis);
945 //  tr=t1*m*t0;
946 //  Apply(tr);
947 //}
948 //
949 //
950 //
951 //
952 //void glTexGen(int offx =0, // angolo basso sinistra della
953 //			  int offy=0,  // subtexture per la quale si vogliono settare le coordinate
954 //			  int sx=1,    // Dimensioni in Texel
955 //			  int sy=1,
956 //			  int Tx=1,	   // Dimensioni della texture
957 //			  int Ty=1)
958 //{
959 //	// prendi la rototraslazione che
960 //	// trasforma la coordinata nel
961 //	// sistema di coordinate della camera
962 //	Matrix44d M;
963 //	M[0][0] =  x_axis[0];
964 //	M[0][1] =  x_axis[1];
965 //	M[0][2] =  x_axis[2];
966 //	M[0][3] = -view_p* x_axis ;
967 //
968 //	M[1][0] =  y_axis[0];
969 //	M[1][1] =  y_axis[1];
970 //	M[1][2] =  y_axis[2];
971 //	M[1][3] = -view_p* y_axis;
972 //
973 //	M[2][0] =  z_axis[0];
974 //	M[2][1] =  z_axis[1];
975 //	M[2][2] =  z_axis[2];
976 //	M[2][3] = -view_p* z_axis;
977 //
978 //	M[3][0] = 0.0;
979 //	M[3][1] = 0.0;
980 //	M[3][2] = 0.0;
981 //	M[3][3] = 1.0;
982 //
983 //	//	prendi la matrice di proiezione
984 //	Matrix44d P;
985 //	P.SetZero();
986 //
987 //	if(!IsOrtho())//  prospettica
988 //	{
989 //
990 //		P[0][0] = sx/(s[0]*viewport[0]*Tx);
991 //		P[0][2] = (1/f)*(offx+0.5*sx)/Tx;
992 //
993 //		P[1][1] = sy/(s[1]* viewport[1]*Ty);
994 //		P[1][2] = (1/f)*(offy+0.5*sy)/Ty;
995 //
996 //		P[2][2] = 1;
997 //		P[3][2] = 1/f;
998 //	}
999 //	else //  ortogonale
1000 //	{
1001 //		P[0][0] = sx/(s[0]*viewport[0]*viewportM*Tx);
1002 //		P[0][3] =  (offx+0.5*sx)/Tx; // l'effetto e' una traslazione di +1/2
1003 //
1004 //		P[1][1] = sy/(s[1]* viewport[1]*viewportM*Ty);
1005 //		P[1][3] =  (offy+0.5*sy)/Ty; // l'effetto e' una traslazione di +1/2
1006 //
1007 //		P[2][2] = 1;
1008 //		P[3][3] = 1;
1009 //	}
1010 //	// componi
1011 //	Matrix44d PM = P*M;
1012 //
1013 //	glTexGend(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1014 //	glTexGend(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1015 //	glTexGend(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1016 //
1017 //	glTexGendv(GL_S,GL_OBJECT_PLANE,&PM[0][0]);
1018 //	glTexGendv(GL_T,GL_OBJECT_PLANE,&PM[1][0]);
1019 //	glTexGendv(GL_Q,GL_OBJECT_PLANE,&PM[3][0]);
1020 //
1021 //	glEnable(GL_TEXTURE_GEN_S);
1022 //	glEnable(GL_TEXTURE_GEN_T);
1023 //	glDisable(GL_TEXTURE_GEN_R);
1024 //	glEnable(GL_TEXTURE_GEN_Q);
1025 //}
1026 //
1027 //// versione per le texture rettangolare NV_TEXTURE_RECTANGLE
1028 //// la differenza da glTexGen e' che il mapping e' in [0..sx]X[0..sy]
1029 //void glTexGen_NV(int sx,    // Texture Size
1030 //				 int sy)
1031 //{
1032 //	// prendi la rototraslazione che
1033 //	// trasforma la coordinata nel
1034 //	// sistema di coordinate della camera
1035 //	Matrix44d M;
1036 //	M[0][0] =  x_axis[0];
1037 //	M[0][1] =  x_axis[1];
1038 //	M[0][2] =  x_axis[2];
1039 //	M[0][3] = -view_p* x_axis ;
1040 //
1041 //	M[1][0] =  y_axis[0];
1042 //	M[1][1] =  y_axis[1];
1043 //	M[1][2] =  y_axis[2];
1044 //	M[1][3] = -view_p* y_axis;
1045 //
1046 //	M[2][0] =  z_axis[0];
1047 //	M[2][1] =  z_axis[1];
1048 //	M[2][2] =  z_axis[2];
1049 //	M[2][3] = -view_p* z_axis;
1050 //
1051 //	M[3][0] = 0.0;
1052 //	M[3][1] = 0.0;
1053 //	M[3][2] = 0.0;
1054 //	M[3][3] = 1.0;
1055 //
1056 //	//	prendi la matrice di proiezione
1057 //	Matrix44d P;
1058 //	P.SetZero();
1059 //
1060 //	if(!IsOrtho())//  prospettica
1061 //	{
1062 //
1063 //		P[0][0] = sx/(s[0]*viewport[0]);
1064 //		P[0][2] = sx*(1/f)*( 0.5);
1065 //
1066 //		P[1][1] = sy/(s[1]* viewport[1] );
1067 //		P[1][2] = sy*(1/f)*( 0.5);
1068 //
1069 //		P[2][2] = 1;
1070 //		P[3][2] = 1/f;
1071 //	}
1072 //	else //  ortogonale
1073 //	{
1074 //		P[0][0] = sx/(s[0]*viewport[0]*viewportM);
1075 //		P[0][3] = sx*  0.5 ; // l'effetto e' una traslazione di +1/2
1076 //
1077 //		P[1][1] = sy/(s[1]* viewport[1]*viewportM);
1078 //		P[1][3] = sy*  0.5 ; // l'effetto e' una traslazione di +1/2
1079 //
1080 //		P[2][2] = 1;
1081 //		P[3][3] = 1;
1082 //	}
1083 //	// componi
1084 //	Matrix44d PM = P*M;
1085 //
1086 //	glTexGend(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1087 //	glTexGend(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1088 //	glTexGend(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1089 //
1090 //	glTexGendv(GL_S,GL_OBJECT_PLANE,&PM[0][0]);
1091 //	glTexGendv(GL_T,GL_OBJECT_PLANE,&PM[1][0]);
1092 //	glTexGendv(GL_Q,GL_OBJECT_PLANE,&PM[3][0]);
1093 //
1094 //	glEnable(GL_TEXTURE_GEN_S);
1095 //	glEnable(GL_TEXTURE_GEN_T);
1096 //	glDisable(GL_TEXTURE_GEN_R);
1097 //	glEnable(GL_TEXTURE_GEN_Q);
1098 ////	glDisable(GL_TEXTURE_GEN_Q);
1099 //
1100 //}
1101 //#endif // __GL_H__
1102 //
1103 //};
1104 //}	// End namespace vcg
1105