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