1 /****************************************************************************
2 * VCGLib o o *
3 * Visual and Computer Graphics Library o o *
4 * _ O _ *
5 * Copyright(C) 2004-2016 \/)\/ *
6 * Visual Computing Lab /\/| *
7 * ISTI - Italian National Research Council | *
8 * \ *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
20 * for more details. *
21 * *
22 ****************************************************************************/
23 /****************************************************************************
24 History
25
26 $Log: not supported by cvs2svn $
27 Revision 1.9 2005/03/02 15:13:45 ponchio
28 Minimal fix in remoteness (Bugged anyway)
29
30 Revision 1.8 2005/02/22 14:33:04 ponchio
31 small bugs
32
33 Revision 1.7 2005/01/21 18:06:05 ponchio
34 Added remoteness ("distance" from frustum)
35
36 Revision 1.6 2004/10/04 12:33:02 ponchio
37 Cleaning up and planes init more stable.
38
39 Revision 1.5 2004/09/28 10:23:28 ponchio
40 Various generic changes.
41
42 Revision 1.4 2004/05/12 20:55:18 ponchio
43 *** empty log message ***
44
45 Revision 1.3 2004/03/31 15:06:41 ponchio
46 #include <camera> -> #include <view>
47
48 Revision 1.2 2004/03/25 14:55:25 ponchio
49 Adding copyright.
50
51
52 ****************************************************************************/
53
54 #ifndef FRUSTUM_H
55 #define FRUSTUM_H
56
57 #include <wrap/gui/view.h>
58 #include <vcg/space/plane3.h>
59 #include <vcg/space/line3.h>
60
61 #include <iostream>
62 using namespace std;
63
64 namespace vcg {
65
66 template <class T> class Frustum: public View<T> {
67 public:
68 void GetView();
69 void SetView(const float *_proj, const float *_modelview, const int *_viewport);
70 Point3<T> ViewPoint();
71 T Resolution(float dist = 1);
72 bool IsOutside(Point3<T> &point);
73 T Remoteness(Point3<T> &point, T radius);
74 T IsOutside(Point3<T> &point, T radius);
75 T Distance(Point3<T> &point, int plane);
76 T range(Point3<T> &point, T radius, T &closest, T &farthest);
77
78 protected:
79 T resolution;
80 Plane3<T> planes[6];
81 Point3<T> view_point;
82 void UpdateView();
83 };
84
85
86 typedef Frustum<float> Frustumf;
87 typedef Frustum<double> Frustumd;
88
89
90 //Implementation
ViewPoint()91 template <class T> Point3<T> Frustum<T>::ViewPoint() {
92 return view_point;
93 }
94
Resolution(float dist)95 template <class T> T Frustum<T>::Resolution(float dist) {
96 return resolution * dist;
97 }
98
IsOutside(Point3<T> & point)99 template <class T> bool Frustum<T>::IsOutside(Point3<T> &point) {
100 Point3<T> r = Project(point);
101 if(r[0] < View<T>::viewport[0] || r[0] > View<T>::viewport[0]+View<T>::viewport[2] ||
102 r[1] < View<T>::viewport[1] || r[1] > View<T>::viewport[1]+View<T>::viewport[3])
103 return true;
104 return false;
105 }
106
Remoteness(Point3<T> & point,T radius)107 template <class T> T Frustum<T>::Remoteness(Point3<T> &point, T radius) {
108 Point3<T> r = Project(point);
109 T dist = (point - view_point).Norm();
110 if(dist < radius) return 0;
111 T rad = 1 + radius / (resolution * dist);
112 T mindist = 0;
113 T tmp;
114 tmp = View<T>::viewport[0] - r[0] - rad;
115 if(tmp > mindist) mindist = tmp;
116 tmp = r[0] - rad - (View<T>::viewport[0] + View<T>::viewport[2]);
117 if(tmp > mindist) mindist = tmp;
118
119 tmp = View<T>::viewport[1] - r[1] - rad;
120 if(tmp > mindist) mindist = tmp;
121 tmp = r[1] - rad - (View<T>::viewport[1] + View<T>::viewport[3]);
122 if(tmp > mindist) mindist = tmp;
123
124 if(mindist == 0) return 0;
125 return 1 + (mindist / (View<T>::viewport[0] + View<T>::viewport[2]));
126 }
127
IsOutside(Point3<T> & point,T radius)128 template <class T> T Frustum<T>::IsOutside(Point3<T> &point, T radius) {
129 T dist = 0;
130 for(int i = 0; i < 4; i++) {
131 T d = -Distance(point, i) - radius;
132 if(d > dist) dist = d;
133 }
134 return dist;
135 }
136
range(Point3<T> & point,T radius,T & closest,T & farthest)137 template <class T> T Frustum<T>::range(Point3<T> &point, T radius, T &closest, T &farthest) {
138 //4 near 5 far
139 T dist = (view_point - point).Norm();
140 closest = dist - radius;
141 farthest = dist + radius;
142 }
143
Distance(Point3<T> & point,int plane)144 template <class T> T Frustum<T>::Distance(Point3<T> &point, int plane) {
145 return vcg::SignedDistancePlanePoint(planes[plane], point);
146 }
147
GetView()148 template <class T> void Frustum<T>::GetView() {
149 View<T>::GetView();
150 UpdateView();
151 }
152 template <class T> void Frustum<T>::SetView(const float *_proj = NULL,
153 const float *_modelview = NULL,
154 const int *_viewport = NULL) {
155 View<T>::SetView(_proj, _modelview, _viewport);
156 UpdateView();
157 }
158
UpdateView()159 template <class T> void Frustum<T>::UpdateView() {
160 float t = (float)(View<T>::viewport[1] +View<T>:: viewport[3]);
161 float b = (float)View<T>::viewport[1];
162 float r = (float)(View<T>::viewport[0] + View<T>::viewport[2]);
163 float l = (float)View<T>::viewport[0];
164
165 Point3<T> nw = UnProject(Point3<T>(l, b, 0.0f));
166 Point3<T> sw = UnProject(Point3<T>(l, t, 0.0f));
167 Point3<T> ne = UnProject(Point3<T>(r, b, 0.0f));
168 Point3<T> se = UnProject(Point3<T>(r, t, 0.0f));
169 Point3<T> NW = UnProject(Point3<T>(l, b, 1.0f));
170 Point3<T> SW = UnProject(Point3<T>(l, t, 1.0f));
171 Point3<T> NE = UnProject(Point3<T>(r, b, 1.0f));
172 Point3<T> SE = UnProject(Point3<T>(r, t, 1.0f));
173
174 view_point = View<T>::ViewPoint();
175
176 planes[0].Init(nw, NW, NE);
177 planes[1].Init(ne, NE, SE);
178 planes[2].Init(se, SE, SW);
179 planes[3].Init(sw, SW, NW);
180 planes[4].Init(se, sw, nw);
181 planes[5].Init(SW, SE, NE);
182
183 //compute resolution: sizeo of a pixel unitary distance from view_point
184 resolution = ((ne + NE)/2 - (nw + NW)/2).Norm() /
185 (View<T>::viewport[2] * ((ne + NE + nw + NW)/4 - view_point).Norm());
186 }
187
188 }//namespace
189
190 #endif
191
192
193
194
195
196