0031682: Visualization - Prs3d_ShadingAspect::SetTransparency() has no effect with...
[occt.git] / src / SelectMgr / SelectMgr_FrustumBuilder.cxx
CommitLineData
f751596e 1// Created on: 2014-11-24
2// Created by: Varvara POSKONINA
3// Copyright (c) 2005-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 <SelectMgr_FrustumBuilder.hxx>
17
92efcf78 18IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_FrustumBuilder,Standard_Transient)
19
f751596e 20#define DOT(A, B) (A.x() * B.x() + A.y() * B.y() + A.z() * B.z())
21#define LENGTH(A) (std::sqrt (A.x() * A.x() + A.y() * A.y() + A.z() * A.z()))
22
bf3977c9 23
f751596e 24//=======================================================================
25// function : SelectMgr_FrustumBuilder
26// purpose : Creates new frustum builder with empty matrices
27//=======================================================================
28SelectMgr_FrustumBuilder::SelectMgr_FrustumBuilder()
825aa485 29: myWorldView(),
f751596e 30 myProjection(),
825aa485 31 myWorldViewProjState(),
f751596e 32 myWidth (INT_MAX),
33 myHeight (INT_MAX),
825aa485 34 myIsViewportSet (Standard_False)
35{
36 //
37}
f751596e 38
39//=======================================================================
825aa485 40// function : SetWorldViewMatrix
41// purpose : Stores current world view transformation matrix
f751596e 42//=======================================================================
825aa485 43void SelectMgr_FrustumBuilder::SetWorldViewMatrix (const Graphic3d_Mat4d& theWorldView)
f751596e 44{
825aa485 45 myWorldView = theWorldView;
f751596e 46}
47
48//=======================================================================
825aa485 49// function : WorldViewMatrix
50// purpose : Returns current world view transformation matrix
51//=======================================================================
52const Graphic3d_Mat4d& SelectMgr_FrustumBuilder::WorldViewMatrix() const
53{
54 return myWorldView;
55}
56
57//=======================================================================
58// function : SetProjectionMatrix
f751596e 59// purpose : Stores current projection matrix
60//=======================================================================
825aa485 61void SelectMgr_FrustumBuilder::SetProjectionMatrix (const Graphic3d_Mat4d& theProjection)
f751596e 62{
63 myProjection = theProjection;
64}
65
825aa485 66//=======================================================================
67// function : ProjectionMatrix
68// purpose : Returns current projection matrix
69//=======================================================================
70const Graphic3d_Mat4d& SelectMgr_FrustumBuilder::ProjectionMatrix() const
71{
72 return myProjection;
73}
74
75//=======================================================================
76// function : SetWorldViewProjState
77// purpose : Stores current world view projection matrix state
78//=======================================================================
79void SelectMgr_FrustumBuilder::SetWorldViewProjState (const Graphic3d_WorldViewProjState& theState)
80{
81 myWorldViewProjState = theState;
82}
83
84//=======================================================================
85// function : WorldViewProjState
86// purpose : Returns current world view projection matrix state
87//=======================================================================
88const Graphic3d_WorldViewProjState& SelectMgr_FrustumBuilder::WorldViewProjState() const
89{
90 return myWorldViewProjState;
91}
92
f751596e 93//=======================================================================
94// function : SetWindowSize
95// purpose : Stores current window width and height
96//=======================================================================
97void SelectMgr_FrustumBuilder::SetWindowSize (const Standard_Integer theWidth,
98 const Standard_Integer theHeight)
99{
100 myWidth = theWidth;
101 myHeight = theHeight;
102}
103
104//=======================================================================
105// function : SetViewport
106// purpose : Stores current viewport coordinates
107//=======================================================================
108void SelectMgr_FrustumBuilder::SetViewport (const Standard_Real theX,
109 const Standard_Real theY,
110 const Standard_Real theWidth,
111 const Standard_Real theHeight)
112{
113 myViewport = NCollection_Vec4<Standard_Real> (theX, theY, theWidth, theHeight);
114 myIsViewportSet = Standard_True;
115}
116
91d96372 117//=======================================================================
118// function : WindowSize
119// purpose :
120//=======================================================================
121void SelectMgr_FrustumBuilder::WindowSize (Standard_Integer& theWidth,
099f3513 122 Standard_Integer& theHeight) const
91d96372 123{
124 theWidth = myWidth;
125 theHeight = myHeight;
126}
127
f751596e 128//=======================================================================
129// function : InvalidateViewport
130// purpose :
131//=======================================================================
132void SelectMgr_FrustumBuilder::InvalidateViewport()
133{
134 myIsViewportSet = Standard_False;
135}
136
137//=======================================================================
138// function : SignedPlanePntDist
139// purpose : Calculates signed distance between plane with equation
140// theEq and point thePnt
141//=======================================================================
142Standard_Real SelectMgr_FrustumBuilder::SignedPlanePntDist (const SelectMgr_Vec3& theEq,
143 const SelectMgr_Vec3& thePnt) const
144{
145 const Standard_Real aNormLength = LENGTH (theEq);
146 const Standard_Real anInvNormLength = aNormLength < Precision::Confusion() ? 0.0 : 1.0 / aNormLength;
147 const Standard_Real anA = theEq.x() * anInvNormLength;
148 const Standard_Real aB = theEq.y() * anInvNormLength;
149 const Standard_Real aC = theEq.z() * anInvNormLength;
150 return anA * thePnt.x() + aB * thePnt.y() + aC * thePnt.z();
151}
152
f751596e 153//=======================================================================
154// function : safePointCast
155// purpose :
156//=======================================================================
157static NCollection_Vec4<Standard_Real> safePointCast (const gp_Pnt& thePnt)
158{
159 Standard_Real aLim = 1e15f;
160
161 // have to deal with values greater then max float
162 gp_Pnt aSafePoint = thePnt;
163 const Standard_Real aBigFloat = aLim * 0.1f;
164 if (Abs (aSafePoint.X()) > aLim)
165 aSafePoint.SetX (aSafePoint.X() >= 0 ? aBigFloat : -aBigFloat);
166 if (Abs (aSafePoint.Y()) > aLim)
167 aSafePoint.SetY (aSafePoint.Y() >= 0 ? aBigFloat : -aBigFloat);
168 if (Abs (aSafePoint.Z()) > aLim)
169 aSafePoint.SetZ (aSafePoint.Z() >= 0 ? aBigFloat : -aBigFloat);
170
171 // convert point
172 NCollection_Vec4<Standard_Real> aPnt (aSafePoint.X(), aSafePoint.Y(), aSafePoint.Z(), 1.0);
173
174 return aPnt;
175}
176
177//=======================================================================
178// function : unProject
179// purpose : Unprojects point from NDC coords to 3d world space
180//=======================================================================
3bf9a45f 181gp_Pnt SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
f751596e 182{
183 Graphic3d_Mat4d aInvView;
184 Graphic3d_Mat4d aInvProj;
185
186 // this case should never happen
825aa485 187 if (!myWorldView.Inverted (aInvView) || !myProjection.Inverted (aInvProj))
f751596e 188 {
3bf9a45f 189 return gp_Pnt (0.0, 0.0, 0.0);
f751596e 190 }
191
192 // use compatible type of point
193 NCollection_Vec4<Standard_Real> aPnt = safePointCast (thePnt);
194
195 aPnt = aInvProj * aPnt; // convert to view coordinate space
196 aPnt = aInvView * aPnt; // convert to world coordinate space
197
198 const Standard_Real aInvW = 1.0 / Standard_Real (aPnt.w());
199
3bf9a45f 200 return gp_Pnt (aPnt.x() * aInvW, aPnt.y() * aInvW, aPnt.z() * aInvW);
f751596e 201}
202
203// =======================================================================
204// function : ProjectPntOnViewPlane
205// purpose : Projects 2d screen point onto view frustum plane:
206// theZ = 0 - near plane,
207// theZ = 1 - far plane
208// =======================================================================
3bf9a45f 209gp_Pnt SelectMgr_FrustumBuilder::ProjectPntOnViewPlane (const Standard_Real& theX,
210 const Standard_Real& theY,
211 const Standard_Real& theZ) const
f751596e 212{
213 Standard_Real aX, anY, aZ;
214
215 // map coords to NDC
216 if (!myIsViewportSet)
217 {
218 aX = 2.0 * theX / myWidth - 1.0;
219 anY = (myHeight - 1 - theY) / myHeight * 2.0 - 1.0;
220 aZ = 2.0 * theZ - 1.0;
221 }
222 else
223 {
224 aX = 2.0 * (theX - myWidth * myViewport.x()) /
225 (myWidth * (myViewport.z() - myViewport.x())) - 1.0;
226 anY = 2.0 * (theY - myHeight * myViewport.y()) /
227 (myHeight * (myViewport.w() - myViewport.y())) - 1.0;
228 aZ = theZ;
229 }
230
231 return unProject (gp_Pnt (aX, anY, aZ));
232}