0024288: Provide flipping text for AIS_Dimensions
[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 #include <OpenGl_Vec.hxx>
22 #include <OpenGl_Workspace.hxx>
23
24 #include <gp_Ax2.hxx>
25
26 // =======================================================================
27 // function : Constructor
28 // purpose  :
29 // =======================================================================
30 OpenGl_Flipper::OpenGl_Flipper (const gp_Ax2& theReferenceSystem)
31 : OpenGl_Element(),
32   myReferenceOrigin ((Standard_ShortReal )theReferenceSystem.Location().X(),
33                      (Standard_ShortReal )theReferenceSystem.Location().Y(),
34                      (Standard_ShortReal )theReferenceSystem.Location().Z(),
35                      1.0f),
36   myReferenceX ((Standard_ShortReal )theReferenceSystem.XDirection().X(),
37                 (Standard_ShortReal )theReferenceSystem.XDirection().Y(),
38                 (Standard_ShortReal )theReferenceSystem.XDirection().Z(),
39                 1.0f),
40   myReferenceY ((Standard_ShortReal )theReferenceSystem.YDirection().X(),
41                 (Standard_ShortReal )theReferenceSystem.YDirection().Y(),
42                 (Standard_ShortReal )theReferenceSystem.YDirection().Z(),
43                 1.0f),
44   myReferenceZ ((Standard_ShortReal )theReferenceSystem.Axis().Direction().X(),
45                 (Standard_ShortReal )theReferenceSystem.Axis().Direction().Y(),
46                 (Standard_ShortReal )theReferenceSystem.Axis().Direction().Z(),
47                 1.0f),
48   myIsEnabled (Standard_True)
49 {
50   //
51 }
52
53 // =======================================================================
54 // function : Release
55 // purpose  :
56 // =======================================================================
57 void OpenGl_Flipper::Release (const Handle(OpenGl_Context)& )
58 {
59   //
60 }
61
62 // =======================================================================
63 // function : Render
64 // purpose  :
65 // =======================================================================
66 void OpenGl_Flipper::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
67 {
68   if (!myIsEnabled)
69   {
70     glMatrixMode (GL_MODELVIEW);
71     glLoadMatrixf ((GLfloat*) theWorkspace->ViewMatrix());
72     return;
73   }
74
75   OpenGl_Mat4 aMatrixMV;
76   glGetFloatv (GL_MODELVIEW_MATRIX, aMatrixMV.ChangeData());
77
78   const OpenGl_Vec4 aMVReferenceOrigin = aMatrixMV * myReferenceOrigin;
79   const OpenGl_Vec4 aMVReferenceX      = aMatrixMV * OpenGl_Vec4 (myReferenceX.xyz() + myReferenceOrigin.xyz(), 1.0f);
80   const OpenGl_Vec4 aMVReferenceY      = aMatrixMV * OpenGl_Vec4 (myReferenceY.xyz() + myReferenceOrigin.xyz(), 1.0f);
81   const OpenGl_Vec4 aMVReferenceZ      = aMatrixMV * OpenGl_Vec4 (myReferenceZ.xyz() + myReferenceOrigin.xyz(), 1.0f);
82
83   const OpenGl_Vec4 aDirX = aMVReferenceX - aMVReferenceOrigin;
84   const OpenGl_Vec4 aDirY = aMVReferenceY - aMVReferenceOrigin;
85   const OpenGl_Vec4 aDirZ = aMVReferenceZ - aMVReferenceOrigin;
86
87   Standard_Boolean isReversedX = aDirX.xyz().Dot (OpenGl_Vec3::DX()) < 0.0f;
88   Standard_Boolean isReversedY = aDirY.xyz().Dot (OpenGl_Vec3::DY()) < 0.0f;
89   Standard_Boolean isReversedZ = aDirZ.xyz().Dot (OpenGl_Vec3::DZ()) < 0.0f;
90
91   // compute flipping (rotational transform)
92   OpenGl_Mat4 aTransform;
93   if ((isReversedX || isReversedY) && !isReversedZ)
94   {
95     // invert by Z axis: left, up vectors mirrored
96     aTransform.SetColumn (0, -aTransform.GetColumn (0).xyz());
97     aTransform.SetColumn (1, -aTransform.GetColumn (1).xyz());
98   }
99   else if (isReversedY && isReversedZ)
100   {
101     // rotate by X axis: up, forward vectors mirrored
102     aTransform.SetColumn (1, -aTransform.GetColumn (1).xyz());
103     aTransform.SetColumn (2, -aTransform.GetColumn (2).xyz());
104   }
105   else if (isReversedZ)
106   {
107     // rotate by Y axis: left, forward vectors mirrored
108     aTransform.SetColumn (0, -aTransform.GetColumn (0).xyz());
109     aTransform.SetColumn (2, -aTransform.GetColumn (2).xyz());
110   }
111   else
112   {
113     return;
114   }
115
116   // do rotation in origin around reference system "forward" direction
117   OpenGl_Mat4 aRefAxes;
118   OpenGl_Mat4 aRefInv;
119   aRefAxes.SetColumn (0, myReferenceX.xyz());
120   aRefAxes.SetColumn (1, myReferenceY.xyz());
121   aRefAxes.SetColumn (2, myReferenceZ.xyz());
122   aRefAxes.SetColumn (3, myReferenceOrigin.xyz());
123   aRefAxes.Inverted (aRefInv);
124
125   aTransform = aRefAxes * aTransform * aRefInv;
126
127   // transform model-view matrix
128   aMatrixMV = aMatrixMV * aTransform;
129
130   // load transformed model-view matrix
131   GLint aCurrMode = GL_MODELVIEW;
132   glGetIntegerv (GL_MATRIX_MODE, &aCurrMode);
133   if (aCurrMode != GL_MODELVIEW)
134   {
135     glMatrixMode (GL_MODELVIEW);
136   }
137
138   glLoadMatrixf ((GLfloat*) aMatrixMV);
139
140   if (aCurrMode != GL_MODELVIEW)
141   {
142     glMatrixMode (aCurrMode);
143   }
144 }