llvolume.h

Go to the documentation of this file.
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 //#include "vmath.h"
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 // These are defined here but are not enforced at this level,
00063 // rather they are here for the convenience of code that uses
00064 // the LLVolume class.
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 // useful masks
00078 const LLPCode LL_PCODE_HOLLOW_MASK      = 0x80;         // has a thickness
00079 const LLPCode LL_PCODE_SEGMENT_MASK = 0x40;             // segments (1 angle)
00080 const LLPCode LL_PCODE_PATCH_MASK       = 0x20;         // segmented segments (2 angles)
00081 const LLPCode LL_PCODE_HEMI_MASK        = 0x10;         // half-primitives get their own type per PR's dictum
00082 const LLPCode LL_PCODE_BASE_MASK        = 0x0F;
00083 
00084         // primitive shapes
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         // surfaces
00096 //const LLPCode LL_PCODE_SURFACE_TRIANGLE       = 10;
00097 //const LLPCode LL_PCODE_SURFACE_SQUARE         = 11;
00098 //const LLPCode LL_PCODE_SURFACE_DISC           = 12;
00099 
00100 const LLPCode   LL_PCODE_APP                            = 14; // App specific pcode (for viewer/sim side only objects)
00101 const LLPCode   LL_PCODE_LEGACY                         = 15;
00102 
00103 // Pcodes for legacy objects
00104 //const LLPCode LL_PCODE_LEGACY_ATOR =                          0x10 | LL_PCODE_LEGACY; // ATOR
00105 const LLPCode   LL_PCODE_LEGACY_AVATAR =                        0x20 | LL_PCODE_LEGACY; // PLAYER
00106 //const LLPCode LL_PCODE_LEGACY_BIRD =                          0x30 | LL_PCODE_LEGACY; // BIRD
00107 //const LLPCode LL_PCODE_LEGACY_DEMON =                         0x40 | LL_PCODE_LEGACY; // DEMON
00108 const LLPCode   LL_PCODE_LEGACY_GRASS =                         0x50 | LL_PCODE_LEGACY; // GRASS
00109 const LLPCode   LL_PCODE_TREE_NEW =                                     0x60 | LL_PCODE_LEGACY; // new trees
00110 //const LLPCode LL_PCODE_LEGACY_ORACLE =                        0x70 | LL_PCODE_LEGACY; // ORACLE
00111 const LLPCode   LL_PCODE_LEGACY_PART_SYS =                      0x80 | LL_PCODE_LEGACY; // PART_SYS
00112 const LLPCode   LL_PCODE_LEGACY_ROCK =                          0x90 | LL_PCODE_LEGACY; // ROCK
00113 //const LLPCode LL_PCODE_LEGACY_SHOT =                          0xA0 | LL_PCODE_LEGACY; // BASIC_SHOT
00114 //const LLPCode LL_PCODE_LEGACY_SHOT_BIG =                      0xB0 | LL_PCODE_LEGACY;
00115 //const LLPCode LL_PCODE_LEGACY_SMOKE =                         0xC0 | LL_PCODE_LEGACY; // SMOKE
00116 //const LLPCode LL_PCODE_LEGACY_SPARK =                         0xD0 | LL_PCODE_LEGACY;// SPARK
00117 const LLPCode   LL_PCODE_LEGACY_TEXT_BUBBLE =           0xE0 | LL_PCODE_LEGACY; // TEXTBUBBLE
00118 const LLPCode   LL_PCODE_LEGACY_TREE =                          0xF0 | LL_PCODE_LEGACY; // TREE
00119 
00120         // hemis
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 // Volumes consist of a profile at the base that is swept around
00128 // a path to make a volume.
00129 // The profile code
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 // Stored in the profile byte
00141 const U8        LL_PCODE_HOLE_MASK              = 0xf0;
00142 const U8        LL_PCODE_HOLE_MIN               = 0x00;   
00143 const U8        LL_PCODE_HOLE_SAME              = 0x00;         // same as outside profile
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;         // min/max needs to be >> 4 of real min/max
00148 
00149 const U8    LL_PCODE_PATH_IGNORE    = 0x00;
00150 const U8        LL_PCODE_PATH_MIN               = 0x01;         // min/max needs to be >> 4 of real min/max
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 // face identifiers
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 // sculpt types
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 &params) const;
00225         bool operator!=(const LLProfileParams &params) const;
00226         bool operator<(const LLProfileParams &params) const;
00227         
00228         void copyParams(const LLProfileParams &params);
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         // Profile params
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 &params) 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 &params) 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 &params) 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 &params) const;
00350         bool operator!=(const LLPathParams &params) const;
00351         bool operator<(const LLPathParams &params) const;
00352 
00353         void copyParams(const LLPathParams &params);
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; }   // deprecated
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); } // deprecated
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         // Path params
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 &params) 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 &params) 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 &params) 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 &params) const;
00535         bool operator!=(const LLVolumeParams &params) const;
00536         bool operator<(const LLVolumeParams &params) const;
00537 
00538 
00539         void copyParams(const LLVolumeParams &params);
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         //void setBeginS(const F32 beginS)                      { mProfileParams.setBegin(beginS); }    // range 0 to 1
00559         //void setBeginT(const F32 beginT)                      { mPathParams.setBegin(beginT); }               // range 0 to 1
00560         //void setEndS(const F32 endS)                          { mProfileParams.setEnd(endS); }                // range 0 to 1, must be greater than begin
00561         //void setEndT(const F32 endT)                          { mPathParams.setEnd(endT); }                   // range 0 to 1, must be greater than begin
00562 
00563         bool setBeginAndEndS(const F32 begin, const F32 end);                   // both range from 0 to 1, begin must be less than end
00564         bool setBeginAndEndT(const F32 begin, const F32 end);                   // both range from 0 to 1, begin must be less than end
00565 
00566         bool setHollow(const F32 hollow);       // range 0 to 1
00567         bool setRatio(const F32 x)                                      { return setRatio(x,x); }                       // 0 = point, 1 = same as base
00568         bool setShear(const F32 x)                                      { return setShear(x,x); }                       // 0 = no movement, 
00569         bool setRatio(const F32 x, const F32 y);                        // 0 = point, 1 = same as base
00570         bool setShear(const F32 x, const F32 y);                        // 0 = no movement
00571 
00572         bool setTwistBegin(const F32 twist_begin);      // range -1 to 1
00573         bool setTwistEnd(const F32 twist_end);          // range -1 to 1
00574         bool setTwist(const F32 twist)                          { return setTwistEnd(twist); }          // deprecated
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);                            // -1 to 1
00577         bool setTaperY(const F32 v);                            // -1 to 1
00578         bool setRevolutions(const F32 revolutions);     // 1 to 4
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         // 'begin' and 'end' should be in range [0, 1] (they will be clamped)
00615         // (begin, end) = (0, 1) will not change the volume
00616         // (begin, end) = (0, 0.5) will reduce the volume to the first half of its profile/path (S/T)
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 &params)
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; }   // Total number of outside points
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 // SWEEP/EXTRUDE PATHS
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 &params)
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 &params) : LLPath(params) { }
00757         BOOL generate(F32 detail=1.0f, S32 split = 0, BOOL is_sculpted = FALSE);
00758 };
00759 
00760 // Yet another "face" class - caches volume-specific, but not instance-specific data for faces)
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         // Only used for INNER/OUTER faces
00797         S32 mBeginS;
00798         S32 mBeginT;
00799         S32 mNumS;
00800         S32 mNumT;
00801 
00802         LLVector3 mExtents[2]; //minimum and maximum point of face
00803 
00804         std::vector<VertexData> mVertices;
00805         std::vector<S32>        mIndices;
00806         std::vector<S32>        mEdge;
00807         LLVolume *mVolumep; // Deliberately NOT reference counted - djs 11/20/03 - otherwise would make an annoying circular reference
00808 
00809         // Shouldn't need num_old and num_new, really - djs
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&);  // Don't implement
00825         ~LLVolume(); // use unref
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 &params, 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         //get the face index of the face that intersects with the given line segment at the point 
00873         //closest to start.  Moves end to the point of intersection.  Returns -1 if no intersection.
00874         //Line segment must be in volume space.
00875         S32 lineSegmentIntersect(const LLVector3& start, LLVector3& end) const;
00876         
00877         // The following cleans up vertices and triangles,
00878         // getting rid of degenerate triangles and duplicate vertices,
00879         // and allocates new arrays with the clean data.
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);              // HACK to bypass Windoze confusion over 
00895                                                                                                                                                                 // conversion if *(LLVolume*) to LLVolume&
00896         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
00897 
00898         U32                                     mFaceMask;                      // bit array of which faces exist in this volume
00899         LLVector3                       mLODScaleBias;          // vector for biasing LOD based on scale
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

Generated on Thu Jul 1 06:09:41 2010 for Second Life Viewer by  doxygen 1.4.7