0dbc528d3ce7ef4e3b2d67ecbfed4c03151f5979
[occt.git] / src / V3d / V3d_PerspectiveView.cxx
1 // Created by: GG
2 // Copyright (c) 1991-1999 Matra Datavision
3 // Copyright (c) 1999-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20 // Modified     07-10-96 : CQ ; correction PRO4522
21 // Modified     23-02-98 : FMN ; Replace PI by Standard_PI
22 // Modified     25-02-98 : FMN ; PERF.27: Optimisation of view creation from an existing view
23 // Modified     02-09-98 : FMN ; Correction problem of angle calculation in V3d_PerspectiveView::Angle(). 
24 // Modified     23-11-98 : FMN ; PRO14896: Correction of the management of the perspective (cf Programming Guide)
25 //                               If the angle is modified the WindowLimit changes not the focal.
26 //              22-12-98 : FMN ; Rename CSF_WALKTHROW into CSF_WALKTHROUGH
27
28 // IMP240100       //GG -> Activates WalkThrough model.
29
30
31 //-Version
32
33 //-Design       
34
35 //-Warning      
36
37 //-References
38
39 //-Language     C++ 2.1
40
41
42 // for Test method
43
44 // for the class
45 #include <V3d_View.hxx>
46 #include <V3d_PerspectiveView.ixx>
47 #include <Visual3d_View.hxx>
48 #include <Viewer_BadValue.hxx>
49
50 V3d_PerspectiveView::V3d_PerspectiveView (const Handle(V3d_Viewer)& VM):V3d_View (VM,V3d_PERSPECTIVE) {
51   MyViewMapping.SetProjection(Visual3d_TOP_PERSPECTIVE) ;
52   SetAngle(VM->DefaultAngle()) ;        
53 //  SetZoom(10.0, Standard_True);
54   SetViewMappingDefault() ;
55   SetViewOrientationDefault() ;
56 }
57
58 V3d_PerspectiveView::V3d_PerspectiveView (const Handle(V3d_Viewer)& VM, const Handle(V3d_OrthographicView)& V):V3d_View (VM,V,V3d_PERSPECTIVE) {
59   MyViewMapping.SetProjection(Visual3d_TOP_PERSPECTIVE) ;
60   SetAngle(VM->DefaultAngle()) ;        
61 //  SetZoom(10.0, Standard_True);
62   SetViewMappingDefault() ;
63   SetViewOrientationDefault() ;
64 }
65
66 V3d_PerspectiveView::V3d_PerspectiveView (const Handle(V3d_Viewer)& VM, const Handle(V3d_PerspectiveView)& V):V3d_View (VM,V,V3d_PERSPECTIVE) {
67   MyViewMapping.SetProjection(Visual3d_TOP_PERSPECTIVE) ;
68 //  SetZoom(10.0, Standard_True);
69   SetViewMappingDefault() ;
70   SetViewOrientationDefault() ;
71 }
72
73 Handle(V3d_PerspectiveView) V3d_PerspectiveView::Copy() const {
74   return new V3d_PerspectiveView(this->Viewer(),this);}
75
76 //-Methods, in order
77
78 void V3d_PerspectiveView::SetAngle(const Standard_Real Angle) {
79   
80   Standard_Real focale,Umin,Vmin,Umax,Vmax,Dxv,Dyv,Rap,Xrp,Yrp;     
81
82   Viewer_BadValue_Raise_if ( Angle <= 0. || Angle >= M_PI, "V3d_PerspectiveView::SetAngle, bad angle");
83
84   MyViewMapping.WindowLimit(Umin,Vmin,Umax,Vmax) ;
85   Dxv = Abs(Umax - Umin)/2. ; Dyv = Abs(Vmax - Vmin)/2.;
86   focale = Focale();
87   Xrp = (Umin + Umax)/2. ; Yrp = (Vmin + Vmax)/2. ;
88   Rap = Dxv / Dyv;
89   if( Dxv >= Dyv ) {
90       Dyv = Abs(focale * tan(Angle/2.)) ;
91       Dxv = Rap * Dyv;
92   } else {
93       Dxv = Abs(focale * tan(Angle/2.)) ;
94       Dyv = Dxv / Rap;
95   }
96   Umin = Xrp - Dxv ; Umax = Xrp + Dxv ;
97   Vmin = Yrp - Dyv ; Vmax = Yrp + Dyv ;
98   MyViewMapping.SetWindowLimit(Umin,Vmin,Umax,Vmax) ;
99   MyView->SetViewMapping(MyViewMapping) ;
100   ImmediateUpdate();
101 }
102
103 Standard_Real V3d_PerspectiveView::Angle()const  {
104   
105 //  Graphic3d_Vertex Prp ;
106   Standard_Real focale,Umin,Vmin,Umax,Vmax,Dxv,Dyv ;     
107   Standard_Real angle = M_PI ;
108   
109   MyViewMapping.WindowLimit(Umin,Vmin,Umax,Vmax) ;
110   focale = Focale() ;
111   Dxv = (Umax - Umin)/2. ; Dyv = (Vmax - Vmin)/2. ;
112   if( focale > 0. ) {
113     if( Dxv >= Dyv ) {
114       angle = 2.*atan(Dyv/focale) ;
115     } else {
116       angle = 2.*atan(Dxv/focale) ;
117     }
118   }
119   
120   return angle ;
121 }
122
123 void V3d_PerspectiveView::SetPerspective(const Standard_Real Angle, const Standard_Real UVRatio,
124                                          const Standard_Real ZNear, const Standard_Real ZFar)
125 {
126   Standard_Real Umin,Vmin,Umax,Vmax,Xrp,Yrp,Zrp,du,dv;
127
128   Viewer_BadValue_Raise_if ( ZNear <= 0. || ZFar <= 0. || ZNear >= ZFar, "V3d_PerspectiveView::SetPerspective, bad distances");
129   Viewer_BadValue_Raise_if ( Angle <= 0. || Angle >= M_PI, "V3d_PerspectiveView::SetAngle, bad angle");
130
131   Graphic3d_Vertex PRP = MyViewMapping.ProjectionReferencePoint() ;
132   Xrp = Yrp = Zrp = 0.;
133
134   PRP.SetCoord(Zrp, Yrp, Zrp);
135   MyViewMapping.SetProjectionReferencePoint(PRP);
136
137   Standard_Real size = (ZFar - ZNear) / 2.;
138
139   MyViewMapping.SetFrontPlaneDistance(size);
140   MyViewMapping.SetBackPlaneDistance(-size);
141   MyViewMapping.SetViewPlaneDistance(size);
142
143   // recompute window limits by mapping to view plane
144   dv = Abs(ZNear * tan(Angle/2.));
145   du = dv * UVRatio;
146   Umin = -du; Umax = du;
147   Vmin = -dv; Vmax = dv;
148   MyViewMapping.SetWindowLimit(Umin, Vmin, Umax, Vmax);
149
150   MyView->SetViewMapping(MyViewMapping) ;
151   ImmediateUpdate();
152 }