0024001: Stereographic rendering support
[occt.git] / src / OpenGl / OpenGl_CappingPlaneResource.cxx
1 // Created on: 2013-08-15
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2013 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and / or modify it
8 // under the terms of the GNU Lesser General Public version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <OpenGl_CappingPlaneResource.hxx>
17 #include <OpenGl_Context.hxx>
18 #include <OpenGl_Vec.hxx>
19 #include <Precision.hxx>
20
21 IMPLEMENT_STANDARD_HANDLE (OpenGl_CappingPlaneResource, OpenGl_Resource)
22 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingPlaneResource, OpenGl_Resource)
23
24 // =======================================================================
25 // function : OpenGl_CappingPlaneResource
26 // purpose  :
27 // =======================================================================
28 OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane)
29 : myOrientation (OpenGl_IdentityMatrix),
30   myAspect (NULL),
31   myPlaneRoot (thePlane),
32   myEquationMod (0),
33   myAspectMod (0)
34 {}
35
36 // =======================================================================
37 // function : OpenGl_CappingPlaneResource
38 // purpose  :
39 // =======================================================================
40 OpenGl_CappingPlaneResource::~OpenGl_CappingPlaneResource()
41 {
42   Release (NULL);
43 }
44
45 // =======================================================================
46 // function : Update
47 // purpose  :
48 // =======================================================================
49 void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& theContext)
50 {
51   UpdateTransform();
52   UpdateAspect (theContext);
53 }
54
55 // =======================================================================
56 // function : Release
57 // purpose  :
58 // =======================================================================
59 void OpenGl_CappingPlaneResource::Release (const OpenGl_Context* theContext)
60 {
61   OpenGl_Element::Destroy (theContext, myAspect);
62   myEquationMod = 0;
63   myAspectMod   = 0;
64 }
65
66 // =======================================================================
67 // function : UpdateAspect
68 // purpose  :
69 // =======================================================================
70 void OpenGl_CappingPlaneResource::UpdateAspect (const Handle(OpenGl_Context)& theContext)
71 {
72   Handle(Graphic3d_AspectFillArea3d) aCappingAsp = myPlaneRoot->CappingAspect();
73   if (myAspect != NULL && !aCappingAsp.IsNull())
74   {
75     if (myAspectMod == myPlaneRoot->MCountAspect())
76       return; // noting to update
77     
78     myAspect->SetAspect (aCappingAsp);
79     myAspectMod = myPlaneRoot->MCountAspect();
80     return;
81   }
82
83   // no more used
84   if (myAspect != NULL && aCappingAsp.IsNull())
85   {
86     OpenGl_Element::Destroy (theContext, myAspect);
87     myAspectMod = myPlaneRoot->MCountAspect();
88     return;
89   }
90
91   // first created
92   if (myAspect == NULL && !aCappingAsp.IsNull())
93   {
94     myAspect = new OpenGl_AspectFace();
95     myAspect->SetAspect (aCappingAsp);
96     myAspectMod = myPlaneRoot->MCountAspect();
97   }
98 }
99
100 // =======================================================================
101 // function : UpdateTransform
102 // purpose  :
103 // =======================================================================
104 void OpenGl_CappingPlaneResource::UpdateTransform()
105 {
106   const Graphic3d_ClipPlane::Equation& anEquation = myPlaneRoot->GetEquation();
107   if (myEquationMod == myPlaneRoot->MCountEquation())
108   {
109     return; // nothing to update
110   }
111
112   // re-evaluate infinite plane transformation matrix
113   Standard_ShortReal N[3] = 
114     { (Standard_ShortReal)anEquation[0],
115       (Standard_ShortReal)anEquation[1],
116       (Standard_ShortReal)anEquation[2] };
117
118   Standard_ShortReal T[3] = 
119     { (Standard_ShortReal)(anEquation[0] * -anEquation[3]),
120       (Standard_ShortReal)(anEquation[1] * -anEquation[3]),
121       (Standard_ShortReal)(anEquation[2] * -anEquation[3]) };
122
123   Standard_ShortReal L[3] = { 0.0f, 0.0f, 0.0f };
124   Standard_ShortReal F[3] = { 0.0f, 0.0f, 0.0f };
125
126   // project plane normal onto OX to find left vector
127   Standard_ShortReal aConfusion = (Standard_ShortReal)Precision::Confusion();
128   Standard_ShortReal aProjLen = 
129     sqrt (  (Standard_ShortReal)(anEquation[0] * anEquation[0])
130           + (Standard_ShortReal)(anEquation[2] * anEquation[2]));
131   if (aProjLen < aConfusion)
132   {
133     L[0] = 1.0f;
134   }
135   else
136   {
137     L[0] =  N[2] / aProjLen;
138     L[2] = -N[0] / aProjLen;
139   }
140
141   // (-aLeft) x aNorm
142   F[0] = (-L[1])*N[2] - (-L[2])*N[1];
143   F[1] = (-L[2])*N[0] - (-L[0])*N[2];
144   F[2] = (-L[0])*N[1] - (-L[1])*N[0];
145
146   myOrientation.mat[0][0] = L[0];
147   myOrientation.mat[0][1] = L[1];
148   myOrientation.mat[0][2] = L[2];
149   myOrientation.mat[0][3] = 0.0f;
150
151   myOrientation.mat[1][0] = N[0];
152   myOrientation.mat[1][1] = N[1];
153   myOrientation.mat[1][2] = N[2];
154   myOrientation.mat[1][3] = 0.0f;
155
156   myOrientation.mat[2][0] = F[0];
157   myOrientation.mat[2][1] = F[1];
158   myOrientation.mat[2][2] = F[2];
159   myOrientation.mat[2][3] = 0.0f;
160
161   myOrientation.mat[3][0] = T[0];
162   myOrientation.mat[3][1] = T[1];
163   myOrientation.mat[3][2] = T[2];
164   myOrientation.mat[3][3] = 1.0f;
165
166   myEquationMod = myPlaneRoot->MCountEquation();
167 }