00001
00032 #ifndef LL_LLVOLUME_H
00033 #define LL_LLVOLUME_H
00034
00035 #include <iostream>
00036
00037 class LLProfileParams;
00038 class LLPathParams;
00039 class LLVolumeParams;
00040 class LLProfile;
00041 class LLPath;
00042 class LLVolumeFace;
00043 class LLVolume;
00044
00045 #include "lldarray.h"
00046 #include "lluuid.h"
00047 #include "v4color.h"
00048
00049 #include "v2math.h"
00050 #include "v3math.h"
00051 #include "llquaternion.h"
00052 #include "llstrider.h"
00053 #include "v4coloru.h"
00054 #include "llmemory.h"
00055
00056
00057
00058 const S32 MIN_DETAIL_FACES = 6;
00059 const S32 MIN_LOD = 0;
00060 const S32 MAX_LOD = 3;
00061
00062
00063
00064
00065 const F32 MIN_VOLUME_PROFILE_WIDTH = 0.05f;
00066 const F32 MIN_VOLUME_PATH_WIDTH = 0.05f;
00067
00068 const F32 CUT_QUANTA = 0.00002f;
00069 const F32 SCALE_QUANTA = 0.01f;
00070 const F32 SHEAR_QUANTA = 0.01f;
00071 const F32 TAPER_QUANTA = 0.01f;
00072 const F32 REV_QUANTA = 0.015f;
00073 const F32 HOLLOW_QUANTA = 0.00002f;
00074
00075
00076
00077
00078 const LLPCode LL_PCODE_HOLLOW_MASK = 0x80;
00079 const LLPCode LL_PCODE_SEGMENT_MASK = 0x40;
00080 const LLPCode LL_PCODE_PATCH_MASK = 0x20;
00081 const LLPCode LL_PCODE_HEMI_MASK = 0x10;
00082 const LLPCode LL_PCODE_BASE_MASK = 0x0F;
00083
00084
00085 const LLPCode LL_PCODE_CUBE = 1;
00086 const LLPCode LL_PCODE_PRISM = 2;
00087 const LLPCode LL_PCODE_TETRAHEDRON = 3;
00088 const LLPCode LL_PCODE_PYRAMID = 4;
00089 const LLPCode LL_PCODE_CYLINDER = 5;
00090 const LLPCode LL_PCODE_CONE = 6;
00091 const LLPCode LL_PCODE_SPHERE = 7;
00092 const LLPCode LL_PCODE_TORUS = 8;
00093 const LLPCode LL_PCODE_VOLUME = 9;
00094
00095
00096
00097
00098
00099
00100 const LLPCode LL_PCODE_APP = 14;
00101 const LLPCode LL_PCODE_LEGACY = 15;
00102
00103
00104
00105 const LLPCode LL_PCODE_LEGACY_AVATAR = 0x20 | LL_PCODE_LEGACY;
00106
00107
00108 const LLPCode LL_PCODE_LEGACY_GRASS = 0x50 | LL_PCODE_LEGACY;
00109 const LLPCode LL_PCODE_TREE_NEW = 0x60 | LL_PCODE_LEGACY;
00110
00111 const LLPCode LL_PCODE_LEGACY_PART_SYS = 0x80 | LL_PCODE_LEGACY;
00112 const LLPCode LL_PCODE_LEGACY_ROCK = 0x90 | LL_PCODE_LEGACY;
00113
00114
00115
00116
00117 const LLPCode LL_PCODE_LEGACY_TEXT_BUBBLE = 0xE0 | LL_PCODE_LEGACY;
00118 const LLPCode LL_PCODE_LEGACY_TREE = 0xF0 | LL_PCODE_LEGACY;
00119
00120
00121 const LLPCode LL_PCODE_CYLINDER_HEMI = LL_PCODE_CYLINDER | LL_PCODE_HEMI_MASK;
00122 const LLPCode LL_PCODE_CONE_HEMI = LL_PCODE_CONE | LL_PCODE_HEMI_MASK;
00123 const LLPCode LL_PCODE_SPHERE_HEMI = LL_PCODE_SPHERE | LL_PCODE_HEMI_MASK;
00124 const LLPCode LL_PCODE_TORUS_HEMI = LL_PCODE_TORUS | LL_PCODE_HEMI_MASK;
00125
00126
00127
00128
00129
00130 const U8 LL_PCODE_PROFILE_MASK = 0x0f;
00131 const U8 LL_PCODE_PROFILE_MIN = 0x00;
00132 const U8 LL_PCODE_PROFILE_CIRCLE = 0x00;
00133 const U8 LL_PCODE_PROFILE_SQUARE = 0x01;
00134 const U8 LL_PCODE_PROFILE_ISOTRI = 0x02;
00135 const U8 LL_PCODE_PROFILE_EQUALTRI = 0x03;
00136 const U8 LL_PCODE_PROFILE_RIGHTTRI = 0x04;
00137 const U8 LL_PCODE_PROFILE_CIRCLE_HALF = 0x05;
00138 const U8 LL_PCODE_PROFILE_MAX = 0x05;
00139
00140
00141 const U8 LL_PCODE_HOLE_MASK = 0xf0;
00142 const U8 LL_PCODE_HOLE_MIN = 0x00;
00143 const U8 LL_PCODE_HOLE_SAME = 0x00;
00144 const U8 LL_PCODE_HOLE_CIRCLE = 0x10;
00145 const U8 LL_PCODE_HOLE_SQUARE = 0x20;
00146 const U8 LL_PCODE_HOLE_TRIANGLE = 0x30;
00147 const U8 LL_PCODE_HOLE_MAX = 0x03;
00148
00149 const U8 LL_PCODE_PATH_IGNORE = 0x00;
00150 const U8 LL_PCODE_PATH_MIN = 0x01;
00151 const U8 LL_PCODE_PATH_LINE = 0x10;
00152 const U8 LL_PCODE_PATH_CIRCLE = 0x20;
00153 const U8 LL_PCODE_PATH_CIRCLE2 = 0x30;
00154 const U8 LL_PCODE_PATH_TEST = 0x40;
00155 const U8 LL_PCODE_PATH_FLEXIBLE = 0x80;
00156 const U8 LL_PCODE_PATH_MAX = 0x08;
00157
00158
00159
00160
00161 typedef U16 LLFaceID;
00162
00163 const LLFaceID LL_FACE_PATH_BEGIN = 0x1 << 0;
00164 const LLFaceID LL_FACE_PATH_END = 0x1 << 1;
00165 const LLFaceID LL_FACE_INNER_SIDE = 0x1 << 2;
00166 const LLFaceID LL_FACE_PROFILE_BEGIN = 0x1 << 3;
00167 const LLFaceID LL_FACE_PROFILE_END = 0x1 << 4;
00168 const LLFaceID LL_FACE_OUTER_SIDE_0 = 0x1 << 5;
00169 const LLFaceID LL_FACE_OUTER_SIDE_1 = 0x1 << 6;
00170 const LLFaceID LL_FACE_OUTER_SIDE_2 = 0x1 << 7;
00171 const LLFaceID LL_FACE_OUTER_SIDE_3 = 0x1 << 8;
00172
00173
00174
00175
00176
00177 const U8 LL_SCULPT_TYPE_NONE = 0;
00178 const U8 LL_SCULPT_TYPE_SPHERE = 1;
00179 const U8 LL_SCULPT_TYPE_TORUS = 2;
00180 const U8 LL_SCULPT_TYPE_PLANE = 3;
00181 const U8 LL_SCULPT_TYPE_CYLINDER = 4;
00182
00183
00184
00185 class LLProfileParams
00186 {
00187 public:
00188 LLProfileParams()
00189 {
00190 mBegin = 0;
00191 mEnd = 1;
00192 mHollow = 0;
00193 mCurveType = LL_PCODE_PROFILE_SQUARE;
00194 }
00195
00196 LLProfileParams(U8 curve, F32 begin, F32 end, F32 hollow)
00197 : mCurveType(curve), mBegin(begin), mEnd(end), mHollow(hollow)
00198 {
00199 }
00200
00201 LLProfileParams(U8 curve, U16 begin, U16 end, U16 hollow)
00202 {
00203 mCurveType = curve;
00204 F32 temp_f32 = begin * CUT_QUANTA;
00205 if (temp_f32 > 1.f)
00206 {
00207 temp_f32 = 1.f;
00208 }
00209 mBegin = temp_f32;
00210 temp_f32 = end * CUT_QUANTA;
00211 if (temp_f32 > 1.f)
00212 {
00213 temp_f32 = 1.f;
00214 }
00215 mEnd = 1.f - temp_f32;
00216 temp_f32 = hollow * HOLLOW_QUANTA;
00217 if (temp_f32 > 1.f)
00218 {
00219 temp_f32 = 1.f;
00220 }
00221 mHollow = temp_f32;
00222 }
00223
00224 bool operator==(const LLProfileParams ¶ms) const;
00225 bool operator!=(const LLProfileParams ¶ms) const;
00226 bool operator<(const LLProfileParams ¶ms) const;
00227
00228 void copyParams(const LLProfileParams ¶ms);
00229
00230 BOOL importFile(FILE *fp);
00231 BOOL exportFile(FILE *fp) const;
00232
00233 BOOL importLegacyStream(std::istream& input_stream);
00234 BOOL exportLegacyStream(std::ostream& output_stream) const;
00235
00236 LLSD asLLSD() const;
00237 operator LLSD() const { return asLLSD(); }
00238 bool fromLLSD(LLSD& sd);
00239
00240 const F32& getBegin () const { return mBegin; }
00241 const F32& getEnd () const { return mEnd; }
00242 const F32& getHollow() const { return mHollow; }
00243 const U8& getCurveType () const { return mCurveType; }
00244
00245 void setCurveType(const U32 type) { mCurveType = type;}
00246 void setBegin(const F32 begin) { mBegin = (begin >= 1.0f) ? 0.0f : ((int) (begin * 100000))/100000.0f;}
00247 void setEnd(const F32 end) { mEnd = (end <= 0.0f) ? 1.0f : ((int) (end * 100000))/100000.0f;}
00248 void setHollow(const F32 hollow) { mHollow = ((int) (hollow * 100000))/100000.0f;}
00249
00250 friend std::ostream& operator<<(std::ostream &s, const LLProfileParams &profile_params);
00251
00252 protected:
00253
00254 U8 mCurveType;
00255 F32 mBegin;
00256 F32 mEnd;
00257 F32 mHollow;
00258
00259 U32 mCRC;
00260 };
00261
00262 inline bool LLProfileParams::operator==(const LLProfileParams ¶ms) const
00263 {
00264 return
00265 (getCurveType() == params.getCurveType()) &&
00266 (getBegin() == params.getBegin()) &&
00267 (getEnd() == params.getEnd()) &&
00268 (getHollow() == params.getHollow());
00269 }
00270
00271 inline bool LLProfileParams::operator!=(const LLProfileParams ¶ms) const
00272 {
00273 return
00274 (getCurveType() != params.getCurveType()) ||
00275 (getBegin() != params.getBegin()) ||
00276 (getEnd() != params.getEnd()) ||
00277 (getHollow() != params.getHollow());
00278 }
00279
00280
00281 inline bool LLProfileParams::operator<(const LLProfileParams ¶ms) const
00282 {
00283 if (getCurveType() != params.getCurveType())
00284 {
00285 return getCurveType() < params.getCurveType();
00286 }
00287 else
00288 if (getBegin() != params.getBegin())
00289 {
00290 return getBegin() < params.getBegin();
00291 }
00292 else
00293 if (getEnd() != params.getEnd())
00294 {
00295 return getEnd() < params.getEnd();
00296 }
00297 else
00298 {
00299 return getHollow() < params.getHollow();
00300 }
00301 }
00302
00303 #define U8_TO_F32(x) (F32)(*((S8 *)&x))
00304
00305 class LLPathParams
00306 {
00307 public:
00308 LLPathParams()
00309 {
00310 mBegin = 0;
00311 mEnd = 1;
00312 mScale.setVec(1,1);
00313 mShear.setVec(0,0);
00314 mCurveType = LL_PCODE_PATH_LINE;
00315 mTwistBegin = 0;
00316 mTwistEnd = 0;
00317 mRadiusOffset = 0;
00318 mTaper.setVec(0,0);
00319 mRevolutions = 1;
00320 mSkew = 0;
00321 }
00322
00323 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)
00324 : mCurveType(curve), mBegin(begin), mEnd(end), mTwistBegin(twistbegin), mTwistEnd(twistend),
00325 mRadiusOffset(radiusoffset), mRevolutions(revolutions), mSkew(skew)
00326 {
00327 mScale.setVec(scx,scy);
00328 mShear.setVec(shx,shy);
00329 mTaper.setVec(tx,ty);
00330 }
00331
00332 LLPathParams(U8 curve, U16 begin, U16 end, U8 scx, U8 scy, U8 shx, U8 shy, U8 twistend, U8 twistbegin, U8 radiusoffset, U8 tx, U8 ty, U8 revolutions, U8 skew)
00333 {
00334 mCurveType = curve;
00335 mBegin = (F32)(begin * CUT_QUANTA);
00336 mEnd = (F32)(100.f - end) * CUT_QUANTA;
00337 if (mEnd > 1.f)
00338 mEnd = 1.f;
00339 mScale.setVec((F32) (200 - scx) * SCALE_QUANTA,(F32) (200 - scy) * SCALE_QUANTA);
00340 mShear.setVec(U8_TO_F32(shx) * SHEAR_QUANTA,U8_TO_F32(shy) * SHEAR_QUANTA);
00341 mTwistBegin = U8_TO_F32(twistbegin) * SCALE_QUANTA;
00342 mTwistEnd = U8_TO_F32(twistend) * SCALE_QUANTA;
00343 mRadiusOffset = U8_TO_F32(radiusoffset) * SCALE_QUANTA;
00344 mTaper.setVec(U8_TO_F32(tx) * TAPER_QUANTA,U8_TO_F32(ty) * TAPER_QUANTA);
00345 mRevolutions = ((F32)revolutions) * REV_QUANTA + 1.0f;
00346 mSkew = U8_TO_F32(skew) * SCALE_QUANTA;
00347 }
00348
00349 bool operator==(const LLPathParams ¶ms) const;
00350 bool operator!=(const LLPathParams ¶ms) const;
00351 bool operator<(const LLPathParams ¶ms) const;
00352
00353 void copyParams(const LLPathParams ¶ms);
00354
00355 BOOL importFile(FILE *fp);
00356 BOOL exportFile(FILE *fp) const;
00357
00358 BOOL importLegacyStream(std::istream& input_stream);
00359 BOOL exportLegacyStream(std::ostream& output_stream) const;
00360
00361 LLSD asLLSD() const;
00362 operator LLSD() const { return asLLSD(); }
00363 bool fromLLSD(LLSD& sd);
00364
00365 const F32& getBegin() const { return mBegin; }
00366 const F32& getEnd() const { return mEnd; }
00367 const LLVector2 &getScale() const { return mScale; }
00368 const F32& getScaleX() const { return mScale.mV[0]; }
00369 const F32& getScaleY() const { return mScale.mV[1]; }
00370 const LLVector2 getBeginScale() const;
00371 const LLVector2 getEndScale() const;
00372 const LLVector2 &getShear() const { return mShear; }
00373 const F32& getShearX() const { return mShear.mV[0]; }
00374 const F32& getShearY() const { return mShear.mV[1]; }
00375 const U8& getCurveType () const { return mCurveType; }
00376
00377 const F32& getTwistBegin() const { return mTwistBegin; }
00378 const F32& getTwistEnd() const { return mTwistEnd; }
00379 const F32& getTwist() const { return mTwistEnd; }
00380 const F32& getRadiusOffset() const { return mRadiusOffset; }
00381 const LLVector2 &getTaper() const { return mTaper; }
00382 const F32& getTaperX() const { return mTaper.mV[0]; }
00383 const F32& getTaperY() const { return mTaper.mV[1]; }
00384 const F32& getRevolutions() const { return mRevolutions; }
00385 const F32& getSkew() const { return mSkew; }
00386
00387 void setCurveType(const U8 type) { mCurveType = type; }
00388 void setBegin(const F32 begin) { mBegin = begin; }
00389 void setEnd(const F32 end) { mEnd = end; }
00390
00391 void setScale(const F32 x, const F32 y) { mScale.setVec(x,y); }
00392 void setScaleX(const F32 v) { mScale.mV[VX] = v; }
00393 void setScaleY(const F32 v) { mScale.mV[VY] = v; }
00394 void setShear(const F32 x, const F32 y) { mShear.setVec(x,y); }
00395 void setShearX(const F32 v) { mShear.mV[VX] = v; }
00396 void setShearY(const F32 v) { mShear.mV[VY] = v; }
00397
00398 void setTwistBegin(const F32 twist_begin) { mTwistBegin = twist_begin; }
00399 void setTwistEnd(const F32 twist_end) { mTwistEnd = twist_end; }
00400 void setTwist(const F32 twist) { setTwistEnd(twist); }
00401 void setRadiusOffset(const F32 radius_offset){ mRadiusOffset = radius_offset; }
00402 void setTaper(const F32 x, const F32 y) { mTaper.setVec(x,y); }
00403 void setTaperX(const F32 v) { mTaper.mV[VX] = v; }
00404 void setTaperY(const F32 v) { mTaper.mV[VY] = v; }
00405 void setRevolutions(const F32 revolutions) { mRevolutions = revolutions; }
00406 void setSkew(const F32 skew) { mSkew = skew; }
00407
00408 friend std::ostream& operator<<(std::ostream &s, const LLPathParams &path_params);
00409
00410 protected:
00411
00412 U8 mCurveType;
00413 F32 mBegin;
00414 F32 mEnd;
00415 LLVector2 mScale;
00416 LLVector2 mShear;
00417
00418 F32 mTwistBegin;
00419 F32 mTwistEnd;
00420 F32 mRadiusOffset;
00421 LLVector2 mTaper;
00422 F32 mRevolutions;
00423 F32 mSkew;
00424
00425 U32 mCRC;
00426 };
00427
00428 inline bool LLPathParams::operator==(const LLPathParams ¶ms) const
00429 {
00430 return
00431 (getCurveType() == params.getCurveType()) &&
00432 (getScale() == params.getScale()) &&
00433 (getBegin() == params.getBegin()) &&
00434 (getEnd() == params.getEnd()) &&
00435 (getShear() == params.getShear()) &&
00436 (getTwist() == params.getTwist()) &&
00437 (getTwistBegin() == params.getTwistBegin()) &&
00438 (getRadiusOffset() == params.getRadiusOffset()) &&
00439 (getTaper() == params.getTaper()) &&
00440 (getRevolutions() == params.getRevolutions()) &&
00441 (getSkew() == params.getSkew());
00442 }
00443
00444 inline bool LLPathParams::operator!=(const LLPathParams ¶ms) const
00445 {
00446 return
00447 (getCurveType() != params.getCurveType()) ||
00448 (getScale() != params.getScale()) ||
00449 (getBegin() != params.getBegin()) ||
00450 (getEnd() != params.getEnd()) ||
00451 (getShear() != params.getShear()) ||
00452 (getTwist() != params.getTwist()) ||
00453 (getTwistBegin() !=params.getTwistBegin()) ||
00454 (getRadiusOffset() != params.getRadiusOffset()) ||
00455 (getTaper() != params.getTaper()) ||
00456 (getRevolutions() != params.getRevolutions()) ||
00457 (getSkew() != params.getSkew());
00458 }
00459
00460
00461 inline bool LLPathParams::operator<(const LLPathParams ¶ms) const
00462 {
00463 if( getCurveType() != params.getCurveType())
00464 {
00465 return getCurveType() < params.getCurveType();
00466 }
00467 else
00468 if( getScale() != params.getScale())
00469 {
00470 return getScale() < params.getScale();
00471 }
00472 else
00473 if( getBegin() != params.getBegin())
00474 {
00475 return getBegin() < params.getBegin();
00476 }
00477 else
00478 if( getEnd() != params.getEnd())
00479 {
00480 return getEnd() < params.getEnd();
00481 }
00482 else
00483 if( getShear() != params.getShear())
00484 {
00485 return getShear() < params.getShear();
00486 }
00487 else
00488 if( getTwist() != params.getTwist())
00489 {
00490 return getTwist() < params.getTwist();
00491 }
00492 else
00493 if( getTwistBegin() != params.getTwistBegin())
00494 {
00495 return getTwistBegin() < params.getTwistBegin();
00496 }
00497 else
00498 if( getRadiusOffset() != params.getRadiusOffset())
00499 {
00500 return getRadiusOffset() < params.getRadiusOffset();
00501 }
00502 else
00503 if( getTaper() != params.getTaper())
00504 {
00505 return getTaper() < params.getTaper();
00506 }
00507 else
00508 if( getRevolutions() != params.getRevolutions())
00509 {
00510 return getRevolutions() < params.getRevolutions();
00511 }
00512 else
00513 {
00514 return getSkew() < params.getSkew();
00515 }
00516 }
00517
00518 typedef LLVolumeParams* LLVolumeParamsPtr;
00519 typedef const LLVolumeParams* const_LLVolumeParamsPtr;
00520
00521 class LLVolumeParams
00522 {
00523 public:
00524 LLVolumeParams()
00525 {
00526 }
00527
00528 LLVolumeParams(LLProfileParams &profile, LLPathParams &path,
00529 LLUUID sculpt_id = LLUUID::null, U8 sculpt_type = LL_SCULPT_TYPE_NONE)
00530 : mProfileParams(profile), mPathParams(path), mSculptID(sculpt_id), mSculptType(sculpt_type)
00531 {
00532 }
00533
00534 bool operator==(const LLVolumeParams ¶ms) const;
00535 bool operator!=(const LLVolumeParams ¶ms) const;
00536 bool operator<(const LLVolumeParams ¶ms) const;
00537
00538
00539 void copyParams(const LLVolumeParams ¶ms);
00540
00541 const LLProfileParams &getProfileParams() const {return mProfileParams;}
00542 LLProfileParams &getProfileParams() {return mProfileParams;}
00543 const LLPathParams &getPathParams() const {return mPathParams;}
00544 LLPathParams &getPathParams() {return mPathParams;}
00545
00546 BOOL importFile(FILE *fp);
00547 BOOL exportFile(FILE *fp) const;
00548
00549 BOOL importLegacyStream(std::istream& input_stream);
00550 BOOL exportLegacyStream(std::ostream& output_stream) const;
00551
00552 LLSD asLLSD() const;
00553 operator LLSD() const { return asLLSD(); }
00554 bool fromLLSD(LLSD& sd);
00555
00556 bool setType(U8 profile, U8 path);
00557
00558
00559
00560
00561
00562
00563 bool setBeginAndEndS(const F32 begin, const F32 end);
00564 bool setBeginAndEndT(const F32 begin, const F32 end);
00565
00566 bool setHollow(const F32 hollow);
00567 bool setRatio(const F32 x) { return setRatio(x,x); }
00568 bool setShear(const F32 x) { return setShear(x,x); }
00569 bool setRatio(const F32 x, const F32 y);
00570 bool setShear(const F32 x, const F32 y);
00571
00572 bool setTwistBegin(const F32 twist_begin);
00573 bool setTwistEnd(const F32 twist_end);
00574 bool setTwist(const F32 twist) { return setTwistEnd(twist); }
00575 bool setTaper(const F32 x, const F32 y) { bool pass_x = setTaperX(x); bool pass_y = setTaperY(y); return pass_x && pass_y; }
00576 bool setTaperX(const F32 v);
00577 bool setTaperY(const F32 v);
00578 bool setRevolutions(const F32 revolutions);
00579 bool setRadiusOffset(const F32 radius_offset);
00580 bool setSkew(const F32 skew);
00581 bool setSculptID(const LLUUID sculpt_id, U8 sculpt_type);
00582
00583 static bool validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 hollow,
00584 U8 path_curve, F32 path_begin, F32 path_end,
00585 F32 scx, F32 scy, F32 shx, F32 shy,
00586 F32 twistend, F32 twistbegin, F32 radiusoffset,
00587 F32 tx, F32 ty, F32 revolutions, F32 skew);
00588
00589 const F32& getBeginS() const { return mProfileParams.getBegin(); }
00590 const F32& getBeginT() const { return mPathParams.getBegin(); }
00591 const F32& getEndS() const { return mProfileParams.getEnd(); }
00592 const F32& getEndT() const { return mPathParams.getEnd(); }
00593
00594 const F32& getHollow() const { return mProfileParams.getHollow(); }
00595 const F32& getTwist() const { return mPathParams.getTwist(); }
00596 const F32& getRatio() const { return mPathParams.getScaleX(); }
00597 const F32& getRatioX() const { return mPathParams.getScaleX(); }
00598 const F32& getRatioY() const { return mPathParams.getScaleY(); }
00599 const F32& getShearX() const { return mPathParams.getShearX(); }
00600 const F32& getShearY() const { return mPathParams.getShearY(); }
00601
00602 const F32& getTwistBegin()const { return mPathParams.getTwistBegin(); }
00603 const F32& getRadiusOffset() const { return mPathParams.getRadiusOffset(); }
00604 const F32& getTaper() const { return mPathParams.getTaperX(); }
00605 const F32& getTaperX() const { return mPathParams.getTaperX(); }
00606 const F32& getTaperY() const { return mPathParams.getTaperY(); }
00607 const F32& getRevolutions() const { return mPathParams.getRevolutions(); }
00608 const F32& getSkew() const { return mPathParams.getSkew(); }
00609 const LLUUID& getSculptID() const { return mSculptID; }
00610 const U8& getSculptType() const { return mSculptType; }
00611
00612 BOOL isConvex() const;
00613
00614
00615
00616
00617 void reduceS(F32 begin, F32 end);
00618 void reduceT(F32 begin, F32 end);
00619
00620 struct compare
00621 {
00622 bool operator()( const const_LLVolumeParamsPtr& first, const const_LLVolumeParamsPtr& second) const
00623 {
00624 return (*first < *second);
00625 }
00626 };
00627
00628 friend std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
00629
00630 protected:
00631 LLProfileParams mProfileParams;
00632 LLPathParams mPathParams;
00633 LLUUID mSculptID;
00634 U8 mSculptType;
00635 };
00636
00637
00638 class LLProfile
00639 {
00640 public:
00641 LLProfile(const LLProfileParams ¶ms)
00642 : mParams(params),
00643 mOpen(FALSE),
00644 mConcave(FALSE),
00645 mDirty(TRUE),
00646 mTotalOut(0),
00647 mTotal(2)
00648 {
00649 }
00650
00651 ~LLProfile();
00652
00653 S32 getTotal() const { return mTotal; }
00654 S32 getTotalOut() const { return mTotalOut; }
00655 BOOL isHollow() const { return (mParams.getHollow() > 0); }
00656 BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); }
00657 BOOL isOpen() const { return mOpen; }
00658 void setDirty() { mDirty = TRUE; }
00659 BOOL generate(BOOL path_open, F32 detail = 1.0f, S32 split = 0, BOOL is_sculpted = FALSE);
00660 BOOL isConcave() const { return mConcave; }
00661 public:
00662 const LLProfileParams &mParams;
00663
00664 struct Face
00665 {
00666 S32 mIndex;
00667 S32 mCount;
00668 F32 mScaleU;
00669 BOOL mCap;
00670 BOOL mFlat;
00671 LLFaceID mFaceID;
00672 };
00673
00674 std::vector<LLVector3> mProfile;
00675 std::vector<LLVector2> mNormals;
00676 std::vector<Face> mFaces;
00677 std::vector<LLVector3> mEdgeNormals;
00678 std::vector<LLVector3> mEdgeCenters;
00679 F32 mMaxX;
00680 F32 mMinX;
00681
00682 friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile);
00683
00684 protected:
00685 void genNormals();
00686 void genNGon(S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
00687
00688 Face* addHole(BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0);
00689 Face* addCap (S16 faceID);
00690 Face* addFace(S32 index, S32 count, F32 scaleU, S16 faceID, BOOL flat);
00691
00692 protected:
00693 BOOL mOpen;
00694 BOOL mConcave;
00695 BOOL mDirty;
00696
00697 S32 mTotalOut;
00698 S32 mTotal;
00699 };
00700
00701
00702
00703
00704
00705 class LLPath
00706 {
00707 public:
00708 struct PathPt
00709 {
00710 LLVector3 mPos;
00711 LLVector2 mScale;
00712 LLQuaternion mRot;
00713 F32 mTexT;
00714 PathPt() { mPos.setVec(0,0,0); mTexT = 0; mScale.setVec(0,0); mRot.loadIdentity(); }
00715 };
00716
00717 public:
00718 LLPath(const LLPathParams ¶ms)
00719 : mParams(params),
00720 mOpen(FALSE),
00721 mTotal(0),
00722 mDirty(TRUE),
00723 mStep(1)
00724 {
00725 }
00726
00727 virtual ~LLPath();
00728
00729 void genNGon(S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
00730 virtual BOOL generate(F32 detail=1.0f, S32 split = 0, BOOL is_sculpted = FALSE);
00731
00732 BOOL isOpen() const { return mOpen; }
00733 F32 getStep() const { return mStep; }
00734 void setDirty() { mDirty = TRUE; }
00735
00736 S32 getPathLength() const { return (S32)mPath.size(); }
00737
00738 void resizePath(S32 length) { mPath.resize(length); }
00739
00740 friend std::ostream& operator<<(std::ostream &s, const LLPath &path);
00741
00742 public:
00743 const LLPathParams &mParams;
00744 std::vector<PathPt> mPath;
00745
00746 protected:
00747 BOOL mOpen;
00748 S32 mTotal;
00749 BOOL mDirty;
00750 F32 mStep;
00751 };
00752
00753 class LLDynamicPath : public LLPath
00754 {
00755 public:
00756 LLDynamicPath(const LLPathParams ¶ms) : LLPath(params) { }
00757 BOOL generate(F32 detail=1.0f, S32 split = 0, BOOL is_sculpted = FALSE);
00758 };
00759
00760
00761 class LLVolumeFace
00762 {
00763 public:
00764 LLVolumeFace();
00765 BOOL create();
00766
00767 class VertexData
00768 {
00769 public:
00770 LLVector3 mPosition;
00771 LLVector3 mNormal;
00772 LLVector3 mBinormal;
00773 LLVector2 mTexCoord;
00774 };
00775
00776 enum
00777 {
00778 SINGLE_MASK = 0x0001,
00779 CAP_MASK = 0x0002,
00780 END_MASK = 0x0004,
00781 SIDE_MASK = 0x0008,
00782 INNER_MASK = 0x0010,
00783 OUTER_MASK = 0x0020,
00784 HOLLOW_MASK = 0x0040,
00785 OPEN_MASK = 0x0080,
00786 FLAT_MASK = 0x0100,
00787 TOP_MASK = 0x0200,
00788 BOTTOM_MASK = 0x0400
00789 };
00790
00791 public:
00792 S32 mID;
00793 U32 mTypeMask;
00794 LLVector3 mCenter;
00795
00796
00797 S32 mBeginS;
00798 S32 mBeginT;
00799 S32 mNumS;
00800 S32 mNumT;
00801
00802 LLVector3 mExtents[2];
00803
00804 std::vector<VertexData> mVertices;
00805 std::vector<S32> mIndices;
00806 std::vector<S32> mEdge;
00807 LLVolume *mVolumep;
00808
00809
00810 static BOOL updateColors(LLColor4U *old_colors, const S32 num_old, const LLVolumeFace &old_face,
00811 LLStrider<LLColor4U> &new_colors, const S32 num_new, const LLVolumeFace &new_face);
00812
00813 protected:
00814 BOOL createUnCutCubeCap();
00815 BOOL createCap();
00816 BOOL createSide();
00817 };
00818
00819 class LLVolume : public LLRefCount
00820 {
00821 friend class LLVolumeLODGroup;
00822
00823 private:
00824 LLVolume(const LLVolume&);
00825 ~LLVolume();
00826
00827 public:
00828 struct Point
00829 {
00830 LLVector3 mPos;
00831 };
00832
00833 struct FaceParams
00834 {
00835 LLFaceID mFaceID;
00836 S32 mBeginS;
00837 S32 mCountS;
00838 S32 mBeginT;
00839 S32 mCountT;
00840 };
00841
00842 LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL generate_single_face = FALSE, const BOOL is_unique = FALSE);
00843
00844 U8 getProfileType() const { return mProfilep->mParams.getCurveType(); }
00845 U8 getPathType() const { return mPathp->mParams.getCurveType(); }
00846 S32 getNumFaces() const { return (S32)mProfilep->mFaces.size(); }
00847 S32 getNumVolumeFaces() const { return mNumVolumeFaces; }
00848 F32 getDetail() const { return mDetail; }
00849 const LLVolumeParams & getParams() const { return mParams; }
00850 LLVolumeParams getCopyOfParams() const { return mParams; }
00851 const LLProfile& getProfile() const { return *mProfilep; }
00852 LLPath& getPath() const { return *mPathp; }
00853 const std::vector<Point>& getMesh() const { return mMesh; }
00854 const LLVector3& getMeshPt(const U32 i) const { return mMesh[i].mPos; }
00855
00856 void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
00857
00858 void regen();
00859
00860 BOOL isConvex() const;
00861 BOOL isCap(S32 face);
00862 BOOL isFlat(S32 face);
00863 BOOL isUnique() const { return mUnique; }
00864
00865 S32 getSculptLevel() const { return mSculptLevel; }
00866
00867 S32 *getTriangleIndices(U32 &num_indices) const;
00868 void generateSilhouetteVertices(std::vector<LLVector3> &vertices, std::vector<LLVector3> &normals, std::vector<S32> &segments, const LLVector3& view_vec,
00869 const LLMatrix4& mat,
00870 const LLMatrix3& norm_mat);
00871
00872
00873
00874
00875 S32 lineSegmentIntersect(const LLVector3& start, LLVector3& end) const;
00876
00877
00878
00879
00880 static BOOL cleanupTriangleData( const S32 num_input_vertices,
00881 const std::vector<Point> &input_vertices,
00882 const S32 num_input_triangles,
00883 S32 *input_triangles,
00884 S32 &num_output_vertices,
00885 LLVector3 **output_vertices,
00886 S32 &num_output_triangles,
00887 S32 **output_triangles);
00888 LLFaceID generateFaceMask();
00889
00890 BOOL isFaceMaskValid(LLFaceID face_mask);
00891 static S32 sNumMeshPoints;
00892
00893 friend std::ostream& operator<<(std::ostream &s, const LLVolume &volume);
00894 friend std::ostream& operator<<(std::ostream &s, const LLVolume *volumep);
00895
00896 const LLVolumeFace &getVolumeFace(const S32 f) const {return mVolumeFaces[f];}
00897
00898 U32 mFaceMask;
00899 LLVector3 mLODScaleBias;
00900
00901 void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level);
00902
00903 protected:
00904 BOOL generate();
00905 void createVolumeFaces();
00906
00907 protected:
00908 BOOL mUnique;
00909 F32 mDetail;
00910 S32 mSculptLevel;
00911
00912 LLVolumeParams mParams;
00913 LLPath *mPathp;
00914 LLProfile *mProfilep;
00915 std::vector<Point> mMesh;
00916
00917 BOOL mGenerateSingleFace;
00918 S32 mNumVolumeFaces;
00919 LLVolumeFace *mVolumeFaces;
00920 };
00921
00922 std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
00923
00924 LLVector3 calc_binormal_from_triangle(
00925 const LLVector3& pos0,
00926 const LLVector2& tex0,
00927 const LLVector3& pos1,
00928 const LLVector2& tex1,
00929 const LLVector3& pos2,
00930 const LLVector2& tex2);
00931
00932 #endif