summaryrefslogtreecommitdiff
path: root/src/V3d/V3d_PerspectiveView.cxx
blob: a2d975c96addb54802785a1b67431a81b8f40ea2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// File         V3d_PerspectiveView.cxx
// Created      September 1992
// Author       GG
// Modified	07-10-96 : CQ ; correction PRO4522
// Modified	23-02-98 : FMN ; Replace PI by Standard_PI
// Modified     25-02-98 : FMN ; PERF.27: Optimisation of view creation from an existing view
// Modified     02-09-98 : FMN ; Correction problem of angle calculation in V3d_PerspectiveView::Angle(). 
// Modified     23-11-98 : FMN ; PRO14896: Correction of the management of the perspective (cf Programming Guide)
//				 If the angle is modified the WindowLimit changes not the focal.
//		22-12-98 : FMN ; Rename CSF_WALKTHROW into CSF_WALKTHROUGH

// IMP240100       //GG -> Activates WalkThrough model.

//-Copyright    MatraDatavision 1991,1992

//-Version

//-Design       

//-Warning      

//-References

//-Language     C++ 2.1


// for Test method

// for the class
#include <V3d_View.hxx>
#include <V3d_PerspectiveView.ixx>
#include <Visual3d_View.hxx>
#include <Viewer_BadValue.hxx>

V3d_PerspectiveView::V3d_PerspectiveView (const Handle(V3d_Viewer)& VM):V3d_View (VM,V3d_PERSPECTIVE) {
  MyViewMapping.SetProjection(Visual3d_TOP_PERSPECTIVE) ;
  SetAngle(VM->DefaultAngle()) ;	
//  SetZoom(10.0, Standard_True);
  SetViewMappingDefault() ;
  SetViewOrientationDefault() ;
}

V3d_PerspectiveView::V3d_PerspectiveView (const Handle(V3d_Viewer)& VM, const Handle(V3d_OrthographicView)& V):V3d_View (VM,V,V3d_PERSPECTIVE) {
  MyViewMapping.SetProjection(Visual3d_TOP_PERSPECTIVE) ;
  SetAngle(VM->DefaultAngle()) ;	
//  SetZoom(10.0, Standard_True);
  SetViewMappingDefault() ;
  SetViewOrientationDefault() ;
}

V3d_PerspectiveView::V3d_PerspectiveView (const Handle(V3d_Viewer)& VM, const Handle(V3d_PerspectiveView)& V):V3d_View (VM,V,V3d_PERSPECTIVE) {
  MyViewMapping.SetProjection(Visual3d_TOP_PERSPECTIVE) ;
//  SetZoom(10.0, Standard_True);
  SetViewMappingDefault() ;
  SetViewOrientationDefault() ;
}

Handle(V3d_PerspectiveView) V3d_PerspectiveView::Copy() const {
  return new V3d_PerspectiveView(this->Viewer(),this);}

//-Methods, in order

void V3d_PerspectiveView::SetAngle(const Standard_Real Angle) {
  
  Standard_Real focale,Umin,Vmin,Umax,Vmax,Dxv,Dyv,Rap,Xrp,Yrp;     

  Viewer_BadValue_Raise_if ( Angle <= 0. || Angle >= Standard_PI, "V3d_PerspectiveView::SetAngle, bad angle");

  MyViewMapping.WindowLimit(Umin,Vmin,Umax,Vmax) ;
  Dxv = Abs(Umax - Umin)/2. ; Dyv = Abs(Vmax - Vmin)/2.;
  focale = Focale();
  Xrp = (Umin + Umax)/2. ; Yrp = (Vmin + Vmax)/2. ;
  Rap = Dxv / Dyv;
  if( Dxv >= Dyv ) {
      Dyv = Abs(focale * tan(Angle/2.)) ;
      Dxv = Rap * Dyv;
  } else {
      Dxv = Abs(focale * tan(Angle/2.)) ;
      Dyv = Dxv / Rap;
  }
  Umin = Xrp - Dxv ; Umax = Xrp + Dxv ;
  Vmin = Yrp - Dyv ; Vmax = Yrp + Dyv ;
  MyViewMapping.SetWindowLimit(Umin,Vmin,Umax,Vmax) ;
  MyView->SetViewMapping(MyViewMapping) ;
  ImmediateUpdate();
}

Standard_Real V3d_PerspectiveView::Angle()const  {
  
//  Graphic3d_Vertex Prp ;
  Standard_Real focale,Umin,Vmin,Umax,Vmax,Dxv,Dyv ;     
  Standard_Real angle = Standard_PI ;
  
  MyViewMapping.WindowLimit(Umin,Vmin,Umax,Vmax) ;
  focale = Focale() ;
  Dxv = (Umax - Umin)/2. ; Dyv = (Vmax - Vmin)/2. ;
  if( focale > 0. ) {
    if( Dxv >= Dyv ) {
      angle = 2.*atan(Dyv/focale) ;
    } else {
      angle = 2.*atan(Dxv/focale) ;
    }
  }
  
  return angle ;
}

void V3d_PerspectiveView::SetPerspective(const Standard_Real Angle, const Standard_Real UVRatio,
                                         const Standard_Real ZNear, const Standard_Real ZFar)
{
  Standard_Real Umin,Vmin,Umax,Vmax,Yrp,Zrp,du,dv;

  Viewer_BadValue_Raise_if ( ZNear <= 0. || ZFar <= 0. || ZNear >= ZFar, "V3d_PerspectiveView::SetPerspective, bad distances");
  Viewer_BadValue_Raise_if ( Angle <= 0. || Angle >= Standard_PI, "V3d_PerspectiveView::SetAngle, bad angle");

  Graphic3d_Vertex PRP = MyViewMapping.ProjectionReferencePoint() ;
  Yrp = Zrp = 0.;

  PRP.SetCoord(Zrp, Yrp, Zrp);
  MyViewMapping.SetProjectionReferencePoint(PRP);

  Standard_Real size = (ZFar - ZNear) / 2.;

  MyViewMapping.SetFrontPlaneDistance(size);
  MyViewMapping.SetBackPlaneDistance(-size);
  MyViewMapping.SetViewPlaneDistance(size);

  // recompute window limits by mapping to view plane
  dv = Abs(ZNear * tan(Angle/2.));
  du = dv * UVRatio;
  Umin = -du; Umax = du;
  Vmin = -dv; Vmax = dv;
  MyViewMapping.SetWindowLimit(Umin, Vmin, Umax, Vmax);

  MyView->SetViewMapping(MyViewMapping) ;
  ImmediateUpdate();
}