0024374: Flipping affects highlight presentation of dimension. Model-view matrix...
[occt.git] / src / OpenGl / OpenGl_Flipper.cxx
1 // Created on: 2013-11-11
2 // Created by: Anastasia BORISOVA
3 // Copyright (c) 2013 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
20 #include <OpenGl_Flipper.hxx>
21
22 #include <OpenGl_Context.hxx>
23 #include <OpenGl_ShaderManager.hxx>
24 #include <OpenGl_Vec.hxx>
25 #include <OpenGl_Workspace.hxx>
26
27 #include <gp_Ax2.hxx>
28
29 // =======================================================================
30 // function : Constructor
31 // purpose  :
32 // =======================================================================
33 OpenGl_Flipper::OpenGl_Flipper (const gp_Ax2& theReferenceSystem)
34 : OpenGl_Element(),
35   myReferenceOrigin ((Standard_ShortReal )theReferenceSystem.Location().X(),
36                      (Standard_ShortReal )theReferenceSystem.Location().Y(),
37                      (Standard_ShortReal )theReferenceSystem.Location().Z(),
38                      1.0f),
39   myReferenceX ((Standard_ShortReal )theReferenceSystem.XDirection().X(),
40                 (Standard_ShortReal )theReferenceSystem.XDirection().Y(),
41                 (Standard_ShortReal )theReferenceSystem.XDirection().Z(),
42                 1.0f),
43   myReferenceY ((Standard_ShortReal )theReferenceSystem.YDirection().X(),
44                 (Standard_ShortReal )theReferenceSystem.YDirection().Y(),
45                 (Standard_ShortReal )theReferenceSystem.YDirection().Z(),
46                 1.0f),
47   myReferenceZ ((Standard_ShortReal )theReferenceSystem.Axis().Direction().X(),
48                 (Standard_ShortReal )theReferenceSystem.Axis().Direction().Y(),
49                 (Standard_ShortReal )theReferenceSystem.Axis().Direction().Z(),
50                 1.0f),
51   myIsEnabled (Standard_True)
52 {
53   //
54 }
55
56 // =======================================================================
57 // function : Release
58 // purpose  :
59 // =======================================================================
60 void OpenGl_Flipper::Release (const Handle(OpenGl_Context)& )
61 {
62   //
63 }
64
65 // =======================================================================
66 // function : Render
67 // purpose  :
68 // =======================================================================
69 void OpenGl_Flipper::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
70 {
71   // Check if rendering is to be in immediate mode
72   const Standard_Boolean isImmediate = (theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
73   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
74   GLint aCurrMode = GL_MODELVIEW;
75   glGetIntegerv (GL_MATRIX_MODE, &aCurrMode);
76
77   if (!myIsEnabled)
78   {
79     // Restore transformation
80     if (isImmediate)
81     {
82       if (aCurrMode != GL_MODELVIEW)
83       {
84         glMatrixMode (GL_MODELVIEW);
85       }
86
87       glPopMatrix();
88
89       if (aCurrMode != GL_MODELVIEW)
90       {
91         glMatrixMode (aCurrMode);
92       }
93
94       Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
95                                     { 0.f, 1.f, 0.f, 0.f },
96                                     { 0.f, 0.f, 1.f, 0.f },
97                                     { 0.f, 0.f, 0.f, 1.f } };
98
99       aContext->ShaderManager()->RevertModelWorldStateTo (aModelWorldState);
100     }
101     else
102     {
103       // Update current model-view matrix in the top of the stack
104       // replacing it with StructureMatrixT*ViewMatrix from the workspace.
105       theWorkspace->UpdateModelViewMatrix();
106     }
107     return;
108   }
109
110   if (isImmediate)
111   {
112
113     if (!aContext->ShaderManager()->IsEmpty())
114     {
115       Tmatrix3 aWorldView;
116       glGetFloatv (GL_MODELVIEW_MATRIX, *aWorldView);
117
118       Tmatrix3 aProjection;
119       glGetFloatv (GL_PROJECTION_MATRIX, *aProjection);
120
121       aContext->ShaderManager()->UpdateWorldViewStateTo (aWorldView);
122       aContext->ShaderManager()->UpdateProjectionStateTo (aProjection);
123     }
124
125     if (aCurrMode != GL_MODELVIEW)
126     {
127       glMatrixMode (GL_MODELVIEW);
128     }
129
130     glPushMatrix();
131
132     if (aCurrMode != GL_MODELVIEW)
133     {
134       glMatrixMode (aCurrMode);
135     }
136   }
137
138   OpenGl_Mat4 aMatrixMV;
139   glGetFloatv (GL_MODELVIEW_MATRIX, aMatrixMV.ChangeData());
140
141   const OpenGl_Vec4 aMVReferenceOrigin = aMatrixMV * myReferenceOrigin;
142   const OpenGl_Vec4 aMVReferenceX      = aMatrixMV * OpenGl_Vec4 (myReferenceX.xyz() + myReferenceOrigin.xyz(), 1.0f);
143   const OpenGl_Vec4 aMVReferenceY      = aMatrixMV * OpenGl_Vec4 (myReferenceY.xyz() + myReferenceOrigin.xyz(), 1.0f);
144   const OpenGl_Vec4 aMVReferenceZ      = aMatrixMV * OpenGl_Vec4 (myReferenceZ.xyz() + myReferenceOrigin.xyz(), 1.0f);
145
146   const OpenGl_Vec4 aDirX = aMVReferenceX - aMVReferenceOrigin;
147   const OpenGl_Vec4 aDirY = aMVReferenceY - aMVReferenceOrigin;
148   const OpenGl_Vec4 aDirZ = aMVReferenceZ - aMVReferenceOrigin;
149
150   Standard_Boolean isReversedX = aDirX.xyz().Dot (OpenGl_Vec3::DX()) < 0.0f;
151   Standard_Boolean isReversedY = aDirY.xyz().Dot (OpenGl_Vec3::DY()) < 0.0f;
152   Standard_Boolean isReversedZ = aDirZ.xyz().Dot (OpenGl_Vec3::DZ()) < 0.0f;
153
154   // compute flipping (rotational transform)
155   OpenGl_Mat4 aTransform;
156   if ((isReversedX || isReversedY) && !isReversedZ)
157   {
158     // invert by Z axis: left, up vectors mirrored
159     aTransform.SetColumn (0, -aTransform.GetColumn (0).xyz());
160     aTransform.SetColumn (1, -aTransform.GetColumn (1).xyz());
161   }
162   else if (isReversedY && isReversedZ)
163   {
164     // rotate by X axis: up, forward vectors mirrored
165     aTransform.SetColumn (1, -aTransform.GetColumn (1).xyz());
166     aTransform.SetColumn (2, -aTransform.GetColumn (2).xyz());
167   }
168   else if (isReversedZ)
169   {
170     // rotate by Y axis: left, forward vectors mirrored
171     aTransform.SetColumn (0, -aTransform.GetColumn (0).xyz());
172     aTransform.SetColumn (2, -aTransform.GetColumn (2).xyz());
173   }
174   else
175   {
176     return;
177   }
178
179   // do rotation in origin around reference system "forward" direction
180   OpenGl_Mat4 aRefAxes;
181   OpenGl_Mat4 aRefInv;
182   aRefAxes.SetColumn (0, myReferenceX.xyz());
183   aRefAxes.SetColumn (1, myReferenceY.xyz());
184   aRefAxes.SetColumn (2, myReferenceZ.xyz());
185   aRefAxes.SetColumn (3, myReferenceOrigin.xyz());
186   aRefAxes.Inverted (aRefInv);
187
188   aTransform = aRefAxes * aTransform * aRefInv;
189
190   // transform model-view matrix
191   aMatrixMV = aMatrixMV * aTransform;
192
193   // load transformed model-view matrix
194   if (aCurrMode != GL_MODELVIEW)
195   {
196     glMatrixMode (GL_MODELVIEW);
197   }
198
199   glLoadMatrixf ((GLfloat*) aMatrixMV);
200
201   if (aCurrMode != GL_MODELVIEW)
202   {
203     glMatrixMode (aCurrMode);
204   }
205 }