4269bd1b |
1 | // Created on: 2013-08-15 |
2 | // Created by: Anton POLETAEV |
d5f74e42 |
3 | // Copyright (c) 2013-2014 OPEN CASCADE SAS |
4269bd1b |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
4269bd1b |
6 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
4269bd1b |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
4269bd1b |
15 | |
e1c659da |
16 | #include <NCollection_AlignedAllocator.hxx> |
4269bd1b |
17 | #include <OpenGl_CappingPlaneResource.hxx> |
18 | #include <OpenGl_Context.hxx> |
19 | #include <OpenGl_Vec.hxx> |
20 | #include <Precision.hxx> |
21 | |
92efcf78 |
22 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingPlaneResource,OpenGl_Resource) |
23 | |
e1c659da |
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, |
44ef962b |
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, |
e1c659da |
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, |
44ef962b |
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, |
e1c659da |
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, |
44ef962b |
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, |
e1c659da |
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, |
44ef962b |
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, |
e1c659da |
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 | }; |
f8ae3605 |
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 | |
e1c659da |
58 | } |
59 | |
4269bd1b |
60 | |
61 | // ======================================================================= |
62 | // function : OpenGl_CappingPlaneResource |
63 | // purpose : |
64 | // ======================================================================= |
65 | OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane) |
e1c659da |
66 | : myPrimitives (NULL), |
67 | myOrientation (OpenGl_IdentityMatrix), |
8d3865d8 |
68 | myAspect (NULL), |
69 | myPlaneRoot (thePlane), |
70 | myEquationMod ((unsigned int )-1), |
71 | myAspectMod ((unsigned int )-1) |
e1c659da |
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 | } |
4269bd1b |
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 | // ======================================================================= |
3e05329c |
102 | void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& , |
103 | const Handle(Graphic3d_AspectFillArea3d)& theObjAspect) |
4269bd1b |
104 | { |
3e05329c |
105 | updateTransform(); |
106 | updateAspect (theObjAspect); |
4269bd1b |
107 | } |
108 | |
109 | // ======================================================================= |
110 | // function : Release |
111 | // purpose : |
112 | // ======================================================================= |
10b9c7df |
113 | void OpenGl_CappingPlaneResource::Release (OpenGl_Context* theContext) |
4269bd1b |
114 | { |
115 | OpenGl_Element::Destroy (theContext, myAspect); |
e1c659da |
116 | myPrimitives.Release (theContext); |
8d3865d8 |
117 | myEquationMod = (unsigned int )-1; |
118 | myAspectMod = (unsigned int )-1; |
4269bd1b |
119 | } |
120 | |
121 | // ======================================================================= |
3e05329c |
122 | // function : updateAspect |
4269bd1b |
123 | // purpose : |
124 | // ======================================================================= |
3e05329c |
125 | void OpenGl_CappingPlaneResource::updateAspect (const Handle(Graphic3d_AspectFillArea3d)& theObjAspect) |
4269bd1b |
126 | { |
3e05329c |
127 | if (myAspect == NULL) |
4269bd1b |
128 | { |
3e05329c |
129 | myAspect = new OpenGl_AspectFace(); |
130 | myAspectMod = myPlaneRoot->MCountAspect() - 1; // mark out of sync |
4269bd1b |
131 | } |
132 | |
3e05329c |
133 | if (theObjAspect.IsNull()) |
4269bd1b |
134 | { |
3e05329c |
135 | if (myAspectMod != myPlaneRoot->MCountAspect()) |
136 | { |
137 | myAspect->SetAspect (myPlaneRoot->CappingAspect()); |
138 | myAspectMod = myPlaneRoot->MCountAspect(); |
139 | } |
4269bd1b |
140 | return; |
141 | } |
142 | |
3e05329c |
143 | if (myFillAreaAspect.IsNull()) |
4269bd1b |
144 | { |
3e05329c |
145 | myFillAreaAspect = new Graphic3d_AspectFillArea3d(); |
4269bd1b |
146 | } |
3e05329c |
147 | if (myAspectMod != myPlaneRoot->MCountAspect()) |
148 | { |
149 | *myFillAreaAspect = *myPlaneRoot->CappingAspect(); |
150 | } |
151 | |
152 | if (myPlaneRoot->ToUseObjectMaterial()) |
153 | { |
154 | // only front material currently supported by capping rendering |
155 | myFillAreaAspect->SetFrontMaterial (theObjAspect->FrontMaterial()); |
156 | myFillAreaAspect->SetInteriorColor (theObjAspect->InteriorColor()); |
157 | } |
158 | if (myPlaneRoot->ToUseObjectTexture()) |
159 | { |
cc8cbabe |
160 | myFillAreaAspect->SetTextureSet (theObjAspect->TextureSet()); |
3e05329c |
161 | if (theObjAspect->ToMapTexture()) |
162 | { |
3e05329c |
163 | myFillAreaAspect->SetTextureMapOn(); |
164 | } |
165 | else |
166 | { |
167 | myFillAreaAspect->SetTextureMapOff(); |
168 | } |
169 | } |
170 | if (myPlaneRoot->ToUseObjectShader()) |
171 | { |
172 | myFillAreaAspect->SetShaderProgram (theObjAspect->ShaderProgram()); |
173 | } |
174 | |
175 | myAspect->SetAspect (myFillAreaAspect); |
4269bd1b |
176 | } |
177 | |
178 | // ======================================================================= |
3e05329c |
179 | // function : updateTransform |
4269bd1b |
180 | // purpose : |
181 | // ======================================================================= |
3e05329c |
182 | void OpenGl_CappingPlaneResource::updateTransform() |
4269bd1b |
183 | { |
184 | const Graphic3d_ClipPlane::Equation& anEquation = myPlaneRoot->GetEquation(); |
185 | if (myEquationMod == myPlaneRoot->MCountEquation()) |
186 | { |
187 | return; // nothing to update |
188 | } |
189 | |
190 | // re-evaluate infinite plane transformation matrix |
191 | Standard_ShortReal N[3] = |
192 | { (Standard_ShortReal)anEquation[0], |
193 | (Standard_ShortReal)anEquation[1], |
194 | (Standard_ShortReal)anEquation[2] }; |
195 | |
196 | Standard_ShortReal T[3] = |
197 | { (Standard_ShortReal)(anEquation[0] * -anEquation[3]), |
198 | (Standard_ShortReal)(anEquation[1] * -anEquation[3]), |
199 | (Standard_ShortReal)(anEquation[2] * -anEquation[3]) }; |
200 | |
201 | Standard_ShortReal L[3] = { 0.0f, 0.0f, 0.0f }; |
202 | Standard_ShortReal F[3] = { 0.0f, 0.0f, 0.0f }; |
203 | |
204 | // project plane normal onto OX to find left vector |
4269bd1b |
205 | Standard_ShortReal aProjLen = |
206 | sqrt ( (Standard_ShortReal)(anEquation[0] * anEquation[0]) |
207 | + (Standard_ShortReal)(anEquation[2] * anEquation[2])); |
79f4f036 |
208 | if (aProjLen < ShortRealSmall()) |
4269bd1b |
209 | { |
210 | L[0] = 1.0f; |
211 | } |
212 | else |
213 | { |
214 | L[0] = N[2] / aProjLen; |
215 | L[2] = -N[0] / aProjLen; |
216 | } |
217 | |
218 | // (-aLeft) x aNorm |
219 | F[0] = (-L[1])*N[2] - (-L[2])*N[1]; |
220 | F[1] = (-L[2])*N[0] - (-L[0])*N[2]; |
221 | F[2] = (-L[0])*N[1] - (-L[1])*N[0]; |
222 | |
223 | myOrientation.mat[0][0] = L[0]; |
224 | myOrientation.mat[0][1] = L[1]; |
225 | myOrientation.mat[0][2] = L[2]; |
226 | myOrientation.mat[0][3] = 0.0f; |
227 | |
228 | myOrientation.mat[1][0] = N[0]; |
229 | myOrientation.mat[1][1] = N[1]; |
230 | myOrientation.mat[1][2] = N[2]; |
231 | myOrientation.mat[1][3] = 0.0f; |
232 | |
233 | myOrientation.mat[2][0] = F[0]; |
234 | myOrientation.mat[2][1] = F[1]; |
235 | myOrientation.mat[2][2] = F[2]; |
236 | myOrientation.mat[2][3] = 0.0f; |
237 | |
238 | myOrientation.mat[3][0] = T[0]; |
239 | myOrientation.mat[3][1] = T[1]; |
240 | myOrientation.mat[3][2] = T[2]; |
241 | myOrientation.mat[3][3] = 1.0f; |
242 | |
243 | myEquationMod = myPlaneRoot->MCountEquation(); |
244 | } |