0032289: Visualization - add NCollection_Mat3 for 3x3 matrix similar to NCollection_Mat4
[occt.git] / src / OpenGl / OpenGl_CappingPlaneResource.cxx
1 // Created on: 2013-08-15
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2013-2014 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 under
8 // the terms of the GNU Lesser General Public License 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
18 #include <OpenGl_Context.hxx>
19 #include <OpenGl_Vec.hxx>
20 #include <OpenGl_ShaderManager.hxx>
21 #include <Precision.hxx>
22
23 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingPlaneResource,OpenGl_Resource)
24
25 namespace
26 {
27   //! 12 plane vertices, interleaved:
28   //!  - 4 floats, position
29   //!  - 4 floats, normal
30   //!  - 4 floats, UV texture coordinates
31   static const GLfloat THE_CAPPING_PLN_VERTS[12 * (4 + 4 + 4)] =
32   {
33     0.0f, 0.0f, 0.0f, 1.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
34     0.0f, 0.0f, 1.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f,-1.0f, 0.0f, 0.0f,
35     1.0f, 0.0f, 0.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,   1.0f, 0.0f, 0.0f, 0.0f,
36
37     0.0f, 0.0f, 0.0f, 1.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
38    -1.0f, 0.0f, 0.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,  -1.0f, 0.0f, 0.0f, 0.0f,
39     0.0f, 0.0f, 1.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f,-1.0f, 0.0f, 0.0f,
40
41     0.0f, 0.0f, 0.0f, 1.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
42     0.0f, 0.0f,-1.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f, 1.0f, 0.0f, 0.0f,
43    -1.0f, 0.0f, 0.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,  -1.0f, 0.0f, 0.0f, 0.0f,
44
45     0.0f, 0.0f, 0.0f, 1.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
46     1.0f, 0.0f, 0.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,   1.0f, 0.0f, 0.0f, 0.0f,
47     0.0f, 0.0f,-1.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f, 1.0f, 0.0f, 0.0f
48   };
49 }
50
51 // =======================================================================
52 // function : OpenGl_CappingPlaneResource
53 // purpose  :
54 // =======================================================================
55 OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane)
56 : myPrimitives  (NULL),
57   myOrientation (OpenGl_Mat4::Identity()),
58   myAspect      (NULL),
59   myPlaneRoot   (thePlane),
60   myEquationMod ((unsigned int )-1),
61   myAspectMod   ((unsigned int )-1)
62 {
63   Handle(Graphic3d_Buffer) anAttribs = new Graphic3d_Buffer (Graphic3d_Buffer::DefaultAllocator());
64   Graphic3d_Attribute anAttribInfo[] =
65   {
66     { Graphic3d_TOA_POS,  Graphic3d_TOD_VEC4 },
67     { Graphic3d_TOA_NORM, Graphic3d_TOD_VEC4 },
68     { Graphic3d_TOA_UV,   Graphic3d_TOD_VEC4 }
69   };
70   if (anAttribs->Init (12, anAttribInfo, 3))
71   {
72     memcpy (anAttribs->ChangeData(), THE_CAPPING_PLN_VERTS, sizeof(THE_CAPPING_PLN_VERTS));
73     myPrimitives.InitBuffers (NULL, Graphic3d_TOPA_TRIANGLES, NULL, anAttribs, NULL);
74   }
75 }
76
77 // =======================================================================
78 // function : OpenGl_CappingPlaneResource
79 // purpose  :
80 // =======================================================================
81 OpenGl_CappingPlaneResource::~OpenGl_CappingPlaneResource()
82 {
83   Release (NULL);
84 }
85
86 // =======================================================================
87 // function : Update
88 // purpose  :
89 // =======================================================================
90 void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& theCtx,
91                                           const Handle(Graphic3d_Aspects)& theObjAspect)
92 {
93   updateTransform (theCtx);
94   updateAspect (theObjAspect);
95 }
96
97 // =======================================================================
98 // function : Release
99 // purpose  :
100 // =======================================================================
101 void OpenGl_CappingPlaneResource::Release (OpenGl_Context* theContext)
102 {
103   OpenGl_Element::Destroy (theContext, myAspect);
104   myPrimitives.Release (theContext);
105   myEquationMod = (unsigned int )-1;
106   myAspectMod   = (unsigned int )-1;
107 }
108
109 // =======================================================================
110 // function : updateAspect
111 // purpose  :
112 // =======================================================================
113 void OpenGl_CappingPlaneResource::updateAspect (const Handle(Graphic3d_Aspects)& theObjAspect)
114 {
115   if (myAspect == NULL)
116   {
117     myAspect = new OpenGl_Aspects();
118     myAspectMod = myPlaneRoot->MCountAspect() - 1; // mark out of sync
119   }
120
121   if (theObjAspect.IsNull())
122   {
123     if (myAspectMod != myPlaneRoot->MCountAspect())
124     {
125       myAspect->SetAspect (myPlaneRoot->CappingAspect());
126       myAspectMod = myPlaneRoot->MCountAspect();
127     }
128     return;
129   }
130
131   if (myFillAreaAspect.IsNull())
132   {
133     myFillAreaAspect = new Graphic3d_AspectFillArea3d();
134   }
135   if (myAspectMod != myPlaneRoot->MCountAspect())
136   {
137     *myFillAreaAspect = *myPlaneRoot->CappingAspect();
138   }
139
140   if (myPlaneRoot->ToUseObjectMaterial())
141   {
142     // only front material currently supported by capping rendering
143     myFillAreaAspect->SetFrontMaterial (theObjAspect->FrontMaterial());
144     myFillAreaAspect->SetInteriorColor (theObjAspect->InteriorColor());
145   }
146   if (myPlaneRoot->ToUseObjectTexture())
147   {
148     myFillAreaAspect->SetTextureSet (theObjAspect->TextureSet());
149     if (theObjAspect->ToMapTexture())
150     {
151       myFillAreaAspect->SetTextureMapOn();
152     }
153     else
154     {
155       myFillAreaAspect->SetTextureMapOff();
156     }
157   }
158   if (myPlaneRoot->ToUseObjectShader())
159   {
160     myFillAreaAspect->SetShaderProgram (theObjAspect->ShaderProgram());
161   }
162
163   myAspect->SetAspect (myFillAreaAspect);
164 }
165
166 // =======================================================================
167 // function : updateTransform
168 // purpose  :
169 // =======================================================================
170 void OpenGl_CappingPlaneResource::updateTransform (const Handle(OpenGl_Context)& theCtx)
171 {
172   if (myEquationMod == myPlaneRoot->MCountEquation()
173    && myLocalOrigin.IsEqual (theCtx->ShaderManager()->LocalOrigin(), gp::Resolution()))
174   {
175     return; // nothing to update
176   }
177
178   myEquationMod = myPlaneRoot->MCountEquation();
179   myLocalOrigin = theCtx->ShaderManager()->LocalOrigin();
180
181   const Graphic3d_ClipPlane::Equation& anEq = myPlaneRoot->GetEquation();
182   const Standard_Real anEqW = theCtx->ShaderManager()->LocalClippingPlaneW (*myPlaneRoot);
183
184   // re-evaluate infinite plane transformation matrix
185   const Graphic3d_Vec3 aNorm (anEq.xyz());
186   const Graphic3d_Vec3 T (anEq.xyz() * -anEqW);
187
188   // project plane normal onto OX to find left vector
189   const Standard_ShortReal aProjLen = sqrt ((Standard_ShortReal)anEq.xz().SquareModulus());
190   Graphic3d_Vec3 aLeft;
191   if (aProjLen < ShortRealSmall())
192   {
193     aLeft[0] = 1.0f;
194   }
195   else
196   {
197     aLeft[0] =  aNorm[2] / aProjLen;
198     aLeft[2] = -aNorm[0] / aProjLen;
199   }
200
201   const Graphic3d_Vec3 F = Graphic3d_Vec3::Cross (-aLeft, aNorm);
202   myOrientation.SetColumn (0, aLeft);
203   myOrientation.SetColumn (1, aNorm);
204   myOrientation.SetColumn (2, F);
205   myOrientation.SetColumn (3, T);
206 }