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 #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 // These are defined here but are not enforced at this level,
00064 // rather they are here for the convenience of code that uses
00065 // the LLVolume class.
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 // useful masks
00081 const LLPCode LL_PCODE_HOLLOW_MASK      = 0x80;         // has a thickness
00082 const LLPCode LL_PCODE_SEGMENT_MASK = 0x40;             // segments (1 angle)
00083 const LLPCode LL_PCODE_PATCH_MASK       = 0x20;         // segmented segments (2 angles)
00084 const LLPCode LL_PCODE_HEMI_MASK        = 0x10;         // half-primitives get their own type per PR's dictum
00085 const LLPCode LL_PCODE_BASE_MASK        = 0x0F;
00086 
00087         // primitive shapes
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         // surfaces
00099 //const LLPCode LL_PCODE_SURFACE_TRIANGLE       = 10;
00100 //const LLPCode LL_PCODE_SURFACE_SQUARE         = 11;
00101 //const LLPCode LL_PCODE_SURFACE_DISC           = 12;
00102 
00103 const LLPCode   LL_PCODE_APP                            = 14; // App specific pcode (for viewer/sim side only objects)
00104 const LLPCode   LL_PCODE_LEGACY                         = 15;
00105 
00106 // Pcodes for legacy objects
00107 //const LLPCode LL_PCODE_LEGACY_ATOR =                          0x10 | LL_PCODE_LEGACY; // ATOR
00108 const LLPCode   LL_PCODE_LEGACY_AVATAR =                        0x20 | LL_PCODE_LEGACY; // PLAYER
00109 //const LLPCode LL_PCODE_LEGACY_BIRD =                          0x30 | LL_PCODE_LEGACY; // BIRD
00110 //const LLPCode LL_PCODE_LEGACY_DEMON =                         0x40 | LL_PCODE_LEGACY; // DEMON
00111 const LLPCode   LL_PCODE_LEGACY_GRASS =                         0x50 | LL_PCODE_LEGACY; // GRASS
00112 const LLPCode   LL_PCODE_TREE_NEW =                                     0x60 | LL_PCODE_LEGACY; // new trees
00113 //const LLPCode LL_PCODE_LEGACY_ORACLE =                        0x70 | LL_PCODE_LEGACY; // ORACLE
00114 const LLPCode   LL_PCODE_LEGACY_PART_SYS =                      0x80 | LL_PCODE_LEGACY; // PART_SYS
00115 const LLPCode   LL_PCODE_LEGACY_ROCK =                          0x90 | LL_PCODE_LEGACY; // ROCK
00116 //const LLPCode LL_PCODE_LEGACY_SHOT =                          0xA0 | LL_PCODE_LEGACY; // BASIC_SHOT
00117 //const LLPCode LL_PCODE_LEGACY_SHOT_BIG =                      0xB0 | LL_PCODE_LEGACY;
00118 //const LLPCode LL_PCODE_LEGACY_SMOKE =                         0xC0 | LL_PCODE_LEGACY; // SMOKE
00119 //const LLPCode LL_PCODE_LEGACY_SPARK =                         0xD0 | LL_PCODE_LEGACY;// SPARK
00120 const LLPCode   LL_PCODE_LEGACY_TEXT_BUBBLE =           0xE0 | LL_PCODE_LEGACY; // TEXTBUBBLE
00121 const LLPCode   LL_PCODE_LEGACY_TREE =                          0xF0 | LL_PCODE_LEGACY; // TREE
00122 
00123         // hemis
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 // Volumes consist of a profile at the base that is swept around
00131 // a path to make a volume.
00132 // The profile code
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 // Stored in the profile byte
00144 const U8        LL_PCODE_HOLE_MASK              = 0xf0;
00145 const U8        LL_PCODE_HOLE_MIN               = 0x00;   
00146 const U8        LL_PCODE_HOLE_SAME              = 0x00;         // same as outside profile
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;         // min/max needs to be >> 4 of real min/max
00151 
00152 const U8    LL_PCODE_PATH_IGNORE    = 0x00;
00153 const U8        LL_PCODE_PATH_MIN               = 0x01;         // min/max needs to be >> 4 of real min/max
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 // face identifiers
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 // sculpt types
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 &params) const;
00228         bool operator!=(const LLProfileParams &params) const;
00229         bool operator<(const LLProfileParams &params) const;
00230         
00231         void copyParams(const LLProfileParams &params);
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         // Profile params
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 &params) 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 &params) 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 &params) 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 &params) const;
00353         bool operator!=(const LLPathParams &params) const;
00354         bool operator<(const LLPathParams &params) const;
00355 
00356         void copyParams(const LLPathParams &params);
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; }   // deprecated
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); } // deprecated
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         // Path params
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 &params) 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 &params) 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 &params) 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 &params) const;
00538         bool operator!=(const LLVolumeParams &params) const;
00539         bool operator<(const LLVolumeParams &params) const;
00540 
00541 
00542         void copyParams(const LLVolumeParams &params);
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         //void setBeginS(const F32 beginS)                      { mProfileParams.setBegin(beginS); }    // range 0 to 1
00562         //void setBeginT(const F32 beginT)                      { mPathParams.setBegin(beginT); }               // range 0 to 1
00563         //void setEndS(const F32 endS)                          { mProfileParams.setEnd(endS); }                // range 0 to 1, must be greater than begin
00564         //void setEndT(const F32 endT)                          { mPathParams.setEnd(endT); }                   // range 0 to 1, must be greater than begin
00565 
00566         bool setBeginAndEndS(const F32 begin, const F32 end);                   // both range from 0 to 1, begin must be less than end
00567         bool setBeginAndEndT(const F32 begin, const F32 end);                   // both range from 0 to 1, begin must be less than end
00568 
00569         bool setHollow(const F32 hollow);       // range 0 to 1
00570         bool setRatio(const F32 x)                                      { return setRatio(x,x); }                       // 0 = point, 1 = same as base
00571         bool setShear(const F32 x)                                      { return setShear(x,x); }                       // 0 = no movement, 
00572         bool setRatio(const F32 x, const F32 y);                        // 0 = point, 1 = same as base
00573         bool setShear(const F32 x, const F32 y);                        // 0 = no movement
00574 
00575         bool setTwistBegin(const F32 twist_begin);      // range -1 to 1
00576         bool setTwistEnd(const F32 twist_end);          // range -1 to 1
00577         bool setTwist(const F32 twist)                          { return setTwistEnd(twist); }          // deprecated
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);                            // -1 to 1
00580         bool setTaperY(const F32 v);                            // -1 to 1
00581         bool setRevolutions(const F32 revolutions);     // 1 to 4
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         // 'begin' and 'end' should be in range [0, 1] (they will be clamped)
00618         // (begin, end) = (0, 1) will not change the volume
00619         // (begin, end) = (0, 0.5) will reduce the volume to the first half of its profile/path (S/T)
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         // debug helper functions
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; }   // Total number of outside points
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 // SWEEP/EXTRUDE PATHS
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         /*virtual*/ BOOL generate(const LLPathParams& params, 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                 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         // Only used for INNER/OUTER faces
00809         S32 mBeginS;
00810         S32 mBeginT;
00811         S32 mNumS;
00812         S32 mNumT;
00813 
00814         LLVector3 mExtents[2]; //minimum and maximum point of face
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&);  // Don't implement
00832         ~LLVolume(); // use unref
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 &params, 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         // returns number of triangle indeces required for path/profile mesh
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         //get the face index of the face that intersects with the given line segment at the point 
00886         //closest to start.  Moves end to the point of intersection.  Returns -1 if no intersection.
00887         //Line segment must be in volume space.
00888         S32 lineSegmentIntersect(const LLVector3& start, LLVector3& end) const;
00889         
00890         // The following cleans up vertices and triangles,
00891         // getting rid of degenerate triangles and duplicate vertices,
00892         // and allocates new arrays with the clean data.
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);              // HACK to bypass Windoze confusion over 
00908                                                                                                                                                                 // conversion if *(LLVolume*) to LLVolume&
00909         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
00910 
00911         U32                                     mFaceMask;                      // bit array of which faces exist in this volume
00912         LLVector3                       mLODScaleBias;          // vector for biasing LOD based on scale
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

Generated on Fri May 16 08:32:17 2008 for SecondLife by  doxygen 1.5.5