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