0021357: Transform persistence bug
[occt.git] / src / OpenGl / OpenGl_View.cxx
CommitLineData
b311480e 1// Created on: 2011-09-20
2// Created by: Sergey ZERCHANINOV
3// Copyright (c) 2011-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
5f8b738e 20#include <OpenGl_GlCore11.hxx>
21
2166f0fa 22#include <OpenGl_View.hxx>
bf75be98 23#include <OpenGl_Context.hxx>
2166f0fa
SK
24#include <OpenGl_Workspace.hxx>
25#include <OpenGl_Display.hxx>
26
bf75be98 27#include <OpenGl_Texture.hxx>
2166f0fa
SK
28#include <OpenGl_Trihedron.hxx>
29#include <OpenGl_GraduatedTrihedron.hxx>
30
31#include <OpenGl_transform_persistence.hxx>
32
bf75be98 33#include <Graphic3d_TextureEnv.hxx>
34
5f8b738e 35#include <GL/glu.h> // gluUnProject()
36
2166f0fa
SK
37IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
38IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
39
40/*----------------------------------------------------------------------*/
41
42static const OPENGL_BG_TEXTURE myDefaultBgTexture = { 0, 0, 0, Aspect_FM_CENTERED };
43static const OPENGL_BG_GRADIENT myDefaultBgGradient = { {{ 0.F, 0.F, 0.F, 1.F }}, {{ 0.F, 0.F, 0.F, 1.F }}, Aspect_GFM_NONE };
44static const Tmatrix3 myDefaultMatrix = { { 1.F, 0.F, 0.F, 0.F }, { 0.F, 1.F, 0.F, 0.F }, { 0.F, 0.F, 1.F, 0.F }, { 0.F, 0.F, 0.F, 1.F } };
45static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
46static const OPENGL_EXTRA_REP myDefaultExtra =
47{
48 //vrp
49 { 0.F, 0.F, 0.F },
50 //vpn
51 { 0.F, 0.F, 1.F },
52 //vup
53 { 0.F, 1.F, 0.F },
54 //map
55 {
56 //window
57 { 0.F, 0.F, 1.F, 1.F },
58 //viewport
59 { 0.F, 0.F, 0.F, 1.F, 1.F, 1.F },
60 //proj
61 TelParallel,
62 //prp
63 { 0.F, 0.F, 0.F },
64 //vpd
65 0.F,
66 //fpd
67 0.F,
68 //bpd
69 -1.F
70 },
71 //scaleFactors
72 { 1.F, 1.F, 1.F }
73};
74
75static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
76static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
c34dba32 77static const GLdouble THE_IDENTITY_MATRIX[4][4] =
78{
79 {1.0, 0.0, 0.0, 0.0},
80 {0.0, 1.0, 0.0, 0.0},
81 {0.0, 0.0, 1.0, 0.0},
82 {0.0, 0.0, 0.0, 1.0}
83};
2166f0fa
SK
84
85/*----------------------------------------------------------------------*/
86
87OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext)
bf75be98 88: mySurfaceDetail(Visual3d_TOD_NONE),
2166f0fa
SK
89 myBackfacing(0),
90 myBgTexture(myDefaultBgTexture),
91 myBgGradient(myDefaultBgGradient),
92 //myOrientationMatrix(myDefaultMatrix),
93 //myMappingMatrix(myDefaultMatrix),
94 //shield_indicator = TOn,
95 //shield_colour = { { 0.F, 0.F, 0.F, 1.F } },
96 //border_indicator = TOff,
97 //border_colour = { { 0.F, 0.F, 0.F, 1.F } },
98 //active_status = TOn,
99 myZClip(myDefaultZClip),
100 myExtra(myDefaultExtra),
101 myFog(myDefaultFog),
102 myVisualization(AContext.Visualization),
103 myIntShadingMethod(TEL_SM_GOURAUD),
104 myAntiAliasing(Standard_False),
105 myAnimationListIndex(0),
106 myAnimationListReady(Standard_False),
107 myTransPers(&myDefaultTransPers),
108 myIsTransPers(Standard_False),
109 myResetFLIST(Standard_False)
110{
111 // Initialize matrices
112 memcpy(myOrientationMatrix,myDefaultMatrix,sizeof(Tmatrix3));
113 memcpy(myMappingMatrix,myDefaultMatrix,sizeof(Tmatrix3));
114
115 // Shading method
116 switch (AContext.Model)
117 {
118 case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
119 case 3 : /* VISUAL3D_TOM_VERTEX */
120 myIntShadingMethod = TEL_SM_GOURAUD;
121 break;
122 default :
123 myIntShadingMethod = TEL_SM_FLAT;
124 break;
125 }
126}
127
128/*----------------------------------------------------------------------*/
129
130OpenGl_View::~OpenGl_View ()
131{
bf75be98 132 ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
133}
134
135void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
136{
137 if (!myTextureEnv.IsNull())
138 {
139 theCtx->DelayedRelease (myTextureEnv);
140 myTextureEnv.Nullify();
141 }
142 if (myBgTexture.TexId != 0)
143 {
144 glDeleteTextures (1, (GLuint*)&(myBgTexture.TexId));
145 myBgTexture.TexId = 0;
146 }
2166f0fa 147 if (myAnimationListIndex)
bf75be98 148 {
149 glDeleteLists ((GLuint )myAnimationListIndex, 1);
150 myAnimationListIndex = 0;
151 }
152}
2166f0fa 153
bf75be98 154void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)& theCtx,
155 const Handle(Graphic3d_TextureEnv)& theTexture)
156{
157 if (!myTextureEnv.IsNull())
158 {
159 theCtx->DelayedRelease (myTextureEnv);
160 myTextureEnv.Nullify();
161 }
162
163 if (theTexture.IsNull())
164 {
165 return;
166 }
167
168 myTextureEnv = new OpenGl_Texture (theTexture->GetParams());
169 Handle(Image_PixMap) anImage = theTexture->GetImage();
170 myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
2166f0fa
SK
171}
172
173/*----------------------------------------------------------------------*/
174
175void OpenGl_View::SetBackfacing (const Standard_Integer AMode)
176{
177 myBackfacing = AMode;
178 myResetFLIST = Standard_True;
179}
180
181/*----------------------------------------------------------------------*/
182
183//call_togl_setlight
184void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT &AContext)
185{
186 myLights.Clear();
187
188 const int nb_lights = AContext.NbActiveLight;
189
190 int i = 0;
191 const CALL_DEF_LIGHT *alight = &(AContext.ActiveLight[0]);
192 for ( ; i < nb_lights; i++, alight++ )
193 {
194 OpenGl_Light rep;
195
196 switch( alight->LightType )
197 {
198 case 0 : /* TOLS_AMBIENT */
199 rep.type = TLightAmbient;
200 rep.col.rgb[0] = alight->Color.r;
201 rep.col.rgb[1] = alight->Color.g;
202 rep.col.rgb[2] = alight->Color.b;
203 break;
204
205 case 1 : /* TOLS_DIRECTIONAL */
206 rep.type = TLightDirectional;
207 rep.col.rgb[0] = alight->Color.r;
208 rep.col.rgb[1] = alight->Color.g;
209 rep.col.rgb[2] = alight->Color.b;
210 rep.dir[0] = alight->Direction.x;
211 rep.dir[1] = alight->Direction.y;
212 rep.dir[2] = alight->Direction.z;
213 break;
214
215 case 2 : /* TOLS_POSITIONAL */
216 rep.type = TLightPositional;
217 rep.col.rgb[0] = alight->Color.r;
218 rep.col.rgb[1] = alight->Color.g;
219 rep.col.rgb[2] = alight->Color.b;
220 rep.pos[0] = alight->Position.x;
221 rep.pos[1] = alight->Position.y;
222 rep.pos[2] = alight->Position.z;
223 rep.atten[0] = alight->Attenuation[0];
224 rep.atten[1] = alight->Attenuation[1];
225 break;
226
227 case 3 : /* TOLS_SPOT */
228 rep.type = TLightSpot;
229 rep.col.rgb[0] = alight->Color.r;
230 rep.col.rgb[1] = alight->Color.g;
231 rep.col.rgb[2] = alight->Color.b;
232 rep.pos[0] = alight->Position.x;
233 rep.pos[1] = alight->Position.y;
234 rep.pos[2] = alight->Position.z;
235 rep.dir[0] = alight->Direction.x;
236 rep.dir[1] = alight->Direction.y;
237 rep.dir[2] = alight->Direction.z;
238 rep.shine = alight->Concentration;
239 rep.atten[0] = alight->Attenuation[0];
240 rep.atten[1] = alight->Attenuation[1];
241 rep.angle = alight->Angle;
242 break;
243 }
244
245 rep.HeadLight = alight->Headlight;
246
247 myLights.Append(rep);
248 }
249}
250
251/*----------------------------------------------------------------------*/
252
253//call_togl_setplane
254void OpenGl_View::SetClippingPlanes (const CALL_DEF_VIEWCONTEXT &AContext)
255{
256 // clear clipping planes information
257 myClippingPlanes.Clear();
bf75be98 258 // update information
2166f0fa
SK
259 int i = 0;
260 for (; i < AContext.NbActivePlane; i++)
261 {
262 const CALL_DEF_PLANE &aCPlane = AContext.ActivePlane[i];
263 if ( aCPlane.Active && aCPlane.PlaneId > 0 )
264 {
265 OPENGL_CLIP_REP aPlane;
266 aPlane.equation[0] = aCPlane.CoefA;
267 aPlane.equation[1] = aCPlane.CoefB;
268 aPlane.equation[2] = aCPlane.CoefC;
269 aPlane.equation[3] = aCPlane.CoefD;
270 myClippingPlanes.Append( aPlane );
271 }
272 }
273}
274
275/*----------------------------------------------------------------------*/
276
277//call_togl_setvisualisation
278void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
279{
280 myVisualization = AContext.Visualization;
281 // Shading method
282 switch (AContext.Model)
283 {
284 case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
285 case 3 : /* VISUAL3D_TOM_VERTEX */
286 myIntShadingMethod = TEL_SM_GOURAUD;
287 break;
288 default :
289 myIntShadingMethod = TEL_SM_FLAT;
290 break;
291 }
292}
293
294/*----------------------------------------------------------------------*/
295
296//call_togl_cliplimit
bf75be98 297void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
2166f0fa
SK
298{
299 myZClip.Back.Limit =
bf75be98 300 (theCView.Context.ZClipBackPlane - theCView.Mapping.BackPlaneDistance) /
301 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
2166f0fa 302 myZClip.Front.Limit =
bf75be98 303 (theCView.Context.ZClipFrontPlane - theCView.Mapping.BackPlaneDistance) /
304 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
305 if (myZClip.Back.Limit < 0.0f)
306 myZClip.Back.Limit = 0.0f;
307 if (myZClip.Front.Limit > 1.0f)
308 myZClip.Front.Limit = 1.0f;
309 if (myZClip.Back.Limit > myZClip.Front.Limit)
2166f0fa 310 {
bf75be98 311 myZClip.Back.Limit = 0.0f;
312 myZClip.Front.Limit = 1.0f;
2166f0fa
SK
313 }
314
bf75be98 315 myZClip.Back.IsOn = (theCView.Context.BackZClipping != 0);
316 myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
2166f0fa
SK
317}
318
319/*----------------------------------------------------------------------*/
320
321//call_togl_viewmapping
bf75be98 322void OpenGl_View::SetMapping (const Graphic3d_CView& theCView)
2166f0fa 323{
bf75be98 324 const float ratio = theCView.DefWindow.dy / theCView.DefWindow.dx;
325 const float r_ratio = theCView.DefWindow.dx / theCView.DefWindow.dy;
2166f0fa
SK
326
327 TEL_VIEW_MAPPING Map;
328
bf75be98 329 Map.window.xmin = theCView.Mapping.WindowLimit.um;
330 Map.window.ymin = theCView.Mapping.WindowLimit.vm;
331 Map.window.xmax = theCView.Mapping.WindowLimit.uM;
332 Map.window.ymax = theCView.Mapping.WindowLimit.vM;
2166f0fa
SK
333
334 Map.viewport.xmin = 0.F;
335 Map.viewport.xmax = ( 1.F < r_ratio ? 1.F : r_ratio );
336 Map.viewport.ymin = 0.F;
337 Map.viewport.ymax = ( 1.F < ratio ? 1.F : ratio );
338 Map.viewport.zmin = 0.F;
339 Map.viewport.zmax = 1.F;
340
bf75be98 341 // projection type
342 switch (theCView.Mapping.Projection)
2166f0fa
SK
343 {
344 case 0 :
345 Map.proj = TelPerspective;
346 break;
347 case 1 :
348 Map.proj = TelParallel;
349 break;
350 }
351
bf75be98 352 // projection reference point
353 Map.prp[0] = theCView.Mapping.ProjectionReferencePoint.x;
354 Map.prp[1] = theCView.Mapping.ProjectionReferencePoint.y;
355 Map.prp[2] = theCView.Mapping.ProjectionReferencePoint.z;
2166f0fa 356 if (!openglDisplay.IsNull() && !openglDisplay->Walkthrough())
bf75be98 357 Map.prp[2] += theCView.Mapping.FrontPlaneDistance;
2166f0fa 358
bf75be98 359 // view plane distance
360 Map.vpd = theCView.Mapping.ViewPlaneDistance;
2166f0fa 361
bf75be98 362 // back plane distance
363 Map.bpd = theCView.Mapping.BackPlaneDistance;
2166f0fa 364
bf75be98 365 // front plane distance
366 Map.fpd = theCView.Mapping.FrontPlaneDistance;
2166f0fa
SK
367
368 Tint err_ind = 0;
369
bf75be98 370 // use user-defined matrix
371 if (theCView.Mapping.IsCustomMatrix)
2166f0fa
SK
372 {
373 int i, j;
374 for( i = 0; i < 4; i++ )
375 for( j = 0; j < 4; j++ )
bf75be98 376 myMappingMatrix[i][j] = theCView.Mapping.ProjectionMatrix[i][j];
2166f0fa 377 }
bf75be98 378 else
2166f0fa
SK
379 TelEvalViewMappingMatrix( &Map, &err_ind, myMappingMatrix );
380
bf75be98 381 if (!err_ind)
2166f0fa
SK
382 myExtra.map = Map;
383}
384
385/*----------------------------------------------------------------------*/
386
387//call_togl_vieworientation
bf75be98 388void OpenGl_View::SetOrientation (const Graphic3d_CView& theCView)
2166f0fa
SK
389{
390 Tfloat Vrp[3];
391 Tfloat Vpn[3];
392 Tfloat Vup[3];
393 Tfloat ScaleFactors[3];
394
bf75be98 395 Vrp[0] = theCView.Orientation.ViewReferencePoint.x;
396 Vrp[1] = theCView.Orientation.ViewReferencePoint.y;
397 Vrp[2] = theCView.Orientation.ViewReferencePoint.z;
2166f0fa 398
bf75be98 399 Vpn[0] = theCView.Orientation.ViewReferencePlane.x;
400 Vpn[1] = theCView.Orientation.ViewReferencePlane.y;
401 Vpn[2] = theCView.Orientation.ViewReferencePlane.z;
2166f0fa 402
bf75be98 403 Vup[0] = theCView.Orientation.ViewReferenceUp.x;
404 Vup[1] = theCView.Orientation.ViewReferenceUp.y;
405 Vup[2] = theCView.Orientation.ViewReferenceUp.z;
2166f0fa 406
bf75be98 407 ScaleFactors[0] = theCView.Orientation.ViewScaleX;
408 ScaleFactors[1] = theCView.Orientation.ViewScaleY;
409 ScaleFactors[2] = theCView.Orientation.ViewScaleZ;
2166f0fa
SK
410
411 Tint err_ind = 0;
412
413 // use user-defined matrix
bf75be98 414 if (theCView.Orientation.IsCustomMatrix)
2166f0fa
SK
415 {
416 int i, j;
417 for( i = 0; i < 4; i++ )
418 for( j = 0; j < 4; j++ )
bf75be98 419 myOrientationMatrix[i][j] = theCView.Orientation.ModelViewMatrix[i][j];
2166f0fa
SK
420 }
421 else
bf75be98 422 {
423 TelEvalViewOrientationMatrix (Vrp, Vpn, Vup, ScaleFactors, &err_ind, myOrientationMatrix);
424 }
2166f0fa 425
bf75be98 426 if (!err_ind)
2166f0fa
SK
427 {
428 myExtra.vrp[0] = Vrp[0];
429 myExtra.vrp[1] = Vrp[1];
430 myExtra.vrp[2] = Vrp[2];
431
432 myExtra.vpn[0] = Vpn[0];
433 myExtra.vpn[1] = Vpn[1];
434 myExtra.vpn[2] = Vpn[2];
435
436 myExtra.vup[0] = Vup[0];
437 myExtra.vup[1] = Vup[1];
438 myExtra.vup[2] = Vup[2];
439
440 myExtra.scaleFactors[0] = ScaleFactors[0],
441 myExtra.scaleFactors[1] = ScaleFactors[1],
442 myExtra.scaleFactors[2] = ScaleFactors[2];
443 }
444}
445
446/*----------------------------------------------------------------------*/
447
bf75be98 448void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
449 const Standard_Boolean theFlag)
2166f0fa 450{
bf75be98 451 if (!theFlag)
2166f0fa
SK
452 {
453 myFog.IsOn = Standard_False;
454 }
455 else
456 {
457 myFog.IsOn = Standard_True;
458
459 myFog.Front =
bf75be98 460 (theCView.Context.DepthFrontPlane - theCView.Mapping.BackPlaneDistance) /
461 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
2166f0fa
SK
462
463 myFog.Back =
bf75be98 464 (theCView.Context.DepthBackPlane - theCView.Mapping.BackPlaneDistance) /
465 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
2166f0fa
SK
466
467 if (myFog.Front < 0.F)
468 myFog.Front = 0.F;
469 else if (myFog.Front > 1.F)
470 myFog.Front = 1.F;
471
472 if (myFog.Back < 0.F)
473 myFog.Back = 0.F;
474 else if (myFog.Back > 1.F)
475 myFog.Back = 1.F;
476
477 if (myFog.Back > myFog.Front)
478 {
479 myFog.Front = 1.F;
480 myFog.Back = 0.F;
481 }
482
bf75be98 483 myFog.Color.rgb[0] = theCView.DefWindow.Background.r;
484 myFog.Color.rgb[1] = theCView.DefWindow.Background.g;
485 myFog.Color.rgb[2] = theCView.DefWindow.Background.b;
486 myFog.Color.rgb[3] = 1.0f;
2166f0fa
SK
487 }
488}
489
490/*----------------------------------------------------------------------*/
491
492void OpenGl_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition APosition, const Quantity_NameOfColor AColor,
493 const Standard_Real AScale, const Standard_Boolean AsWireframe)
494{
495 myTrihedron = new OpenGl_Trihedron (APosition, AColor, AScale, AsWireframe);
496}
497
498/*----------------------------------------------------------------------*/
499
500void OpenGl_View::TriedronErase ()
501{
502 myTrihedron.Nullify();
503}
504
505/*----------------------------------------------------------------------*/
506
507void OpenGl_View::GraduatedTrihedronDisplay (const Graphic3d_CGraduatedTrihedron &data)
508{
509 myGraduatedTrihedron = new OpenGl_GraduatedTrihedron(data);
510}
511
512/*----------------------------------------------------------------------*/
513
514void OpenGl_View::GraduatedTrihedronErase ()
515{
516 myGraduatedTrihedron.Nullify();
517}
518
519/*----------------------------------------------------------------------*/
520
521//transform_persistence_end
c34dba32 522void OpenGl_View::EndTransformPersistence()
2166f0fa 523{
c34dba32 524 if (myIsTransPers)
2166f0fa 525 {
c34dba32 526 // restore matrix
2166f0fa 527 glMatrixMode (GL_PROJECTION);
c34dba32 528 glPopMatrix();
2166f0fa 529 glMatrixMode (GL_MODELVIEW);
c34dba32 530 glPopMatrix();
2166f0fa
SK
531 myIsTransPers = Standard_False;
532 }
bf75be98 533}
2166f0fa
SK
534
535/*----------------------------------------------------------------------*/
536
537//transform_persistence_begin
c34dba32 538const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const TEL_TRANSFORM_PERSISTENCE* theTransPers)
2166f0fa 539{
c34dba32 540 const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
541 myTransPers = theTransPers;
542 if (theTransPers->mode == 0)
2166f0fa
SK
543 {
544 EndTransformPersistence();
c34dba32 545 return aTransPersPrev;
2166f0fa
SK
546 }
547
c34dba32 548 GLint aViewport[4];
549 GLdouble aModelMatrix[4][4];
550 GLdouble aProjMatrix[4][4];
551 glGetIntegerv (GL_VIEWPORT, aViewport);
552 glGetDoublev (GL_MODELVIEW_MATRIX, (GLdouble* )aModelMatrix);
553 glGetDoublev (GL_PROJECTION_MATRIX, (GLdouble *)aProjMatrix);
554 const GLdouble aViewportW = (GLdouble )aViewport[2];
555 const GLdouble aViewportH = (GLdouble )aViewport[3];
2166f0fa 556
c34dba32 557 if (myIsTransPers)
2166f0fa 558 {
c34dba32 559 // pop matrix stack - it will be overridden later
2166f0fa 560 glMatrixMode (GL_PROJECTION);
c34dba32 561 glPopMatrix();
2166f0fa 562 glMatrixMode (GL_MODELVIEW);
c34dba32 563 glPopMatrix();
2166f0fa
SK
564 }
565 else
c34dba32 566 {
2166f0fa 567 myIsTransPers = Standard_True;
c34dba32 568 }
2166f0fa 569
c34dba32 570 // push matrices into stack and reset them
571 glMatrixMode (GL_MODELVIEW);
2166f0fa
SK
572 glPushMatrix();
573 glLoadIdentity();
574
c34dba32 575 glMatrixMode (GL_PROJECTION);
2166f0fa
SK
576 glPushMatrix();
577 glLoadIdentity();
578
c34dba32 579 // get the window's (fixed) coordinates for theTransPers->point before matrixes modifications
580 GLdouble aWinX = 0.0, aWinY = 0.0, aWinZ = 0.0;
581 if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
2166f0fa 582 {
c34dba32 583 gluProject (theTransPers->pointX, theTransPers->pointY, theTransPers->pointZ,
584 (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
585 &aWinX, &aWinY, &aWinZ);
2166f0fa
SK
586 }
587
c34dba32 588 // prevent zooming
589 if ((theTransPers->mode & TPF_ZOOM)
590 || (theTransPers->mode == TPF_TRIEDRON))
2166f0fa 591 {
c34dba32 592 // compute fixed-zoom multiplier
593 // actually function works ugly with TelPerspective!
594 const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix[1][1] : aProjMatrix[0][0]);
595 aProjMatrix[0][0] *= aDet2;
596 aProjMatrix[1][1] *= aDet2;
597 aProjMatrix[2][2] *= aDet2;
2166f0fa
SK
598 }
599
c34dba32 600 // prevent translation - annulate translate matrix
601 if ((theTransPers->mode & TPF_PAN)
602 || (theTransPers->mode == TPF_TRIEDRON))
2166f0fa 603 {
c34dba32 604 aModelMatrix[3][0] = 0.0;
605 aModelMatrix[3][1] = 0.0;
606 aModelMatrix[3][2] = 0.0;
607 aProjMatrix [3][0] = 0.0;
608 aProjMatrix [3][1] = 0.0;
609 aProjMatrix [3][2] = 0.0;
2166f0fa 610 }
2166f0fa 611
c34dba32 612 // prevent scaling-on-axis
613 if (theTransPers->mode & TPF_ZOOM)
614 {
615 const double aScaleX = myExtra.scaleFactors[0];
616 const double aScaleY = myExtra.scaleFactors[1];
617 const double aScaleZ = myExtra.scaleFactors[2];
618 for (int i = 0; i < 3; ++i)
619 {
620 aModelMatrix[0][i] /= aScaleX;
621 aModelMatrix[1][i] /= aScaleY;
622 aModelMatrix[2][i] /= aScaleZ;
623 }
2166f0fa
SK
624 }
625
c34dba32 626 // prevent rotating - annulate rotate matrix
627 if (theTransPers->mode & TPF_ROTATE)
2166f0fa 628 {
c34dba32 629 aModelMatrix[0][0] = 1.0;
630 aModelMatrix[1][1] = 1.0;
631 aModelMatrix[2][2] = 1.0;
632
633 aModelMatrix[1][0] = 0.0;
634 aModelMatrix[2][0] = 0.0;
635 aModelMatrix[0][1] = 0.0;
636 aModelMatrix[2][1] = 0.0;
637 aModelMatrix[0][2] = 0.0;
638 aModelMatrix[1][2] = 0.0;
2166f0fa
SK
639 }
640
c34dba32 641 // load computed matrices
2166f0fa 642 glMatrixMode (GL_MODELVIEW);
c34dba32 643 glMultMatrixd ((GLdouble* )aModelMatrix);
2166f0fa
SK
644
645 glMatrixMode (GL_PROJECTION);
c34dba32 646 glMultMatrixd ((GLdouble* )aProjMatrix);
2166f0fa 647
c34dba32 648 if (theTransPers->mode == TPF_TRIEDRON)
2166f0fa 649 {
c34dba32 650 // move to the window corner
651 if (theTransPers->pointX != 0.0
652 && theTransPers->pointY != 0.0)
2166f0fa 653 {
c34dba32 654 GLdouble aW1, aH1, aW2, aH2, aDummy;
655 glMatrixMode (GL_PROJECTION);
656 gluUnProject ( 0.5 * aViewportW, 0.5 * aViewportH, 0.0,
657 (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
658 &aW1, &aH1, &aDummy);
659 gluUnProject (-0.5 * aViewportW, -0.5 * aViewportH, 0.0,
660 (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
661 &aW2, &aH2, &aDummy);
662 GLdouble aMoveX = 0.5 * (aW1 - aW2 - theTransPers->pointZ);
663 GLdouble aMoveY = 0.5 * (aH1 - aH2 - theTransPers->pointZ);
664 aMoveX = (theTransPers->pointX > 0.0) ? aMoveX : -aMoveX;
665 aMoveY = (theTransPers->pointY > 0.0) ? aMoveY : -aMoveY;
666 glTranslated (aMoveX, aMoveY, 0.0);
2166f0fa
SK
667 }
668 }
c34dba32 669 else if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
670 {
671 // move to thePoint using saved win-coordinates ('marker-behaviour')
672 GLdouble aMoveX, aMoveY, aMoveZ;
673 glGetDoublev (GL_MODELVIEW_MATRIX, (GLdouble* )aModelMatrix);
674 glGetDoublev (GL_PROJECTION_MATRIX, (GLdouble* )aProjMatrix);
675 gluUnProject (aWinX, aWinY, aWinZ,
676 (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
677 &aMoveX, &aMoveY, &aMoveZ);
2166f0fa 678
c34dba32 679 glMatrixMode (GL_MODELVIEW);
680 glTranslated (aMoveX, aMoveY, aMoveZ);
681 }
2166f0fa 682
c34dba32 683 return aTransPersPrev;
684}