aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llwaterpatch.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llwaterpatch.h')
-rw-r--r--linden/indra/newview/llwaterpatch.h316
1 files changed, 316 insertions, 0 deletions
diff --git a/linden/indra/newview/llwaterpatch.h b/linden/indra/newview/llwaterpatch.h
new file mode 100644
index 0000000..7779d60
--- /dev/null
+++ b/linden/indra/newview/llwaterpatch.h
@@ -0,0 +1,316 @@
1/**
2 * @file llwaterpatch.h
3 * @brief LLWaterTri class header file
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_WATER_PATCH_H
29#define LL_WATER_PATCH_H
30
31#include "llmath.h"
32#include "v3math.h"
33#include "llroam.h"
34
35const U8 MAX_LEVEL = 10;
36
37class LL2Coord
38{
39protected:
40 S32 mX;
41 S32 mY;
42public:
43 LL2Coord() {}
44 //LL2Coord() : mX(0), mY(0) {}
45 LL2Coord (S32 i, S32 j) : mX(i), mY(j) {}
46 LL2Coord operator+ (const LL2Coord& c) const
47 {
48 return LL2Coord(mX + c.mX, mY + c.mY);
49 }
50 LL2Coord operator* (F32 c) const
51 {
52 return LL2Coord(llround(mX * c), llround(mY * c));
53 }
54 S32 x() const { return mX; }
55 S32 y() const { return mY; }
56
57 S32& x() { return mX; }
58 S32& y() { return mY; }
59
60 LL2Coord middle(const LL2Coord& c2) const
61 {
62 return LL2Coord((x() + c2.x()) >> 1, (y() + c2.y()) >> 1);
63 }
64
65 S32 distance2(const LL2Coord& c2) const
66 {
67 S32 dx = x() - c2.x();
68 S32 dy = y() - c2.y();
69
70 return dx * dx + dy * dy;
71 }
72
73 F32 distance(const LL2Coord& c2) const
74 {
75 return (F32) sqrt((F32)distance2(c2));
76 }
77};
78
79
80
81
82
83
84class LLWaterGrid;
85
86class LLWaterTri : public LLRoamTriNode
87{
88protected:
89 LL2Coord mLvtx; // Left vertex
90 LL2Coord mRvtx; // Right vertex
91 LL2Coord mTvtx; // Top vertex
92 LL2Coord mMiddle; // Top vertex
93
94 F32 mSize;
95
96 BOOL mCurr;
97 BOOL mRefine;
98
99public:
100 static LL2Coord sCam;
101 static F32 sClipFar;
102 static U32 sMaxDivLevel;
103 static U32 sMinStep;
104
105 static BOOL sCurrRound;
106
107
108public:
109 LLWaterTri (const LL2Coord& l, const LL2Coord& r, const LL2Coord& t):
110 LLRoamTriNode(0, 0, 0), mLvtx(l), mRvtx(r), mTvtx(t), mRefine(FALSE)
111 {
112 mSize = mLvtx.distance(mRvtx) * sMinStep;
113 mCurr = sCurrRound;
114 mMiddle = mLvtx.middle(mRvtx);
115 }
116
117 LLWaterTri (U8 level = 0, S8 type = 0, LLWaterTri* par = 0);
118
119 virtual LLRoamTriNode* newLChild()
120 {
121 return new LLWaterTri(mLevel+1, -1, this);
122 }
123 virtual LLRoamTriNode* newRChild()
124 {
125 return new LLWaterTri(mLevel+1, 1, this);
126 }
127
128 virtual ~LLWaterTri() {}
129
130 const LL2Coord& Lvtx() const { return mLvtx; }
131 const LL2Coord& Rvtx() const { return mRvtx; }
132 const LL2Coord& Tvtx() const { return mTvtx; }
133
134 F32 size() const { return mSize; }
135
136 LL2Coord middleSide() const { return mMiddle; }//middle(mLvtx, mRvtx); }
137
138 void setLvtx(const LL2Coord& c) { mLvtx = c; }
139 void setRvtx(const LL2Coord& c) { mRvtx = c; }
140 void setTvtx(const LL2Coord& c) { mTvtx = c; }
141
142 void updatePassive();
143 BOOL refine();
144 void initForcefulRefine()
145 {
146 setUpToDate();
147 mRefine = TRUE;
148 }
149 void flushFromQueue() { setUpToDate(); }
150
151 BOOL upToDate() const { return mCurr == sCurrRound; }
152 void setUpToDate() { mCurr = sCurrRound; }
153 void setNotUpToDate() { mCurr = !sCurrRound; }
154 static void nextRound() { sCurrRound = !sCurrRound; }
155
156 BOOL checkUpToDate() const
157 {
158 BOOL ok = leaf() ? upToDate() :
159 upToDate() && ((LLWaterTri*)Lchild())->upToDate() && ((LLWaterTri*)Rchild())->upToDate();
160 if (!ok)
161 return ok;
162 else
163 return ok;
164 }
165
166};
167
168
169
170
171class LLWaterPatch : public LLRoamPatch
172{
173protected:
174 LL2Coord mOrig; // Bottom left vertex
175 U32 mSize;
176 U32 mRegionWidth;
177 LLVector3 mCenter;
178 BOOL mVis;
179
180public:
181 LLWaterPatch() :
182 LLRoamPatch(MAX_LEVEL, TRUE), mOrig(0, 0), mSize(32), mRegionWidth(256) {}
183
184 LLWaterPatch(const LL2Coord o, U32 size, U32 width, const LLVector3& center,
185 U8 max_level = MAX_LEVEL, BOOL back_slash = TRUE) :
186 LLRoamPatch(back_slash, max_level), mOrig(o), mSize(size), mRegionWidth(width), mCenter(center)
187 { createTris(); }
188
189 LLWaterPatch(S32 o1, S32 o2, U32 size, U32 width, const LLVector3& center,
190 U8 max_level = MAX_LEVEL, BOOL back_slash = TRUE) :
191 LLRoamPatch(back_slash, max_level), mOrig(o1, o2), mSize(size), mRegionWidth(width), mCenter(center)
192 { createTris(); }
193
194
195 const LL2Coord& orig() const { return mOrig; }
196 void set (S32 o1, S32 o2, U32 size, U32 width, const LLVector3& center,
197 U8 max_level = MAX_LEVEL, BOOL back_slash = TRUE)
198 {
199 deleteTris();
200 mBackSlash = back_slash;
201 mMaxLevel = max_level;
202 mOrig.x() = o1;
203 mOrig.y() = o2;
204 mSize = size;
205 mCenter = center;
206 mRegionWidth = width;
207 mNumTris = 0;
208 createTris();
209 }
210
211 void setMaxLevel (U8 max_level) { mMaxLevel = max_level; }
212
213 void createTris()
214 {
215 if (mBackSlash)
216 {
217 mTri[0] = new LLWaterTri(LL2Coord(mOrig.x() + mSize, mOrig.y()),
218 LL2Coord(mOrig.x(), mOrig.y() + mSize), mOrig);
219 mTri[1] = new LLWaterTri(LL2Coord(mOrig.x(), mOrig.y() + mSize),
220 LL2Coord(mOrig.x() + mSize, mOrig.y()),
221 LL2Coord(mOrig.x() + mSize, mOrig.y() + mSize));
222 } else {
223 mTri[0] = new LLWaterTri(mOrig,
224 LL2Coord(mOrig.x() + mSize, mOrig.y() + mSize),
225 LL2Coord(mOrig.x(), mOrig.y() + mSize));
226 mTri[1] = new LLWaterTri(LL2Coord(mOrig.x() + mSize, mOrig.y() + mSize),
227 mOrig,
228 LL2Coord(mOrig.x() + mSize, mOrig.y()));
229 }
230 setTris();
231 ((LLWaterTri*)mTri[0])->setUpToDate();
232 ((LLWaterTri*)mTri[1])->setUpToDate();
233 }
234 //virtual ~LLWaterPatch() {}
235 void setInvisible() { mVis = FALSE; }
236 void setVisible() { mVis = TRUE; }
237
238 BOOL visible() const { return mVis; }
239
240 BOOL updateTree(const LLVector3 &camera_pos, const LLVector3 &look_at, const LLVector3 &reg_orig)
241 {
242 const static F32 patch_rad = mRegionWidth * F_SQRT2 * 0.5f;
243
244 LLVector3 to_patch = reg_orig + mCenter - camera_pos;
245 F32 to_patch_dist = to_patch.normVec();
246
247 if ( to_patch_dist < patch_rad)
248 {
249 setVisible();
250 update();
251 } else {
252 const F32 sin_min_angle = patch_rad / to_patch_dist;
253 const F32 cos_min_angle = (F32)sqrt(1.f - sin_min_angle * sin_min_angle);
254 const F32 cos_max = OO_SQRT2 * (cos_min_angle - sin_min_angle);
255
256 if (to_patch * look_at > cos_max)
257 {
258 setVisible();
259 update();
260 } else {
261 setInvisible();
262 updatePassive();
263 }
264 }
265
266 return mVis;
267 }
268
269 BOOL updateVisibility(const LLVector3 &camera_pos, const LLVector3 &look_at, const LLVector3 &reg_orig)
270 {
271 const static F32 patch_rad = mRegionWidth * F_SQRT2 * 0.5f;
272 const static U32 reg_width_half = mRegionWidth / 2;
273 //const static F32 patch_rad2 = patch_rad * patch_rad;
274
275 LLVector3 to_patch = reg_orig + mCenter - camera_pos;
276 //const F32 to_patch_dist2D2 = to_patch.mV[VX] * to_patch.mV[VX] + to_patch.mV[VY] * to_patch.mV[VY];
277
278 if (fabs(to_patch.mV[VX]) <= reg_width_half && fabs(to_patch.mV[VY]) <= reg_width_half)
279 //if ( to_patch_dist2D2 < patch_rad2)
280 {
281 setVisible();
282 } else {
283 F32 to_patch_dist = to_patch.normVec();
284 //const F32 to_patch_dist = sqrt(to_patch_dist2D2 + to_patch.mV[VZ] * to_patch.mV[VZ]);
285 const F32 sin_min_angle = patch_rad / to_patch_dist;
286 if (sin_min_angle >= 1)
287 {
288 setVisible();
289 } else {
290 const F32 cos_min_angle = (F32)sqrt(1.f - sin_min_angle * sin_min_angle);
291 const F32 cos_max = OO_SQRT2 * (cos_min_angle - sin_min_angle);
292
293 if (to_patch * look_at > cos_max)
294 {
295 setVisible();
296 } else {
297 setInvisible();
298 }
299 }
300 }
301
302 return mVis;
303 }
304 void checkUpToDate() const
305 {
306 for (U8 h = 0; h < 2; h++)
307 {
308 ((LLWaterTri*)left())->checkUpToDate();
309 ((LLWaterTri*)right())->checkUpToDate();
310 }
311 }
312
313};
314
315
316#endif