aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmath/llvolume.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llmath/llvolume.h')
-rw-r--r--linden/indra/llmath/llvolume.h901
1 files changed, 901 insertions, 0 deletions
diff --git a/linden/indra/llmath/llvolume.h b/linden/indra/llmath/llvolume.h
new file mode 100644
index 0000000..63981da
--- /dev/null
+++ b/linden/indra/llmath/llvolume.h
@@ -0,0 +1,901 @@
1/**
2 * @file llvolume.h
3 * @brief LLVolume base class.
4 *
5 * Copyright (c) 2002-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_LLVOLUME_H
29#define LL_LLVOLUME_H
30
31#include <iostream>
32
33class LLProfileParams;
34class LLPathParams;
35class LLVolumeParams;
36class LLProfile;
37class LLPath;
38class LLVolumeFace;
39class LLVolume;
40
41#include "lldarray.h"
42#include "lluuid.h"
43#include "v4color.h"
44//#include "vmath.h"
45#include "v2math.h"
46#include "v3math.h"
47#include "llquaternion.h"
48#include "llstrider.h"
49#include "v4coloru.h"
50#include "llmemory.h"
51
52//============================================================================
53
54const S32 MIN_DETAIL_FACES = 6;
55const S32 MIN_LOD = 0;
56const S32 MAX_LOD = 3;
57
58// These are defined here but are not enforced at this level,
59// rather they are here for the convenience of code that uses
60// the LLVolume class.
61const F32 MIN_VOLUME_PROFILE_WIDTH = 0.05f;
62const F32 MIN_VOLUME_PATH_WIDTH = 0.05f;
63
64const F32 CUT_QUANTA = 0.005f;
65const F32 SCALE_QUANTA = 0.01f;
66const F32 SHEAR_QUANTA = 0.01f;
67const F32 TAPER_QUANTA = 0.01f;
68const F32 REV_QUANTA = 0.015f;
69
70
71//============================================================================
72
73// useful masks
74const LLPCode LL_PCODE_HOLLOW_MASK = 0x80; // has a thickness
75const LLPCode LL_PCODE_SEGMENT_MASK = 0x40; // segments (1 angle)
76const LLPCode LL_PCODE_PATCH_MASK = 0x20; // segmented segments (2 angles)
77const LLPCode LL_PCODE_HEMI_MASK = 0x10; // half-primitives get their own type per PR's dictum
78const LLPCode LL_PCODE_BASE_MASK = 0x0F;
79
80 // primitive shapes
81const LLPCode LL_PCODE_CUBE = 1;
82const LLPCode LL_PCODE_PRISM = 2;
83const LLPCode LL_PCODE_TETRAHEDRON = 3;
84const LLPCode LL_PCODE_PYRAMID = 4;
85const LLPCode LL_PCODE_CYLINDER = 5;
86const LLPCode LL_PCODE_CONE = 6;
87const LLPCode LL_PCODE_SPHERE = 7;
88const LLPCode LL_PCODE_TORUS = 8;
89const LLPCode LL_PCODE_VOLUME = 9;
90
91 // surfaces
92//const LLPCode LL_PCODE_SURFACE_TRIANGLE = 10;
93//const LLPCode LL_PCODE_SURFACE_SQUARE = 11;
94//const LLPCode LL_PCODE_SURFACE_DISC = 12;
95
96const LLPCode LL_PCODE_APP = 14; // App specific pcode (for viewer/sim side only objects)
97const LLPCode LL_PCODE_LEGACY = 15;
98
99// Pcodes for legacy objects
100//const LLPCode LL_PCODE_LEGACY_ATOR = 0x10 | LL_PCODE_LEGACY; // ATOR
101const LLPCode LL_PCODE_LEGACY_AVATAR = 0x20 | LL_PCODE_LEGACY; // PLAYER
102//const LLPCode LL_PCODE_LEGACY_BIRD = 0x30 | LL_PCODE_LEGACY; // BIRD
103//const LLPCode LL_PCODE_LEGACY_DEMON = 0x40 | LL_PCODE_LEGACY; // DEMON
104const LLPCode LL_PCODE_LEGACY_GRASS = 0x50 | LL_PCODE_LEGACY; // GRASS
105const LLPCode LL_PCODE_TREE_NEW = 0x60 | LL_PCODE_LEGACY; // new trees
106//const LLPCode LL_PCODE_LEGACY_ORACLE = 0x70 | LL_PCODE_LEGACY; // ORACLE
107const LLPCode LL_PCODE_LEGACY_PART_SYS = 0x80 | LL_PCODE_LEGACY; // PART_SYS
108const LLPCode LL_PCODE_LEGACY_ROCK = 0x90 | LL_PCODE_LEGACY; // ROCK
109//const LLPCode LL_PCODE_LEGACY_SHOT = 0xA0 | LL_PCODE_LEGACY; // BASIC_SHOT
110//const LLPCode LL_PCODE_LEGACY_SHOT_BIG = 0xB0 | LL_PCODE_LEGACY;
111//const LLPCode LL_PCODE_LEGACY_SMOKE = 0xC0 | LL_PCODE_LEGACY; // SMOKE
112//const LLPCode LL_PCODE_LEGACY_SPARK = 0xD0 | LL_PCODE_LEGACY;// SPARK
113const LLPCode LL_PCODE_LEGACY_TEXT_BUBBLE = 0xE0 | LL_PCODE_LEGACY; // TEXTBUBBLE
114const LLPCode LL_PCODE_LEGACY_TREE = 0xF0 | LL_PCODE_LEGACY; // TREE
115
116 // hemis
117const LLPCode LL_PCODE_CYLINDER_HEMI = LL_PCODE_CYLINDER | LL_PCODE_HEMI_MASK;
118const LLPCode LL_PCODE_CONE_HEMI = LL_PCODE_CONE | LL_PCODE_HEMI_MASK;
119const LLPCode LL_PCODE_SPHERE_HEMI = LL_PCODE_SPHERE | LL_PCODE_HEMI_MASK;
120const LLPCode LL_PCODE_TORUS_HEMI = LL_PCODE_TORUS | LL_PCODE_HEMI_MASK;
121
122
123// Volumes consist of a profile at the base that is swept around
124// a path to make a volume.
125// The profile code
126const U8 LL_PCODE_PROFILE_MASK = 0x0f;
127const U8 LL_PCODE_PROFILE_MIN = 0x00;
128const U8 LL_PCODE_PROFILE_CIRCLE = 0x00;
129const U8 LL_PCODE_PROFILE_SQUARE = 0x01;
130const U8 LL_PCODE_PROFILE_ISOTRI = 0x02;
131const U8 LL_PCODE_PROFILE_EQUALTRI = 0x03;
132const U8 LL_PCODE_PROFILE_RIGHTTRI = 0x04;
133const U8 LL_PCODE_PROFILE_CIRCLE_HALF = 0x05;
134const U8 LL_PCODE_PROFILE_MAX = 0x05;
135
136// Stored in the profile byte
137const U8 LL_PCODE_HOLE_MASK = 0xf0;
138const U8 LL_PCODE_HOLE_MIN = 0x00;
139const U8 LL_PCODE_HOLE_SAME = 0x00; // same as outside profile
140const U8 LL_PCODE_HOLE_CIRCLE = 0x10;
141const U8 LL_PCODE_HOLE_SQUARE = 0x20;
142const U8 LL_PCODE_HOLE_TRIANGLE = 0x30;
143const U8 LL_PCODE_HOLE_MAX = 0x03; // min/max needs to be >> 4 of real min/max
144
145const U8 LL_PCODE_PATH_IGNORE = 0x00;
146const U8 LL_PCODE_PATH_MIN = 0x01; // min/max needs to be >> 4 of real min/max
147const U8 LL_PCODE_PATH_LINE = 0x10;
148const U8 LL_PCODE_PATH_CIRCLE = 0x20;
149const U8 LL_PCODE_PATH_CIRCLE2 = 0x30;
150const U8 LL_PCODE_PATH_TEST = 0x40;
151const U8 LL_PCODE_PATH_FLEXIBLE = 0x80;
152const U8 LL_PCODE_PATH_MAX = 0x08;
153
154//============================================================================
155
156// face identifiers
157typedef U16 LLFaceID;
158
159const LLFaceID LL_FACE_PATH_BEGIN = 0x1 << 0;
160const LLFaceID LL_FACE_PATH_END = 0x1 << 1;
161const LLFaceID LL_FACE_INNER_SIDE = 0x1 << 2;
162const LLFaceID LL_FACE_PROFILE_BEGIN = 0x1 << 3;
163const LLFaceID LL_FACE_PROFILE_END = 0x1 << 4;
164const LLFaceID LL_FACE_OUTER_SIDE_0 = 0x1 << 5;
165const LLFaceID LL_FACE_OUTER_SIDE_1 = 0x1 << 6;
166const LLFaceID LL_FACE_OUTER_SIDE_2 = 0x1 << 7;
167const LLFaceID LL_FACE_OUTER_SIDE_3 = 0x1 << 8;
168
169//============================================================================
170
171class LLProfileParams
172{
173public:
174 LLProfileParams()
175 {
176 mBegin = 0;
177 mEnd = 1;
178 mHollow = 0;
179 mCurveType = LL_PCODE_PROFILE_SQUARE;
180 }
181
182 LLProfileParams(U8 curve, F32 begin, F32 end, F32 hollow)
183 : mCurveType(curve), mBegin(begin), mEnd(end), mHollow(hollow)
184 {
185 }
186
187 LLProfileParams(U8 curve, U8 begin, U8 end, U8 hollow)
188 {
189 mCurveType = curve;
190 F32 temp_f32 = begin * CUT_QUANTA;
191 if (temp_f32 > 1.f)
192 {
193 temp_f32 = 1.f;
194 }
195 mBegin = temp_f32;
196 temp_f32 = end * CUT_QUANTA;
197 if (temp_f32 > 1.f)
198 {
199 temp_f32 = 1.f;
200 }
201 mEnd = 1.f - temp_f32;
202 temp_f32 = hollow * SCALE_QUANTA;
203 if (temp_f32 > 1.f)
204 {
205 temp_f32 = 1.f;
206 }
207 mHollow = temp_f32;
208 }
209
210 bool operator==(const LLProfileParams &params) const;
211 bool operator!=(const LLProfileParams &params) const;
212 bool operator<(const LLProfileParams &params) const;
213
214 void copyParams(const LLProfileParams &params);
215
216 BOOL importFile(FILE *fp);
217 BOOL exportFile(FILE *fp) const;
218
219 BOOL importLegacyStream(std::istream& input_stream);
220 BOOL exportLegacyStream(std::ostream& output_stream) const;
221
222 LLSD asLLSD() const;
223 operator LLSD() const { return asLLSD(); }
224 bool fromLLSD(LLSD& sd);
225
226 const F32& getBegin () const { return mBegin; }
227 const F32& getEnd () const { return mEnd; }
228 const F32& getHollow() const { return mHollow; }
229 const U8& getCurveType () const { return mCurveType; }
230
231 void setCurveType(const U32 type) { mCurveType = type;}
232 void setBegin(const F32 begin) { mBegin = (begin >= 1.0f) ? 0.0f : ((int) (begin * 1000))/1000.0f;}
233 void setEnd(const F32 end) { mEnd = (end <= 0.0f) ? 1.0f : ((int) (end * 1000))/1000.0f;}
234 void setHollow(const F32 hollow) { mHollow = ((int) (hollow * 1000))/1000.0f;}
235
236 friend std::ostream& operator<<(std::ostream &s, const LLProfileParams &profile_params);
237
238protected:
239 // Profile params
240 U8 mCurveType;
241 F32 mBegin;
242 F32 mEnd;
243 F32 mHollow;
244
245 U32 mCRC;
246};
247
248inline bool LLProfileParams::operator==(const LLProfileParams &params) const
249{
250 return
251 (getCurveType() == params.getCurveType()) &&
252 (getBegin() == params.getBegin()) &&
253 (getEnd() == params.getEnd()) &&
254 (getHollow() == params.getHollow());
255}
256
257inline bool LLProfileParams::operator!=(const LLProfileParams &params) const
258{
259 return
260 (getCurveType() != params.getCurveType()) ||
261 (getBegin() != params.getBegin()) ||
262 (getEnd() != params.getEnd()) ||
263 (getHollow() != params.getHollow());
264}
265
266
267inline bool LLProfileParams::operator<(const LLProfileParams &params) const
268{
269 if (getCurveType() != params.getCurveType())
270 {
271 return getCurveType() < params.getCurveType();
272 }
273 else
274 if (getBegin() != params.getBegin())
275 {
276 return getBegin() < params.getBegin();
277 }
278 else
279 if (getEnd() != params.getEnd())
280 {
281 return getEnd() < params.getEnd();
282 }
283 else
284 {
285 return getHollow() < params.getHollow();
286 }
287}
288
289#define U8_TO_F32(x) (F32)(*((S8 *)&x))
290
291class LLPathParams
292{
293public:
294 LLPathParams()
295 {
296 mBegin = 0;
297 mEnd = 1;
298 mScale.setVec(1,1);
299 mShear.setVec(0,0);
300 mCurveType = LL_PCODE_PATH_LINE;
301 mTwistBegin = 0;
302 mTwistEnd = 0;
303 mRadiusOffset = 0;
304 mTaper.setVec(0,0);
305 mRevolutions = 1;
306 mSkew = 0;
307 }
308
309 LLPathParams(U8 curve, F32 begin, F32 end, F32 scx, F32 scy, F32 shx, F32 shy, F32 twistend, F32 twistbegin, F32 radiusoffset, F32 tx, F32 ty, F32 revolutions, F32 skew)
310 : mCurveType(curve), mBegin(begin), mEnd(end), mTwistBegin(twistbegin), mTwistEnd(twistend),
311 mRadiusOffset(radiusoffset), mRevolutions(revolutions), mSkew(skew)
312 {
313 mScale.setVec(scx,scy);
314 mShear.setVec(shx,shy);
315 mTaper.setVec(tx,ty);
316 }
317
318 LLPathParams(U8 curve, U8 begin, U8 end, U8 scx, U8 scy, U8 shx, U8 shy, U8 twistend, U8 twistbegin, U8 radiusoffset, U8 tx, U8 ty, U8 revolutions, U8 skew)
319 {
320 mCurveType = curve;
321 mBegin = (F32)(begin * SCALE_QUANTA);
322 mEnd = (F32)(100.f - end) * SCALE_QUANTA;
323 if (mEnd > 1.f)
324 mEnd = 1.f;
325 mScale.setVec((F32) (200 - scx) * SCALE_QUANTA,(F32) (200 - scy) * SCALE_QUANTA);
326 mShear.setVec(U8_TO_F32(shx) * SHEAR_QUANTA,U8_TO_F32(shy) * SHEAR_QUANTA);
327 mTwistBegin = U8_TO_F32(twistbegin) * SCALE_QUANTA;
328 mTwistEnd = U8_TO_F32(twistend) * SCALE_QUANTA;
329 mRadiusOffset = U8_TO_F32(radiusoffset) * SCALE_QUANTA;
330 mTaper.setVec(U8_TO_F32(tx) * TAPER_QUANTA,U8_TO_F32(ty) * TAPER_QUANTA);
331 mRevolutions = ((F32)revolutions) * REV_QUANTA + 1.0f;
332 mSkew = U8_TO_F32(skew) * SCALE_QUANTA;
333 }
334
335 bool operator==(const LLPathParams &params) const;
336 bool operator!=(const LLPathParams &params) const;
337 bool operator<(const LLPathParams &params) const;
338
339 void copyParams(const LLPathParams &params);
340
341 BOOL importFile(FILE *fp);
342 BOOL exportFile(FILE *fp) const;
343
344 BOOL importLegacyStream(std::istream& input_stream);
345 BOOL exportLegacyStream(std::ostream& output_stream) const;
346
347 LLSD asLLSD() const;
348 operator LLSD() const { return asLLSD(); }
349 bool fromLLSD(LLSD& sd);
350
351 const F32& getBegin() const { return mBegin; }
352 const F32& getEnd() const { return mEnd; }
353 const LLVector2 &getScale() const { return mScale; }
354 const F32& getScaleX() const { return mScale.mV[0]; }
355 const F32& getScaleY() const { return mScale.mV[1]; }
356 const LLVector2 getBeginScale() const;
357 const LLVector2 getEndScale() const;
358 const LLVector2 &getShear() const { return mShear; }
359 const F32& getShearX() const { return mShear.mV[0]; }
360 const F32& getShearY() const { return mShear.mV[1]; }
361 const U8& getCurveType () const { return mCurveType; }
362
363 const F32& getTwistBegin() const { return mTwistBegin; }
364 const F32& getTwistEnd() const { return mTwistEnd; }
365 const F32& getTwist() const { return mTwistEnd; } // deprecated
366 const F32& getRadiusOffset() const { return mRadiusOffset; }
367 const LLVector2 &getTaper() const { return mTaper; }
368 const F32& getTaperX() const { return mTaper.mV[0]; }
369 const F32& getTaperY() const { return mTaper.mV[1]; }
370 const F32& getRevolutions() const { return mRevolutions; }
371 const F32& getSkew() const { return mSkew; }
372
373 void setCurveType(const U8 type) { mCurveType = type; }
374 void setBegin(const F32 begin) { mBegin = begin; }
375 void setEnd(const F32 end) { mEnd = end; }
376
377 void setScale(const F32 x, const F32 y) { mScale.setVec(x,y); }
378 void setScaleX(const F32 v) { mScale.mV[VX] = v; }
379 void setScaleY(const F32 v) { mScale.mV[VY] = v; }
380 void setShear(const F32 x, const F32 y) { mShear.setVec(x,y); }
381 void setShearX(const F32 v) { mShear.mV[VX] = v; }
382 void setShearY(const F32 v) { mShear.mV[VY] = v; }
383
384 void setTwistBegin(const F32 twist_begin) { mTwistBegin = twist_begin; }
385 void setTwistEnd(const F32 twist_end) { mTwistEnd = twist_end; }
386 void setTwist(const F32 twist) { setTwistEnd(twist); } // deprecated
387 void setRadiusOffset(const F32 radius_offset){ mRadiusOffset = radius_offset; }
388 void setTaper(const F32 x, const F32 y) { mTaper.setVec(x,y); }
389 void setTaperX(const F32 v) { mTaper.mV[VX] = v; }
390 void setTaperY(const F32 v) { mTaper.mV[VY] = v; }
391 void setRevolutions(const F32 revolutions) { mRevolutions = revolutions; }
392 void setSkew(const F32 skew) { mSkew = skew; }
393
394 friend std::ostream& operator<<(std::ostream &s, const LLPathParams &path_params);
395
396protected:
397 // Path params
398 U8 mCurveType;
399 F32 mBegin;
400 F32 mEnd;
401 LLVector2 mScale;
402 LLVector2 mShear;
403
404 F32 mTwistBegin;
405 F32 mTwistEnd;
406 F32 mRadiusOffset;
407 LLVector2 mTaper;
408 F32 mRevolutions;
409 F32 mSkew;
410
411 U32 mCRC;
412};
413
414inline bool LLPathParams::operator==(const LLPathParams &params) const
415{
416 return
417 (getCurveType() == params.getCurveType()) &&
418 (getScale() == params.getScale()) &&
419 (getBegin() == params.getBegin()) &&
420 (getEnd() == params.getEnd()) &&
421 (getShear() == params.getShear()) &&
422 (getTwist() == params.getTwist()) &&
423 (getTwistBegin() == params.getTwistBegin()) &&
424 (getRadiusOffset() == params.getRadiusOffset()) &&
425 (getTaper() == params.getTaper()) &&
426 (getRevolutions() == params.getRevolutions()) &&
427 (getSkew() == params.getSkew());
428}
429
430inline bool LLPathParams::operator!=(const LLPathParams &params) const
431{
432 return
433 (getCurveType() != params.getCurveType()) ||
434 (getScale() != params.getScale()) ||
435 (getBegin() != params.getBegin()) ||
436 (getEnd() != params.getEnd()) ||
437 (getShear() != params.getShear()) ||
438 (getTwist() != params.getTwist()) ||
439 (getTwistBegin() !=params.getTwistBegin()) ||
440 (getRadiusOffset() != params.getRadiusOffset()) ||
441 (getTaper() != params.getTaper()) ||
442 (getRevolutions() != params.getRevolutions()) ||
443 (getSkew() != params.getSkew());
444}
445
446
447inline bool LLPathParams::operator<(const LLPathParams &params) const
448{
449 if( getCurveType() != params.getCurveType())
450 {
451 return getCurveType() < params.getCurveType();
452 }
453 else
454 if( getScale() != params.getScale())
455 {
456 return getScale() < params.getScale();
457 }
458 else
459 if( getBegin() != params.getBegin())
460 {
461 return getBegin() < params.getBegin();
462 }
463 else
464 if( getEnd() != params.getEnd())
465 {
466 return getEnd() < params.getEnd();
467 }
468 else
469 if( getShear() != params.getShear())
470 {
471 return getShear() < params.getShear();
472 }
473 else
474 if( getTwist() != params.getTwist())
475 {
476 return getTwist() < params.getTwist();
477 }
478 else
479 if( getTwistBegin() != params.getTwistBegin())
480 {
481 return getTwistBegin() < params.getTwistBegin();
482 }
483 else
484 if( getRadiusOffset() != params.getRadiusOffset())
485 {
486 return getRadiusOffset() < params.getRadiusOffset();
487 }
488 else
489 if( getTaper() != params.getTaper())
490 {
491 return getTaper() < params.getTaper();
492 }
493 else
494 if( getRevolutions() != params.getRevolutions())
495 {
496 return getRevolutions() < params.getRevolutions();
497 }
498 else
499 {
500 return getSkew() < params.getSkew();
501 }
502}
503
504typedef LLVolumeParams* LLVolumeParamsPtr;
505typedef const LLVolumeParams* const_LLVolumeParamsPtr;
506
507class LLVolumeParams
508{
509public:
510 LLVolumeParams()
511 {
512 }
513
514 LLVolumeParams(LLProfileParams &profile, LLPathParams &path)
515 : mProfileParams(profile), mPathParams(path)
516 {
517 }
518
519 bool operator==(const LLVolumeParams &params) const;
520 bool operator!=(const LLVolumeParams &params) const;
521 bool operator<(const LLVolumeParams &params) const;
522
523
524 void copyParams(const LLVolumeParams &params);
525
526 const LLProfileParams &getProfileParams() const {return mProfileParams;}
527 LLProfileParams &getProfileParams() {return mProfileParams;}
528 const LLPathParams &getPathParams() const {return mPathParams;}
529 LLPathParams &getPathParams() {return mPathParams;}
530
531 BOOL importFile(FILE *fp);
532 BOOL exportFile(FILE *fp) const;
533
534 BOOL importLegacyStream(std::istream& input_stream);
535 BOOL exportLegacyStream(std::ostream& output_stream) const;
536
537 LLSD asLLSD() const;
538 operator LLSD() const { return asLLSD(); }
539 bool fromLLSD(LLSD& sd);
540
541 bool setType(U8 profile, U8 path);
542
543 //void setBeginS(const F32 beginS) { mProfileParams.setBegin(beginS); } // range 0 to 1
544 //void setBeginT(const F32 beginT) { mPathParams.setBegin(beginT); } // range 0 to 1
545 //void setEndS(const F32 endS) { mProfileParams.setEnd(endS); } // range 0 to 1, must be greater than begin
546 //void setEndT(const F32 endT) { mPathParams.setEnd(endT); } // range 0 to 1, must be greater than begin
547
548 bool setBeginAndEndS(const F32 begin, const F32 end); // both range from 0 to 1, begin must be less than end
549 bool setBeginAndEndT(const F32 begin, const F32 end); // both range from 0 to 1, begin must be less than end
550
551 bool setHollow(const F32 hollow); // range 0 to 1
552 bool setRatio(const F32 x) { return setRatio(x,x); } // 0 = point, 1 = same as base
553 bool setShear(const F32 x) { return setShear(x,x); } // 0 = no movement,
554 bool setRatio(const F32 x, const F32 y); // 0 = point, 1 = same as base
555 bool setShear(const F32 x, const F32 y); // 0 = no movement
556
557 bool setTwistBegin(const F32 twist_begin); // range -1 to 1
558 bool setTwistEnd(const F32 twist_end); // range -1 to 1
559 bool setTwist(const F32 twist) { return setTwistEnd(twist); } // deprecated
560 bool setTaper(const F32 x, const F32 y) { bool pass_x = setTaperX(x); bool pass_y = setTaperY(y); return pass_x && pass_y; }
561 bool setTaperX(const F32 v); // -1 to 1
562 bool setTaperY(const F32 v); // -1 to 1
563 bool setRevolutions(const F32 revolutions); // 1 to 4
564 bool setRadiusOffset(const F32 radius_offset);
565 bool setSkew(const F32 skew);
566
567 static bool validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 hollow,
568 U8 path_curve, F32 path_begin, F32 path_end,
569 F32 scx, F32 scy, F32 shx, F32 shy,
570 F32 twistend, F32 twistbegin, F32 radiusoffset,
571 F32 tx, F32 ty, F32 revolutions, F32 skew);
572
573 const F32& getBeginS() const { return mProfileParams.getBegin(); }
574 const F32& getBeginT() const { return mPathParams.getBegin(); }
575 const F32& getEndS() const { return mProfileParams.getEnd(); }
576 const F32& getEndT() const { return mPathParams.getEnd(); }
577
578 const F32& getHollow() const { return mProfileParams.getHollow(); }
579 const F32& getTwist() const { return mPathParams.getTwist(); }
580 const F32& getRatio() const { return mPathParams.getScaleX(); }
581 const F32& getRatioX() const { return mPathParams.getScaleX(); }
582 const F32& getRatioY() const { return mPathParams.getScaleY(); }
583 const F32& getShearX() const { return mPathParams.getShearX(); }
584 const F32& getShearY() const { return mPathParams.getShearY(); }
585
586 const F32& getTwistBegin()const { return mPathParams.getTwistBegin(); }
587 const F32& getRadiusOffset() const { return mPathParams.getRadiusOffset(); }
588 const F32& getTaper() const { return mPathParams.getTaperX(); }
589 const F32& getTaperX() const { return mPathParams.getTaperX(); }
590 const F32& getTaperY() const { return mPathParams.getTaperY(); }
591 const F32& getRevolutions() const { return mPathParams.getRevolutions(); }
592 const F32& getSkew() const { return mPathParams.getSkew(); }
593
594 BOOL isConvex() const;
595
596 // 'begin' and 'end' should be in range [0, 1] (they will be clamped)
597 // (begin, end) = (0, 1) will not change the volume
598 // (begin, end) = (0, 0.5) will reduce the volume to the first half of its profile/path (S/T)
599 void reduceS(F32 begin, F32 end);
600 void reduceT(F32 begin, F32 end);
601
602 struct compare
603 {
604 bool operator()( const const_LLVolumeParamsPtr& first, const const_LLVolumeParamsPtr& second) const
605 {
606 return (*first < *second);
607 }
608 };
609
610 friend std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
611
612protected:
613 LLProfileParams mProfileParams;
614 LLPathParams mPathParams;
615};
616
617
618class LLProfile
619{
620public:
621 LLProfile(const LLProfileParams &params) : mParams(params)
622 {
623 mTotal = 2;
624 mTotalOut = 0;
625 mDirty = TRUE;
626 mConcave = FALSE;
627 }
628
629 ~LLProfile();
630
631 S32 getTotal() const { return mTotal; }
632 S32 getTotalOut() const { return mTotalOut; } // Total number of outside points
633 BOOL isHollow() const { return (mParams.getHollow() > 0); }
634 BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); }
635 BOOL isOpen() const { return mOpen; }
636 void setDirty() { mDirty = TRUE; }
637 BOOL generate(BOOL path_open, F32 detail = 1.0f, S32 split = 0);
638 BOOL isConcave() const { return mConcave; }
639public:
640 const LLProfileParams &mParams;
641
642 struct Face
643 {
644 S32 mIndex;
645 S32 mCount;
646 F32 mScaleU;
647 BOOL mCap;
648 BOOL mFlat;
649 LLFaceID mFaceID;
650 };
651
652 std::vector<LLVector3> mProfile;
653 std::vector<LLVector2> mNormals;
654 std::vector<Face> mFaces;
655 std::vector<LLVector3> mEdgeNormals;
656 std::vector<LLVector3> mEdgeCenters;
657 F32 mMaxX;
658 F32 mMinX;
659
660 friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile);
661
662protected:
663 void genNormals();
664 void genNGon(S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
665
666 Face* addHole(BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0);
667 Face* addCap (S16 faceID);
668 Face* addFace(S32 index, S32 count, F32 scaleU, S16 faceID, BOOL flat);
669
670protected:
671 BOOL mOpen;
672 BOOL mConcave;
673 BOOL mDirty;
674
675 S32 mTotalOut;
676 S32 mTotal;
677};
678
679//-------------------------------------------------------------------
680// SWEEP/EXTRUDE PATHS
681//-------------------------------------------------------------------
682
683class LLPath
684{
685public:
686 struct PathPt
687 {
688 LLVector3 mPos;
689 LLVector2 mScale;
690 LLQuaternion mRot;
691 F32 mTexT;
692 PathPt() { mPos.setVec(0,0,0); mTexT = 0; mScale.setVec(0,0); mRot.loadIdentity(); }
693 };
694
695public:
696 LLPath(const LLPathParams &params) : mParams(params)
697 {
698 mOpen = FALSE;
699 mDirty = TRUE;
700 mStep = 1;
701 }
702
703 virtual ~LLPath();
704
705 void genNGon(S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
706 virtual BOOL generate(F32 detail=1.0f, S32 split = 0);
707
708 BOOL isOpen() const { return mOpen; }
709 F32 getStep() const { return mStep; }
710 void setDirty() { mDirty = TRUE; }
711
712 S32 getPathLength() const { return (S32)mPath.size(); }
713
714 void resizePath(S32 length) { mPath.resize(length); }
715
716 friend std::ostream& operator<<(std::ostream &s, const LLPath &path);
717
718public:
719 const LLPathParams &mParams;
720 std::vector<PathPt> mPath;
721
722protected:
723 BOOL mOpen;
724 S32 mTotal;
725 BOOL mDirty;
726 F32 mStep;
727};
728
729class LLDynamicPath : public LLPath
730{
731public:
732 LLDynamicPath(const LLPathParams &params) : LLPath(params) { }
733 BOOL generate(F32 detail=1.0f, S32 split = 0);
734};
735
736// Yet another "face" class - caches volume-specific, but not instance-specific data for faces)
737class LLVolumeFace
738{
739public:
740 LLVolumeFace();
741 BOOL create();
742
743 class VertexData
744 {
745 public:
746 LLVector3 mPosition;
747 LLVector3 mNormal;
748 LLVector3 mBinormal;
749 LLVector2 mTexCoord;
750 };
751
752 enum
753 {
754 SINGLE_MASK = 0x0001,
755 CAP_MASK = 0x0002,
756 END_MASK = 0x0004,
757 SIDE_MASK = 0x0008,
758 INNER_MASK = 0x0010,
759 OUTER_MASK = 0x0020,
760 HOLLOW_MASK = 0x0040,
761 OPEN_MASK = 0x0080,
762 FLAT_MASK = 0x0100,
763 TOP_MASK = 0x0200,
764 BOTTOM_MASK = 0x0400
765 } TypeMask;
766
767public:
768 S32 mID;
769 U32 mTypeMask;
770 LLVector3 mCenter;
771
772 // Only used for INNER/OUTER faces
773 S32 mBeginS;
774 S32 mBeginT;
775 S32 mNumS;
776 S32 mNumT;
777
778 std::vector<VertexData> mVertices;
779 std::vector<S32> mIndices;
780 std::vector<S32> mEdge;
781 LLVolume *mVolumep; // Deliberately NOT reference counted - djs 11/20/03 - otherwise would make an annoying circular reference
782
783 // Shouldn't need num_old and num_new, really - djs
784 static BOOL updateColors(LLColor4U *old_colors, const S32 num_old, const LLVolumeFace &old_face,
785 LLStrider<LLColor4U> &new_colors, const S32 num_new, const LLVolumeFace &new_face);
786
787protected:
788 BOOL createUnCutCubeCap();
789 BOOL createCap();
790 BOOL createSide();
791};
792
793class LLVolume : public LLRefCount
794{
795 friend class LLVolumeLODGroup;
796
797private:
798 LLVolume(const LLVolume&); // Don't implement
799 ~LLVolume(); // use unref
800
801public:
802 struct Point
803 {
804 LLVector3 mPos;
805 };
806
807 struct FaceParams
808 {
809 LLFaceID mFaceID;
810 S32 mBeginS;
811 S32 mCountS;
812 S32 mBeginT;
813 S32 mCountT;
814 };
815
816 LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL generate_single_face = FALSE, const BOOL is_unique = FALSE);
817
818 U8 getProfileType() const { return mProfilep->mParams.getCurveType(); }
819 U8 getPathType() const { return mPathp->mParams.getCurveType(); }
820 S32 getNumFaces() const { return (S32)mProfilep->mFaces.size(); }
821
822 const F32 getDetail() const { return mDetail; }
823 const LLVolumeParams & getParams() const { return mParams; }
824 LLVolumeParams getCopyOfParams() const { return mParams; }
825 const LLProfile& getProfile() const { return *mProfilep; }
826 LLPath& getPath() const { return *mPathp; }
827 const std::vector<Point>& getMesh() const { return mMesh; }
828 const LLVector3& getMeshPt(const U32 i) const { return mMesh[i].mPos; }
829
830 void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
831
832 void regen();
833
834 BOOL isConvex() const;
835 BOOL isCap(S32 face);
836 BOOL isFlat(S32 face);
837 BOOL isUnique() const { return mUnique; }
838
839 S32 *getTriangleIndices(U32 &num_indices) const;
840 void generateSilhouetteVertices(std::vector<LLVector3> &vertices, std::vector<LLVector3> &normals, std::vector<S32> &segments, const LLVector3& view_vec,
841 const LLMatrix4& mat,
842 const LLMatrix3& norm_mat);
843
844 //get the face index of the face that intersects with the given line segment at the point
845 //closest to start. Moves end to the point of intersection. Returns -1 if no intersection.
846 //Line segment must be in volume space.
847 S32 lineSegmentIntersect(const LLVector3& start, LLVector3& end) const;
848
849 // The following cleans up vertices and triangles,
850 // getting rid of degenerate triangles and duplicate vertices,
851 // and allocates new arrays with the clean data.
852 static BOOL cleanupTriangleData( const S32 num_input_vertices,
853 const std::vector<Point> &input_vertices,
854 const S32 num_input_triangles,
855 S32 *input_triangles,
856 S32 &num_output_vertices,
857 LLVector3 **output_vertices,
858 S32 &num_output_triangles,
859 S32 **output_triangles);
860 LLFaceID generateFaceMask();
861
862 BOOL isFaceMaskValid(LLFaceID face_mask);
863 static S32 mNumMeshPoints;
864
865 friend std::ostream& operator<<(std::ostream &s, const LLVolume &volume);
866 friend std::ostream& operator<<(std::ostream &s, const LLVolume *volumep); // HACK to bypass Windoze confusion over
867 // conversion if *(LLVolume*) to LLVolume&
868 const LLVolumeFace &getVolumeFace(const S32 f) const {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE
869
870 U32 mFaceMask; // bit array of which faces exist in this volume
871 LLVector3 mBounds[2]; // bounding box (center, half-height)
872 LLVector3 mLODScaleBias; // vector for biasing LOD based on scale
873
874protected:
875 BOOL generate();
876 void createVolumeFaces();
877
878protected:
879 BOOL mUnique;
880 F32 mDetail;
881 LLVolumeParams mParams;
882 LLPath *mPathp;
883 LLProfile *mProfilep;
884 std::vector<Point> mMesh;
885
886 BOOL mGenerateSingleFace;
887 S32 mNumVolumeFaces;
888 LLVolumeFace *mVolumeFaces;
889};
890
891std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
892
893LLVector3 calc_binormal_from_triangle(
894 const LLVector3& pos0,
895 const LLVector2& tex0,
896 const LLVector3& pos1,
897 const LLVector2& tex1,
898 const LLVector3& pos2,
899 const LLVector2& tex2);
900
901#endif