aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmath/llcamera.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llmath/llcamera.cpp')
-rw-r--r--linden/indra/llmath/llcamera.cpp155
1 files changed, 110 insertions, 45 deletions
diff --git a/linden/indra/llmath/llcamera.cpp b/linden/indra/llmath/llcamera.cpp
index cb9fae6..0f343bc 100644
--- a/linden/indra/llmath/llcamera.cpp
+++ b/linden/indra/llmath/llcamera.cpp
@@ -17,7 +17,8 @@
17 * There are special exceptions to the terms and conditions of the GPL as 17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception 18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or 19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception 20 * online at
21 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 * 22 *
22 * By copying, modifying or distributing this software, you acknowledge 23 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above, 24 * that you have read and understood your obligations described above,
@@ -50,33 +51,38 @@ LLCamera::LLCamera() :
50} 51}
51 52
52 53
53LLCamera::LLCamera(F32 z_field_of_view, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane) : 54LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane) :
54 LLCoordFrame(), 55 LLCoordFrame(),
55 mView(z_field_of_view),
56 mAspect(aspect_ratio),
57 mViewHeightInPixels(view_height_in_pixels), 56 mViewHeightInPixels(view_height_in_pixels),
58 mNearPlane(near_plane),
59 mFarPlane(far_plane),
60 mFixedDistance(-1.f), 57 mFixedDistance(-1.f),
61 mPlaneCount(6) 58 mPlaneCount(6)
62{ 59{
63 if (mView < MIN_FIELD_OF_VIEW) { mView = MIN_FIELD_OF_VIEW; } 60 mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
64 else if (mView > MAX_FIELD_OF_VIEW) { mView = MAX_FIELD_OF_VIEW; } 61 mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE);
62 if(far_plane < 0) far_plane = DEFAULT_FAR_PLANE;
63 mFarPlane = llclamp(far_plane, MIN_FAR_PLANE, MAX_FAR_PLANE);
65 64
66 if (mAspect < MIN_ASPECT_RATIO) { mAspect = MIN_ASPECT_RATIO; } 65 setView(vertical_fov_rads);
67 else if (mAspect > MAX_ASPECT_RATIO) { mAspect = MAX_ASPECT_RATIO; } 66}
68
69 if (mNearPlane < MIN_NEAR_PLANE) { mNearPlane = MIN_NEAR_PLANE; }
70 else if (mNearPlane > MAX_NEAR_PLANE) { mNearPlane = MAX_NEAR_PLANE; }
71 67
72 if (mFarPlane < 0) { mFarPlane = DEFAULT_FAR_PLANE; }
73 else if (mFarPlane < MIN_FAR_PLANE) { mFarPlane = MIN_FAR_PLANE; }
74 else if (mFarPlane > MAX_FAR_PLANE) { mFarPlane = MAX_FAR_PLANE; }
75 68
76 calculateFrustumPlanes(); 69// ---------------- LLCamera::getFoo() member functions ----------------
77}
78 70
71F32 LLCamera::getMinView() const
72{
73 // minimum vertical fov needs to be constrained in narrow windows.
74 return mAspect > 1
75 ? MIN_FIELD_OF_VIEW // wide views
76 : MIN_FIELD_OF_VIEW * 1/mAspect; // clamps minimum width in narrow views
77}
79 78
79F32 LLCamera::getMaxView() const
80{
81 // maximum vertical fov needs to be constrained in wide windows.
82 return mAspect > 1
83 ? MAX_FIELD_OF_VIEW / mAspect // clamps maximum width in wide views
84 : MAX_FIELD_OF_VIEW; // narrow views
85}
80 86
81// ---------------- LLCamera::setFoo() member functions ---------------- 87// ---------------- LLCamera::setFoo() member functions ----------------
82 88
@@ -92,11 +98,9 @@ void LLCamera::disableUserClipPlane()
92 mPlaneCount = 6; 98 mPlaneCount = 6;
93} 99}
94 100
95void LLCamera::setView(F32 field_of_view) 101void LLCamera::setView(F32 vertical_fov_rads)
96{ 102{
97 mView = field_of_view; 103 mView = llclamp(vertical_fov_rads, MIN_FIELD_OF_VIEW, MAX_FIELD_OF_VIEW);
98 if (mView < MIN_FIELD_OF_VIEW) { mView = MIN_FIELD_OF_VIEW; }
99 else if (mView > MAX_FIELD_OF_VIEW) { mView = MAX_FIELD_OF_VIEW; }
100 calculateFrustumPlanes(); 104 calculateFrustumPlanes();
101} 105}
102 106
@@ -110,27 +114,21 @@ void LLCamera::setViewHeightInPixels(S32 height)
110 114
111void LLCamera::setAspect(F32 aspect_ratio) 115void LLCamera::setAspect(F32 aspect_ratio)
112{ 116{
113 mAspect = aspect_ratio; 117 mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
114 if (mAspect < MIN_ASPECT_RATIO) { mAspect = MIN_ASPECT_RATIO; }
115 else if (mAspect > MAX_ASPECT_RATIO) { mAspect = MAX_ASPECT_RATIO; }
116 calculateFrustumPlanes(); 118 calculateFrustumPlanes();
117} 119}
118 120
119 121
120void LLCamera::setNear(F32 near_plane) 122void LLCamera::setNear(F32 near_plane)
121{ 123{
122 mNearPlane = near_plane; 124 mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE);
123 if (mNearPlane < MIN_NEAR_PLANE) { mNearPlane = MIN_NEAR_PLANE; }
124 else if (mNearPlane > MAX_NEAR_PLANE) { mNearPlane = MAX_NEAR_PLANE; }
125 calculateFrustumPlanes(); 125 calculateFrustumPlanes();
126} 126}
127 127
128 128
129void LLCamera::setFar(F32 far_plane) 129void LLCamera::setFar(F32 far_plane)
130{ 130{
131 mFarPlane = far_plane; 131 mFarPlane = llclamp(far_plane, MIN_FAR_PLANE, MAX_FAR_PLANE);
132 if (mFarPlane < MIN_FAR_PLANE) { mFarPlane = MIN_FAR_PLANE; }
133 else if (mFarPlane > MAX_FAR_PLANE) { mFarPlane = MAX_FAR_PLANE; }
134 calculateFrustumPlanes(); 132 calculateFrustumPlanes();
135} 133}
136 134
@@ -180,28 +178,95 @@ S32 LLCamera::AABBInFrustum(const LLVector3 &center, const LLVector3& radius)
180 U8 mask = 0; 178 U8 mask = 0;
181 S32 result = 2; 179 S32 result = 2;
182 180
183 for (U32 i = 0; i < mPlaneCount; i++) 181 if (radius.magVecSquared() > mFrustumCornerDist * mFrustumCornerDist)
184 { 182 { //box is larger than frustum, check frustum quads against box planes
185 mask = mAgentPlanes[i].mask;
186 LLPlane p = mAgentPlanes[i].p;
187 LLVector3 n = LLVector3(p);
188 float d = p.mV[3];
189 LLVector3 rscale = radius.scaledVec(scaler[mask]);
190
191 LLVector3 minp = center - rscale;
192 LLVector3 maxp = center + rscale;
193 183
194 if (n * minp > -d) 184 static const LLVector3 dir[] =
195 { 185 {
196 return 0; 186 LLVector3(1, 0, 0),
187 LLVector3(-1, 0, 0),
188 LLVector3(0, 1, 0),
189 LLVector3(0, -1, 0),
190 LLVector3(0, 0, 1),
191 LLVector3(0, 0, -1)
192 };
193
194 U32 quads[] =
195 {
196 0, 1, 2, 3,
197 0, 1, 5, 4,
198 2, 3, 7, 6,
199 3, 0, 7, 4,
200 1, 2, 6, 4,
201 4, 5, 6, 7
202 };
203
204 result = 0;
205
206 BOOL total_inside = TRUE;
207 for (U32 i = 0; i < 6; i++)
208 {
209 LLVector3 p = center + radius.scaledVec(dir[i]);
210 F32 d = -p*dir[i];
211
212 for (U32 j = 0; j < 6; j++)
213 { //for each quad
214 F32 dist = mAgentFrustum[quads[j*4+0]]*dir[i] + d;
215 if (dist > 0)
216 { //at least one frustum point is outside the AABB
217 total_inside = FALSE;
218 for (U32 k = 1; k < 4; k++)
219 { //for each other point on quad
220 if ( mAgentFrustum[quads[j*4+k]]*dir[i]+d <= 0.f)
221 { //quad is straddling some plane of AABB
222 return 1;
223 }
224 }
225 }
226 else
227 {
228 for (U32 k = 1; k < 4; k++)
229 {
230 if (mAgentFrustum[quads[j*4+k]]*dir[i]+d > 0.f)
231 {
232 return 1;
233 }
234 }
235 }
236 }
197 } 237 }
198 238
199 if (n * maxp > -d) 239 if (total_inside)
200 { 240 {
201 result = 1; 241 result = 1;
202 } 242 }
203 } 243 }
244 else
245 {
246 for (U32 i = 0; i < mPlaneCount; i++)
247 {
248 mask = mAgentPlanes[i].mask;
249 LLPlane p = mAgentPlanes[i].p;
250 LLVector3 n = LLVector3(p);
251 float d = p.mV[3];
252 LLVector3 rscale = radius.scaledVec(scaler[mask]);
253
254 LLVector3 minp = center - rscale;
255 LLVector3 maxp = center + rscale;
256
257 if (n * minp > -d)
258 {
259 return 0;
260 }
261
262 if (n * maxp > -d)
263 {
264 result = 1;
265 }
266 }
267 }
204 268
269
205 return result; 270 return result;
206} 271}
207 272