0027232: Configuration - fix mblen missing building issue on Android
[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 <NCollection_AlignedAllocator.hxx>
17 #include <OpenGl_CappingPlaneResource.hxx>
18 #include <OpenGl_Context.hxx>
19 #include <OpenGl_Vec.hxx>
20 #include <Precision.hxx>
21
22 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingPlaneResource,OpenGl_Resource)
23
24 namespace
25 {
26   //! 12 plane vertices, interleaved:
27   //!  - 4 floats, position
28   //!  - 4 floats, normal
29   //!  - 4 floats, UV texture coordinates
30   static const GLfloat THE_CAPPING_PLN_VERTS[12 * (4 + 4 + 4)] =
31   {
32     0.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
33     1.0f, 0.0f, 0.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   1.0f, 0.0f, 0.0f, 0.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
36     0.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
37     0.0f, 0.0f, 1.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f,-1.0f, 0.0f, 0.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
40     0.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
41    -1.0f, 0.0f, 0.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,  -1.0f, 0.0f, 0.0f, 0.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
44     0.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
45     0.0f, 0.0f,-1.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 1.0f, 0.0f, 0.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   };
48
49   static const OpenGl_Matrix OpenGl_IdentityMatrix =
50   {
51     // mat[4][4]
52     { { 1.0f, 0.0f, 0.0f, 0.0f },
53       { 0.0f, 1.0f, 0.0f, 0.0f },
54       { 0.0f, 0.0f, 1.0f, 0.0f },
55       { 0.0f, 0.0f, 0.0f, 1.0f } }
56   };
57
58 }
59
60
61 // =======================================================================
62 // function : OpenGl_CappingPlaneResource
63 // purpose  :
64 // =======================================================================
65 OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane)
66 : myPrimitives  (NULL),
67   myOrientation (OpenGl_IdentityMatrix),
68   myAspect      (NULL),
69   myPlaneRoot   (thePlane),
70   myEquationMod ((unsigned int )-1),
71   myAspectMod   ((unsigned int )-1)
72 {
73   // Fill primitive array
74   Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16);
75   Handle(Graphic3d_Buffer) anAttribs = new Graphic3d_Buffer (anAlloc);
76   Graphic3d_Attribute anAttribInfo[] =
77   {
78     { Graphic3d_TOA_POS,  Graphic3d_TOD_VEC4 },
79     { Graphic3d_TOA_NORM, Graphic3d_TOD_VEC4 },
80     { Graphic3d_TOA_UV,   Graphic3d_TOD_VEC4 }
81   };
82   if (anAttribs->Init (12, anAttribInfo, 3))
83   {
84     memcpy (anAttribs->ChangeData(), THE_CAPPING_PLN_VERTS, sizeof(THE_CAPPING_PLN_VERTS));
85     myPrimitives.InitBuffers (NULL, Graphic3d_TOPA_TRIANGLES, NULL, anAttribs, NULL);
86   }
87 }
88
89 // =======================================================================
90 // function : OpenGl_CappingPlaneResource
91 // purpose  :
92 // =======================================================================
93 OpenGl_CappingPlaneResource::~OpenGl_CappingPlaneResource()
94 {
95   Release (NULL);
96 }
97
98 // =======================================================================
99 // function : Update
100 // purpose  :
101 // =======================================================================
102 void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& theContext)
103 {
104   UpdateTransform();
105   UpdateAspect (theContext);
106 }
107
108 // =======================================================================
109 // function : Release
110 // purpose  :
111 // =======================================================================
112 void OpenGl_CappingPlaneResource::Release (OpenGl_Context* theContext)
113 {
114   OpenGl_Element::Destroy (theContext, myAspect);
115   myPrimitives.Release (theContext);
116   myEquationMod = (unsigned int )-1;
117   myAspectMod   = (unsigned int )-1;
118 }
119
120 // =======================================================================
121 // function : UpdateAspect
122 // purpose  :
123 // =======================================================================
124 void OpenGl_CappingPlaneResource::UpdateAspect (const Handle(OpenGl_Context)& theContext)
125 {
126   Handle(Graphic3d_AspectFillArea3d) aCappingAsp = myPlaneRoot->CappingAspect();
127   if (myAspect != NULL && !aCappingAsp.IsNull())
128   {
129     if (myAspectMod == myPlaneRoot->MCountAspect())
130       return; // noting to update
131     
132     myAspect->SetAspect (aCappingAsp);
133     myAspectMod = myPlaneRoot->MCountAspect();
134     return;
135   }
136
137   // no more used
138   if (myAspect != NULL && aCappingAsp.IsNull())
139   {
140     OpenGl_Element::Destroy (theContext.operator->(), myAspect);
141     myAspectMod = myPlaneRoot->MCountAspect();
142     return;
143   }
144
145   // first created
146   if (myAspect == NULL && !aCappingAsp.IsNull())
147   {
148     myAspect = new OpenGl_AspectFace();
149     myAspect->SetAspect (aCappingAsp);
150     myAspectMod = myPlaneRoot->MCountAspect();
151   }
152 }
153
154 // =======================================================================
155 // function : UpdateTransform
156 // purpose  :
157 // =======================================================================
158 void OpenGl_CappingPlaneResource::UpdateTransform()
159 {
160   const Graphic3d_ClipPlane::Equation& anEquation = myPlaneRoot->GetEquation();
161   if (myEquationMod == myPlaneRoot->MCountEquation())
162   {
163     return; // nothing to update
164   }
165
166   // re-evaluate infinite plane transformation matrix
167   Standard_ShortReal N[3] = 
168     { (Standard_ShortReal)anEquation[0],
169       (Standard_ShortReal)anEquation[1],
170       (Standard_ShortReal)anEquation[2] };
171
172   Standard_ShortReal T[3] = 
173     { (Standard_ShortReal)(anEquation[0] * -anEquation[3]),
174       (Standard_ShortReal)(anEquation[1] * -anEquation[3]),
175       (Standard_ShortReal)(anEquation[2] * -anEquation[3]) };
176
177   Standard_ShortReal L[3] = { 0.0f, 0.0f, 0.0f };
178   Standard_ShortReal F[3] = { 0.0f, 0.0f, 0.0f };
179
180   // project plane normal onto OX to find left vector
181   Standard_ShortReal aProjLen = 
182     sqrt (  (Standard_ShortReal)(anEquation[0] * anEquation[0])
183           + (Standard_ShortReal)(anEquation[2] * anEquation[2]));
184   if (aProjLen < ShortRealSmall())
185   {
186     L[0] = 1.0f;
187   }
188   else
189   {
190     L[0] =  N[2] / aProjLen;
191     L[2] = -N[0] / aProjLen;
192   }
193
194   // (-aLeft) x aNorm
195   F[0] = (-L[1])*N[2] - (-L[2])*N[1];
196   F[1] = (-L[2])*N[0] - (-L[0])*N[2];
197   F[2] = (-L[0])*N[1] - (-L[1])*N[0];
198
199   myOrientation.mat[0][0] = L[0];
200   myOrientation.mat[0][1] = L[1];
201   myOrientation.mat[0][2] = L[2];
202   myOrientation.mat[0][3] = 0.0f;
203
204   myOrientation.mat[1][0] = N[0];
205   myOrientation.mat[1][1] = N[1];
206   myOrientation.mat[1][2] = N[2];
207   myOrientation.mat[1][3] = 0.0f;
208
209   myOrientation.mat[2][0] = F[0];
210   myOrientation.mat[2][1] = F[1];
211   myOrientation.mat[2][2] = F[2];
212   myOrientation.mat[2][3] = 0.0f;
213
214   myOrientation.mat[3][0] = T[0];
215   myOrientation.mat[3][1] = T[1];
216   myOrientation.mat[3][2] = T[2];
217   myOrientation.mat[3][3] = 1.0f;
218
219   myEquationMod = myPlaneRoot->MCountEquation();
220 }