llprimitive.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "material_codes.h"
00035 #include "llerror.h"
00036 #include "message.h"
00037 #include "llprimitive.h"
00038 #include "llvolume.h"
00039 #include "legacy_object_types.h"
00040 #include "v4coloru.h"
00041 #include "llvolumemgr.h"
00042 #include "llstring.h"
00043 #include "lldatapacker.h"
00044 
00049 const F32 OBJECT_CUT_MIN = 0.f;
00050 const F32 OBJECT_CUT_MAX = 1.f;
00051 const F32 OBJECT_CUT_INC = 0.05f;
00052 const F32 OBJECT_MIN_CUT_INC = 0.02f;
00053 const F32 OBJECT_ROTATION_PRECISION = 0.05f;
00054 
00055 const F32 OBJECT_TWIST_MIN = -360.f;
00056 const F32 OBJECT_TWIST_MAX =  360.f;
00057 const F32 OBJECT_TWIST_INC =   18.f;
00058 
00059 // This is used for linear paths,
00060 // since twist is used in a slightly different manner.
00061 const F32 OBJECT_TWIST_LINEAR_MIN       = -180.f;
00062 const F32 OBJECT_TWIST_LINEAR_MAX       =  180.f;
00063 const F32 OBJECT_TWIST_LINEAR_INC       =    9.f;
00064 
00065 const F32 OBJECT_MIN_HOLE_SIZE = 0.05f;
00066 const F32 OBJECT_MAX_HOLE_SIZE_X = 1.0f;
00067 const F32 OBJECT_MAX_HOLE_SIZE_Y = 0.5f;
00068 
00069 // Revolutions parameters.
00070 const F32 OBJECT_REV_MIN = 1.0f;
00071 const F32 OBJECT_REV_MAX = 4.0f;
00072 const F32 OBJECT_REV_INC = 0.1f;
00073 
00074 // lights
00075 const F32 LIGHT_MIN_RADIUS = 0.0f;
00076 const F32 LIGHT_DEFAULT_RADIUS = 5.0f;
00077 const F32 LIGHT_MAX_RADIUS = 20.0f;
00078 const F32 LIGHT_MIN_FALLOFF = 0.0f;
00079 const F32 LIGHT_DEFAULT_FALLOFF = 1.0f;
00080 const F32 LIGHT_MAX_FALLOFF = 2.0f;
00081 const F32 LIGHT_MIN_CUTOFF = 0.0f;
00082 const F32 LIGHT_DEFAULT_CUTOFF = 0.0f;
00083 const F32 LIGHT_MAX_CUTOFF = 180.f;
00084 
00085 // "Tension" => [0,10], increments of 0.1
00086 const F32 FLEXIBLE_OBJECT_MIN_TENSION = 0.0f;
00087 const F32 FLEXIBLE_OBJECT_DEFAULT_TENSION = 1.0f;
00088 const F32 FLEXIBLE_OBJECT_MAX_TENSION = 10.0f; 
00089 
00090 // "Drag" => [0,10], increments of 0.1
00091 const F32 FLEXIBLE_OBJECT_MIN_AIR_FRICTION = 0.0f;
00092 const F32 FLEXIBLE_OBJECT_DEFAULT_AIR_FRICTION = 2.0f;
00093 const F32 FLEXIBLE_OBJECT_MAX_AIR_FRICTION = 10.0f;
00094 
00095 // "Gravity" = [-10,10], increments of 0.1
00096 const F32 FLEXIBLE_OBJECT_MIN_GRAVITY = -10.0f;
00097 const F32 FLEXIBLE_OBJECT_DEFAULT_GRAVITY = 0.3f;
00098 const F32 FLEXIBLE_OBJECT_MAX_GRAVITY = 10.0f;
00099 
00100 // "Wind" = [0,10], increments of 0.1
00101 const F32 FLEXIBLE_OBJECT_MIN_WIND_SENSITIVITY = 0.0f;
00102 const F32 FLEXIBLE_OBJECT_DEFAULT_WIND_SENSITIVITY = 0.0f;
00103 const F32 FLEXIBLE_OBJECT_MAX_WIND_SENSITIVITY = 10.0f;
00104 
00105 // I'll explain later...
00106 const F32 FLEXIBLE_OBJECT_MAX_INTERNAL_TENSION_FORCE = 0.99f; 
00107 
00108 const F32 FLEXIBLE_OBJECT_DEFAULT_LENGTH = 1.0f;
00109 const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE;
00110 const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE;
00111 
00112 
00113 const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e";
00114 
00115 
00116 //===============================================================
00117 LLPrimitive::LLPrimitive()
00118 {
00119         mPrimitiveCode = 0;
00120 
00121         mMaterial = LL_MCODE_STONE;
00122         mVolumep  = NULL;
00123 
00124         mChanged  = UNCHANGED;
00125 
00126         mPosition.setVec(0.f,0.f,0.f);
00127         mVelocity.setVec(0.f,0.f,0.f);
00128         mAcceleration.setVec(0.f,0.f,0.f);
00129 
00130         mRotation.loadIdentity();
00131         mAngularVelocity.setVec(0.f,0.f,0.f);
00132         
00133         mScale.setVec(1.f,1.f,1.f);
00134 
00135         mNumTEs = 0;
00136         mTextureList = NULL;
00137 }
00138 
00139 //===============================================================
00140 LLPrimitive::~LLPrimitive()
00141 {
00142         if (mTextureList)
00143         {
00144                 delete [] mTextureList;
00145                 mTextureList = NULL;
00146         }
00147 
00148         // Cleanup handled by volume manager
00149         if (mVolumep)
00150         {
00151                 gVolumeMgr->cleanupVolume(mVolumep);
00152         }
00153         mVolumep = NULL;
00154 }
00155 
00156 //===============================================================
00157 // static
00158 LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code)
00159 {
00160         LLPrimitive *retval = new LLPrimitive();
00161         
00162         if (retval)
00163         {
00164                 retval->init(p_code);
00165         }
00166         else
00167         {
00168                 llerrs << "primitive allocation failed" << llendl;
00169         }
00170 
00171         return retval;
00172 }
00173 
00174 //===============================================================
00175 void LLPrimitive::init(LLPCode p_code)
00176 {
00177         if (mNumTEs)
00178         {
00179                 if (mTextureList)
00180                 {
00181                         delete [] mTextureList;
00182                 }
00183                 mTextureList = new LLTextureEntry[mNumTEs];
00184         }
00185 
00186         mPrimitiveCode = p_code;
00187 }
00188 
00189 void LLPrimitive::setPCode(const U8 p_code)
00190 {
00191         mPrimitiveCode = p_code;
00192 }
00193 
00194 //===============================================================
00195 const LLTextureEntry * LLPrimitive::getTE(const U8 te_num) const
00196 {
00197         // if we're asking for a non-existent face, return null
00198         if (mNumTEs && (te_num< mNumTEs))
00199         {
00200                 return(&mTextureList[te_num]);
00201         }
00202         else
00203         {       
00204                 return(NULL);
00205         }
00206 }
00207 
00208 //===============================================================
00209 void LLPrimitive::setNumTEs(const U8 num_tes)
00210 {
00211         if (num_tes == mNumTEs)
00212         {
00213                 return;
00214         }
00215         
00216         // Right now, we don't try and preserve entries when the number of faces
00217         // changes.
00218 
00219         if (num_tes)
00220         {
00221                 LLTextureEntry *new_tes;
00222                 new_tes = new LLTextureEntry[num_tes];
00223                 U32 i;
00224                 for (i = 0; i < num_tes; i++)
00225                 {
00226                         if (i < mNumTEs)
00227                         {
00228                                 new_tes[i] = mTextureList[i];
00229                         }
00230                         else if (mNumTEs)
00231                         {
00232                                 new_tes[i] = mTextureList[mNumTEs - 1];
00233                         }
00234                         else
00235                         {
00236                                 new_tes[i] = LLTextureEntry();
00237                         }
00238                 }
00239                 delete[] mTextureList;
00240                 mTextureList = new_tes;
00241         }
00242         else
00243         {
00244                 delete[] mTextureList;
00245                 mTextureList = NULL;
00246         }
00247 
00248 
00249         mNumTEs = num_tes;
00250 }
00251 
00252 //===============================================================
00253 void  LLPrimitive::setAllTETextures(const LLUUID &tex_id)
00254 {
00255         U8 i;
00256 
00257         for (i = 0; i < mNumTEs; i++)
00258         {
00259                 mTextureList[i].setID(tex_id);
00260         }
00261 }
00262 
00263 //===============================================================
00264 void LLPrimitive::setTE(const U8 index, const LLTextureEntry &te)
00265 {
00266         mTextureList[index] = te;
00267 }
00268 
00269 S32  LLPrimitive::setTETexture(const U8 te, const LLUUID &tex_id)
00270 {
00271     // if we're asking for a non-existent face, return null
00272         if (te >= mNumTEs)
00273         {
00274                 llwarns << "setting non-existent te " << te << llendl
00275                 return 0;
00276         }
00277 
00278         return mTextureList[te].setID(tex_id);
00279 }
00280 
00281 S32  LLPrimitive::setTEColor(const U8 te, const LLColor4 &color)
00282 {
00283     // if we're asking for a non-existent face, return null
00284         if (te >= mNumTEs)
00285         {
00286                 llwarns << "setting non-existent te " << te << llendl
00287                 return 0;
00288         }
00289 
00290         return mTextureList[te].setColor(color);
00291 }
00292 
00293 S32  LLPrimitive::setTEColor(const U8 te, const LLColor3 &color)
00294 {
00295     // if we're asking for a non-existent face, return null
00296         if (te >= mNumTEs)
00297         {
00298                 llwarns << "setting non-existent te " << te << llendl
00299                 return 0;
00300         }
00301 
00302         return mTextureList[te].setColor(color);
00303 }
00304 
00305 S32  LLPrimitive::setTEAlpha(const U8 te, const F32 alpha)
00306 {
00307     // if we're asking for a non-existent face, return null
00308         if (te >= mNumTEs)
00309         {
00310                 llwarns << "setting non-existent te " << te << llendl
00311                 return 0;
00312         }
00313 
00314         return mTextureList[te].setAlpha(alpha);
00315 }
00316 
00317 //===============================================================
00318 S32  LLPrimitive::setTEScale(const U8 te, const F32 s, const F32 t)
00319 {
00320     // if we're asking for a non-existent face, return null
00321         if (te >= mNumTEs)
00322         {
00323                 llwarns << "Setting nonexistent face" << llendl;
00324                 return 0;
00325         }
00326 
00327         return mTextureList[te].setScale(s,t);
00328 }
00329 
00330 
00331 // BUG: slow - done this way because texture entries have some
00332 // voodoo related to texture coords
00333 S32 LLPrimitive::setTEScaleS(const U8 te, const F32 s)
00334 {
00335         if (te >= mNumTEs)
00336         {
00337                 llwarns << "Setting nonexistent face" << llendl;
00338                 return 0;
00339         }
00340 
00341         F32 ignore, t;
00342         mTextureList[te].getScale(&ignore, &t);
00343         return mTextureList[te].setScale(s,t);
00344 }
00345 
00346 
00347 // BUG: slow - done this way because texture entries have some
00348 // voodoo related to texture coords
00349 S32 LLPrimitive::setTEScaleT(const U8 te, const F32 t)
00350 {
00351         if (te >= mNumTEs)
00352         {
00353                 llwarns << "Setting nonexistent face" << llendl;
00354                 return 0;
00355         }
00356 
00357         F32 s, ignore;
00358         mTextureList[te].getScale(&s, &ignore);
00359         return mTextureList[te].setScale(s,t);
00360 }
00361 
00362 
00363 //===============================================================
00364 S32  LLPrimitive::setTEOffset(const U8 te, const F32 s, const F32 t)
00365 {
00366     // if we're asking for a non-existent face, return null
00367         if (te >= mNumTEs)
00368         {
00369                 llwarns << "Setting nonexistent face" << llendl;
00370                 return 0;
00371         }
00372 
00373         return mTextureList[te].setOffset(s,t);
00374 }
00375 
00376 
00377 // BUG: slow - done this way because texture entries have some
00378 // voodoo related to texture coords
00379 S32 LLPrimitive::setTEOffsetS(const U8 te, const F32 s)
00380 {
00381         if (te >= mNumTEs)
00382         {
00383                 llwarns << "Setting nonexistent face" << llendl;
00384                 return 0;
00385         }
00386 
00387         F32 ignore, t;
00388         mTextureList[te].getOffset(&ignore, &t);
00389         return mTextureList[te].setOffset(s,t);
00390 }
00391 
00392 
00393 // BUG: slow - done this way because texture entries have some
00394 // voodoo related to texture coords
00395 S32 LLPrimitive::setTEOffsetT(const U8 te, const F32 t)
00396 {
00397         if (te >= mNumTEs)
00398         {
00399                 llwarns << "Setting nonexistent face" << llendl;
00400                 return 0;
00401         }
00402 
00403         F32 s, ignore;
00404         mTextureList[te].getOffset(&s, &ignore);
00405         return mTextureList[te].setOffset(s,t);
00406 }
00407 
00408 
00409 //===============================================================
00410 S32  LLPrimitive::setTERotation(const U8 te, const F32 r)
00411 {
00412      // if we're asking for a non-existent face, return null
00413         if (te >= mNumTEs)
00414         {
00415                 llwarns << "Setting nonexistent face" << llendl;
00416                 return 0;
00417         }
00418 
00419         return mTextureList[te].setRotation(r);
00420 }
00421 
00422 
00423 //===============================================================
00424 S32  LLPrimitive::setTEBumpShinyFullbright(const U8 te, const U8 bump)
00425 {
00426     // if we're asking for a non-existent face, return null
00427         if (te >= mNumTEs)
00428         {
00429                 llwarns << "setting non-existent te " << te << llendl
00430                 return 0;
00431         }
00432 
00433         return mTextureList[te].setBumpShinyFullbright( bump );
00434 }
00435 
00436 S32  LLPrimitive::setTEMediaTexGen(const U8 te, const U8 media)
00437 {
00438     // if we're asking for a non-existent face, return null
00439         if (te >= mNumTEs)
00440         {
00441                 llwarns << "setting non-existent te " << te << llendl
00442                 return 0;
00443         }
00444 
00445         return mTextureList[te].setMediaTexGen( media );
00446 }
00447 
00448 S32  LLPrimitive::setTEBumpmap(const U8 te, const U8 bump)
00449 {
00450     // if we're asking for a non-existent face, return null
00451         if (te >= mNumTEs)
00452         {
00453                 llwarns << "setting non-existent te " << te << llendl
00454                 return 0;
00455         }
00456 
00457         return mTextureList[te].setBumpmap( bump );
00458 }
00459 
00460 S32  LLPrimitive::setTEBumpShiny(const U8 te, const U8 bump_shiny)
00461 {
00462     // if we're asking for a non-existent face, return null
00463         if (te >= mNumTEs)
00464         {
00465                 llwarns << "setting non-existent te " << te << llendl
00466                 return 0;
00467         }
00468 
00469         return mTextureList[te].setBumpShiny( bump_shiny );
00470 }
00471 
00472 S32  LLPrimitive::setTETexGen(const U8 te, const U8 texgen)
00473 {
00474     // if we're asking for a non-existent face, return null
00475         if (te >= mNumTEs)
00476         {
00477                 llwarns << "setting non-existent te " << te << llendl
00478                 return 0;
00479         }
00480 
00481         return mTextureList[te].setTexGen( texgen );
00482 }
00483 
00484 S32  LLPrimitive::setTEShiny(const U8 te, const U8 shiny)
00485 {
00486     // if we're asking for a non-existent face, return null
00487         if (te >= mNumTEs)
00488         {
00489                 llwarns << "setting non-existent te " << te << llendl
00490                 return 0;
00491         }
00492 
00493         return mTextureList[te].setShiny( shiny );
00494 }
00495 
00496 S32  LLPrimitive::setTEFullbright(const U8 te, const U8 fullbright)
00497 {
00498     // if we're asking for a non-existent face, return null
00499         if (te >= mNumTEs)
00500         {
00501                 llwarns << "setting non-existent te " << te << llendl
00502                 return 0;
00503         }
00504 
00505         return mTextureList[te].setFullbright( fullbright );
00506 }
00507 
00508 S32  LLPrimitive::setTEMediaFlags(const U8 te, const U8 media_flags)
00509 {
00510     // if we're asking for a non-existent face, return null
00511         if (te >= mNumTEs)
00512         {
00513                 llwarns << "setting non-existent te " << te << llendl
00514                 return 0;
00515         }
00516 
00517         return mTextureList[te].setMediaFlags( media_flags );
00518 }
00519 
00520 S32 LLPrimitive::setTEGlow(const U8 te, const F32 glow)
00521 {
00522         // if we're asking for a non-existent face, return null
00523         if (te >= mNumTEs)
00524         {
00525                 llwarns << "setting non-existent te " << te << llendl
00526                         return 0;
00527         }
00528 
00529         return mTextureList[te].setGlow( glow );
00530 }
00531 
00532 
00533 LLPCode LLPrimitive::legacyToPCode(const U8 legacy)
00534 {
00535         LLPCode pcode = 0;
00536 
00537         switch (legacy)
00538         {
00539                 /*
00540         case BOX:
00541                 pcode = LL_PCODE_CUBE;
00542                 break;
00543         case CYLINDER:
00544                 pcode = LL_PCODE_CYLINDER;
00545                 break;
00546         case CONE:
00547                 pcode = LL_PCODE_CONE;
00548                 break;
00549         case HALF_CONE:
00550                 pcode = LL_PCODE_CONE_HEMI;
00551                 break;
00552         case HALF_CYLINDER:
00553                 pcode = LL_PCODE_CYLINDER_HEMI;
00554                 break;
00555         case HALF_SPHERE:
00556                 pcode = LL_PCODE_SPHERE_HEMI;
00557                 break;
00558         case PRISM:
00559                 pcode = LL_PCODE_PRISM;
00560                 break;
00561         case PYRAMID:
00562                 pcode = LL_PCODE_PYRAMID;
00563                 break;
00564         case SPHERE:
00565                 pcode = LL_PCODE_SPHERE;
00566                 break;
00567         case TETRAHEDRON:
00568                 pcode = LL_PCODE_TETRAHEDRON;
00569                 break;
00570         case DEMON:
00571                 pcode = LL_PCODE_LEGACY_DEMON;
00572                 break;
00573         case LSL_TEST:
00574                 pcode = LL_PCODE_LEGACY_LSL_TEST;
00575                 break;
00576         case ORACLE:
00577                 pcode = LL_PCODE_LEGACY_ORACLE;
00578                 break;
00579         case TEXTBUBBLE:
00580                 pcode = LL_PCODE_LEGACY_TEXT_BUBBLE;
00581                 break;
00582         case ATOR:
00583                 pcode = LL_PCODE_LEGACY_ATOR;
00584                 break;
00585         case BASIC_SHOT:
00586                 pcode = LL_PCODE_LEGACY_SHOT;
00587                 break;
00588         case BIG_SHOT:
00589                 pcode = LL_PCODE_LEGACY_SHOT_BIG;
00590                 break;
00591         case BIRD:
00592                 pcode = LL_PCODE_LEGACY_BIRD;
00593                 break;
00594         case ROCK:
00595                 pcode = LL_PCODE_LEGACY_ROCK;
00596                 break;
00597         case SMOKE:
00598                 pcode = LL_PCODE_LEGACY_SMOKE;
00599                 break;
00600         case SPARK:
00601                 pcode = LL_PCODE_LEGACY_SPARK;
00602                 break;
00603                 */
00604         case PRIMITIVE_VOLUME:
00605                 pcode = LL_PCODE_VOLUME;
00606                 break;
00607         case GRASS:
00608                 pcode = LL_PCODE_LEGACY_GRASS;
00609                 break;
00610         case PART_SYS:
00611                 pcode = LL_PCODE_LEGACY_PART_SYS;
00612                 break;
00613         case PLAYER:
00614                 pcode = LL_PCODE_LEGACY_AVATAR;
00615                 break;
00616         case TREE:
00617                 pcode = LL_PCODE_LEGACY_TREE;
00618                 break;
00619         case TREE_NEW:
00620                 pcode = LL_PCODE_TREE_NEW;
00621                 break;
00622         default:
00623                 llwarns << "Unknown legacy code " << legacy << "!" << llendl;
00624         }
00625 
00626         return pcode;
00627 }
00628 
00629 U8 LLPrimitive::pCodeToLegacy(const LLPCode pcode)
00630 {
00631         U8 legacy;
00632         switch (pcode)
00633         {
00634 /*
00635         case LL_PCODE_CUBE:
00636                 legacy = BOX;
00637                 break;
00638         case LL_PCODE_CYLINDER:
00639                 legacy = CYLINDER;
00640                 break;
00641         case LL_PCODE_CONE:
00642                 legacy = CONE;
00643                 break;
00644         case LL_PCODE_CONE_HEMI:
00645                 legacy = HALF_CONE;
00646                 break;
00647         case LL_PCODE_CYLINDER_HEMI:
00648                 legacy = HALF_CYLINDER;
00649                 break;
00650         case LL_PCODE_SPHERE_HEMI:
00651                 legacy = HALF_SPHERE;
00652                 break;
00653         case LL_PCODE_PRISM:
00654                 legacy = PRISM;
00655                 break;
00656         case LL_PCODE_PYRAMID:
00657                 legacy = PYRAMID;
00658                 break;
00659         case LL_PCODE_SPHERE:
00660                 legacy = SPHERE;
00661                 break;
00662         case LL_PCODE_TETRAHEDRON:
00663                 legacy = TETRAHEDRON;
00664                 break;
00665         case LL_PCODE_LEGACY_ATOR:
00666                 legacy = ATOR;
00667                 break;
00668         case LL_PCODE_LEGACY_SHOT:
00669                 legacy = BASIC_SHOT;
00670                 break;
00671         case LL_PCODE_LEGACY_SHOT_BIG:
00672                 legacy = BIG_SHOT;
00673                 break;
00674         case LL_PCODE_LEGACY_BIRD:
00675                 legacy = BIRD;
00676                 break;          
00677         case LL_PCODE_LEGACY_DEMON:
00678                 legacy = DEMON;
00679                 break;
00680         case LL_PCODE_LEGACY_LSL_TEST:
00681                 legacy = LSL_TEST;
00682                 break;
00683         case LL_PCODE_LEGACY_ORACLE:
00684                 legacy = ORACLE;
00685                 break;
00686         case LL_PCODE_LEGACY_ROCK:
00687                 legacy = ROCK;
00688                 break;
00689         case LL_PCODE_LEGACY_TEXT_BUBBLE:
00690                 legacy = TEXTBUBBLE;
00691                 break;
00692         case LL_PCODE_LEGACY_SMOKE:
00693                 legacy = SMOKE;
00694                 break;
00695         case LL_PCODE_LEGACY_SPARK:
00696                 legacy = SPARK;
00697                 break;
00698 */
00699         case LL_PCODE_VOLUME:
00700                 legacy = PRIMITIVE_VOLUME;
00701                 break;
00702         case LL_PCODE_LEGACY_GRASS:
00703                 legacy = GRASS;
00704                 break;
00705         case LL_PCODE_LEGACY_PART_SYS:
00706                 legacy = PART_SYS;
00707                 break;
00708         case LL_PCODE_LEGACY_AVATAR:
00709                 legacy = PLAYER;
00710                 break;
00711         case LL_PCODE_LEGACY_TREE:
00712                 legacy = TREE;
00713                 break;
00714         case LL_PCODE_TREE_NEW:
00715                 legacy = TREE_NEW;
00716                 break;
00717         default:
00718                 llwarns << "Unknown pcode " << (S32)pcode << ":" << pcode << "!" << llendl;
00719                 return 0;
00720         }
00721         return legacy;
00722 }
00723 
00724 
00725 // static
00726 // Don't crash or llerrs here!  This function is used for debug strings.
00727 const char * LLPrimitive::pCodeToString(const LLPCode pcode)
00728 {
00729         static char pcode_string[255];  /* Flawfinder: ignore */
00730 
00731         U8 base_code = pcode & LL_PCODE_BASE_MASK;
00732         pcode_string[0] = 0;
00733         if (!pcode)
00734         {
00735                 snprintf(pcode_string, sizeof(pcode_string), "null");   /* Flawfinder: ignore */
00736         }
00737         else if ((base_code) == LL_PCODE_LEGACY)
00738         {
00739                 // It's a legacy object
00740                 switch (pcode)
00741                 {
00742                 case LL_PCODE_LEGACY_GRASS:
00743                         snprintf(pcode_string, sizeof(pcode_string), "grass");  /* Flawfinder: ignore */
00744                         break;
00745                 case LL_PCODE_LEGACY_PART_SYS:
00746                         snprintf(pcode_string, sizeof(pcode_string), "particle system");        /* Flawfinder: ignore */
00747                         break;
00748                 case LL_PCODE_LEGACY_AVATAR:
00749                         snprintf(pcode_string, sizeof(pcode_string), "avatar"); /* Flawfinder: ignore */
00750                         break;
00751                 case LL_PCODE_LEGACY_TEXT_BUBBLE:
00752                         snprintf(pcode_string, sizeof(pcode_string), "text bubble");    /* Flawfinder: ignore */
00753                         break;
00754                 case LL_PCODE_LEGACY_TREE:
00755                         snprintf(pcode_string, sizeof(pcode_string), "tree");           /* Flawfinder: ignore */
00756                         break;
00757                 case LL_PCODE_TREE_NEW:
00758                         snprintf(pcode_string, sizeof(pcode_string), "tree_new");       /* Flawfinder: ignore */
00759                         break;
00760                 default:
00761                         snprintf(pcode_string, sizeof(pcode_string), "unknown legacy pcode %i",(U32)pcode);     /* Flawfinder: ignore */
00762                 }
00763         }
00764         else
00765         {
00766                 char shape[32]; /* Flawfinder: ignore */
00767                 char mask[32];  /* Flawfinder: ignore */
00768                 if (base_code == LL_PCODE_CUBE)
00769                 {
00770                         snprintf(shape, sizeof(shape), "cube"); /* Flawfinder: ignore */
00771                 }
00772                 else if (base_code == LL_PCODE_CYLINDER)
00773                 {
00774                         snprintf(shape, sizeof(shape), "cylinder");     /* Flawfinder: ignore */
00775                 }
00776                 else if (base_code == LL_PCODE_CONE)
00777                 {
00778                         snprintf(shape, sizeof(shape), "cone"); /* Flawfinder: ignore */
00779                 }
00780                 else if (base_code == LL_PCODE_PRISM)
00781                 {
00782                         snprintf(shape, sizeof(shape), "prism");        /* Flawfinder: ignore */
00783                 }
00784                 else if (base_code == LL_PCODE_PYRAMID)
00785                 {
00786                         snprintf(shape, sizeof(shape), "pyramid");              /* Flawfinder: ignore */
00787                 }
00788                 else if (base_code == LL_PCODE_SPHERE)
00789                 {
00790                         snprintf(shape, sizeof(shape), "sphere");               /* Flawfinder: ignore */
00791                 }
00792                 else if (base_code == LL_PCODE_TETRAHEDRON)
00793                 {
00794                         snprintf(shape, sizeof(shape), "tetrahedron");          /* Flawfinder: ignore */
00795                 }
00796                 else if (base_code == LL_PCODE_VOLUME)
00797                 {
00798                         snprintf(shape, sizeof(shape), "volume");               /* Flawfinder: ignore */
00799                 }
00800                 else if (base_code == LL_PCODE_APP)
00801                 {
00802                         snprintf(shape, sizeof(shape), "app");          /* Flawfinder: ignore */
00803                 }
00804                 else
00805                 {
00806                         llwarns << "Unknown base mask for pcode: " << base_code << llendl;
00807                 }
00808 
00809                 U8 mask_code = pcode & (~LL_PCODE_BASE_MASK);
00810                 if (base_code == LL_PCODE_APP)
00811                 {
00812                         snprintf(mask, sizeof(mask), "%x", mask_code);          /* Flawfinder: ignore */
00813                 }
00814                 else if (mask_code & LL_PCODE_HEMI_MASK)
00815                 {
00816                         snprintf(mask, sizeof(mask), "hemi");           /* Flawfinder: ignore */
00817                 }
00818                 else 
00819                 {
00820                         snprintf(mask, sizeof(mask), "%x", mask_code);          /* Flawfinder: ignore */
00821                 }
00822 
00823                 // extra sanity against snprintf() being naturally crap
00824                 mask[sizeof(mask)-1] = '\0';
00825                 shape[sizeof(shape)-1] = '\0';
00826 
00827                 if (mask[0])
00828                 {
00829                         snprintf(pcode_string, sizeof(pcode_string), "%s-%s", shape, mask);             /* Flawfinder: ignore */
00830                 }
00831                 else
00832                 {
00833                         snprintf(pcode_string, sizeof(pcode_string), "%s", shape);              /* Flawfinder: ignore */
00834                 }
00835         }
00836 
00837         // Be really sure that pcode_string is nul-terminated after we've
00838         // been using crappy snprintf() to build it.
00839         pcode_string[sizeof(pcode_string)-1] = '\0';
00840 
00841         return pcode_string;
00842 }
00843 
00844 
00845 void LLPrimitive::copyTEs(const LLPrimitive *primitivep)
00846 {
00847         U32 i;
00848         if (primitivep->getNumTEs() != getNumTEs())
00849         {
00850                 llwarns << "Primitives don't have same number of TE's" << llendl;
00851         }
00852         U32 num_tes = llmin(primitivep->getNumTEs(), getNumTEs());
00853         for (i = 0; i < num_tes; i++)
00854         {
00855                 const LLTextureEntry *tep = primitivep->getTE(i);
00856                 F32 s, t;
00857                 setTETexture(i, tep->getID());
00858                 setTEColor(i, tep->getColor());
00859                 tep->getScale(&s, &t);
00860                 setTEScale(i, s, t);
00861                 tep->getOffset(&s, &t);
00862                 setTEOffset(i, s, t);
00863                 setTERotation(i, tep->getRotation());
00864                 setTEBumpShinyFullbright(i, tep->getBumpShinyFullbright());
00865                 setTEMediaTexGen(i, tep->getMediaTexGen());
00866                 setTEGlow(i, tep->getGlow());
00867         }
00868 }
00869 
00870 S32     face_index_from_id(LLFaceID face_ID, const std::vector<LLProfile::Face>& faceArray)
00871 {
00872         S32 i;
00873         for (i = 0; i < (S32)faceArray.size(); i++)
00874         {
00875                 if (faceArray[i].mFaceID == face_ID)
00876                 {
00877                         return i;
00878                 }
00879         }
00880         return -1;
00881 }
00882 
00883 BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume)
00884 {
00885         LLVolume *volumep;
00886         if (unique_volume)
00887         {
00888                 F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail);
00889                 if (mVolumep.notNull() && volume_params == mVolumep->getParams() && (volume_detail == mVolumep->getDetail()))
00890                 {
00891                         return FALSE;
00892                 }
00893                 volumep = new LLVolume(volume_params, volume_detail, FALSE, TRUE);
00894         }
00895         else
00896         {
00897                 if (mVolumep.notNull())
00898                 {
00899                         F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail);
00900                         if (volume_params == mVolumep->getParams() && (volume_detail == mVolumep->getDetail()))
00901                         {
00902                                 return FALSE;
00903                         }
00904                 }
00905 
00906                 volumep = gVolumeMgr->getVolume(volume_params, detail);
00907                 if (volumep == mVolumep)
00908                 {
00909                         gVolumeMgr->cleanupVolume( volumep );  // gVolumeMgr->getVolume() creates a reference, but we don't need a second one.
00910                         return TRUE;
00911                 }
00912         }
00913 
00914         setChanged(GEOMETRY);
00915 
00916         
00917         if (!mVolumep)
00918         {
00919                 mVolumep = volumep;
00920                 //mFaceMask = mVolumep->generateFaceMask();
00921                 setNumTEs(mVolumep->getNumFaces());
00922                 return TRUE;
00923         }
00924 
00925         U32 old_face_mask = mVolumep->mFaceMask;
00926 
00927         S32 face_bit = 0;
00928         S32 cur_mask = 0;
00929 
00930         // grab copies of the old faces so we can determine the TE mappings...
00931         std::vector<LLProfile::Face> old_faces; // list of old faces for remapping texture entries
00932         LLTextureEntry old_tes[9];
00933 
00934         for (S32 face = 0; face < mVolumep->getNumFaces(); face++)
00935         {
00936                 old_faces.push_back(mVolumep->getProfile().mFaces[face]);
00937         }
00938 
00939         for (face_bit = 0; face_bit < 9; face_bit++)
00940         {
00941                 cur_mask = 0x1 << face_bit;
00942                 if (old_face_mask & cur_mask)
00943                 {
00944                         S32 te_index = face_index_from_id(cur_mask, old_faces);
00945                         old_tes[face_bit] = *getTE(te_index);
00946                         //llinfos << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << llendl;
00947                 }
00948         }
00949 
00950 
00951         // build the new object
00952         gVolumeMgr->cleanupVolume(mVolumep);
00953         mVolumep = volumep;
00954         
00955         U32 new_face_mask = mVolumep->mFaceMask;
00956         S32 i;
00957 
00958         /*
00959         LLString old_mask_string;
00960         for (i = 0; i < 9; i++)
00961         {
00962                 if (old_face_mask & (1 << i))
00963                 {
00964                         old_mask_string.append("1");
00965                 }
00966                 else
00967                 {
00968                         old_mask_string.append("0");
00969                 }
00970         }
00971         LLString new_mask_string;
00972         for (i = 0; i < 9; i++)
00973         {
00974                 if (new_face_mask & (1 << i))
00975                 {
00976                         new_mask_string.append("1");
00977                 }
00978                 else
00979                 {
00980                         new_mask_string.append("0");
00981                 }
00982         }
00983 
00984         llinfos << "old mask: " << old_mask_string << llendl;
00985         llinfos << "new mask: " << new_mask_string << llendl;
00986         */
00987 
00988 
00989         if (old_face_mask == new_face_mask) 
00990         {
00991                 // nothing to do
00992                 return TRUE;
00993         }
00994 
00995         if (mVolumep->getNumFaces() == 0 && new_face_mask != 0)
00996         {
00997                 llwarns << "Object with 0 faces found...INCORRECT!" << llendl;
00998                 setNumTEs(mVolumep->getNumFaces());
00999                 return TRUE;
01000         }
01001 
01002 
01003         S32 face_mapping[9];
01004         for (face_bit = 0; face_bit < 9; face_bit++)
01005         {
01006                 face_mapping[face_bit] = face_bit;
01007         }
01008 
01009         // Generate the face-type mappings
01010         for (face_bit = 0; face_bit < 9; face_bit++)
01011         {
01012                 cur_mask = 0x1 << face_bit;
01013                 if (!(new_face_mask & cur_mask))
01014                 {
01015                         // Face doesn't exist in new map.
01016                         face_mapping[face_bit] = -1;
01017                         continue;
01018                 }
01019                 else if (old_face_mask & cur_mask)
01020                 {
01021                         // Face exists in new and old map.
01022                         face_mapping[face_bit] = face_bit;
01023                         continue;
01024                 }
01025 
01026                 // OK, how we've got a mismatch, where we have to fill a new face with one from
01027                 // the old face.
01028                 if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE))
01029                 {
01030                         // It's a top/bottom/hollow interior face.
01031                         if (old_face_mask & LL_FACE_PATH_END)
01032                         {
01033                                 face_mapping[face_bit] = 1;
01034                                 continue;
01035                         }
01036                         else
01037                         {
01038                                 S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0;
01039                                 for (i = 0; i < 4; i++)
01040                                 {
01041                                         if (old_face_mask & cur_outer_mask)
01042                                         {
01043                                                 face_mapping[face_bit] = 5 + i;
01044                                                 break;
01045                                         }
01046                                         cur_outer_mask <<= 1;
01047                                 }
01048                                 if (i == 4)
01049                                 {
01050                                         llwarns << "No path end or outer face in volume!" << llendl;
01051                                 }
01052                                 continue;
01053                         }
01054                 }
01055 
01056                 if (cur_mask & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END))
01057                 {
01058                         // A cut slice.  Use the hollow interior if we have it.
01059                         if (old_face_mask & LL_FACE_INNER_SIDE)
01060                         {
01061                                 face_mapping[face_bit] = 2;
01062                                 continue;
01063                         }
01064 
01065                         // No interior, use the bottom face.
01066                         // Could figure out which of the outer faces was nearest, but that would be harder.
01067                         if (old_face_mask & LL_FACE_PATH_END)
01068                         {
01069                                 face_mapping[face_bit] = 1;
01070                                 continue;
01071                         }
01072                         else
01073                         {
01074                                 S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0;
01075                                 for (i = 0; i < 4; i++)
01076                                 {
01077                                         if (old_face_mask & cur_outer_mask)
01078                                         {
01079                                                 face_mapping[face_bit] = 5 + i;
01080                                                 break;
01081                                         }
01082                                         cur_outer_mask <<= 1;
01083                                 }
01084                                 if (i == 4)
01085                                 {
01086                                         llwarns << "No path end or outer face in volume!" << llendl;
01087                                 }
01088                                 continue;
01089                         }
01090                 }
01091 
01092                 // OK, the face that's missing is an outer face...
01093                 // Pull from the nearest adjacent outer face (there's always guaranteed to be one...
01094                 S32 cur_outer = face_bit - 5;
01095                 S32 min_dist = 5;
01096                 S32 min_outer_bit = -1;
01097                 S32 i;
01098                 for (i = 0; i < 4; i++)
01099                 {
01100                         if (old_face_mask & (LL_FACE_OUTER_SIDE_0 << i))
01101                         {
01102                                 S32 dist = abs(i - cur_outer);
01103                                 if (dist < min_dist)
01104                                 {
01105                                         min_dist = dist;
01106                                         min_outer_bit = i + 5;
01107                                 }
01108                         }
01109                 }
01110                 if (-1 == min_outer_bit)
01111                 {
01112                         llinfos << (LLVolume *)mVolumep << llendl;
01113                         llwarns << "Bad!  No outer faces, impossible!" << llendl;
01114                 }
01115                 face_mapping[face_bit] = min_outer_bit;
01116         }
01117 
01118 
01119         setNumTEs(mVolumep->getNumFaces());
01120         for (face_bit = 0; face_bit < 9; face_bit++)
01121         {
01122                 cur_mask = 0x1 << face_bit;
01123                 if (new_face_mask & cur_mask)
01124                 {
01125                         if (-1 == face_mapping[face_bit])
01126                         {
01127                                 llwarns << "No mapping from old face to new face!" << llendl;
01128                         }
01129 
01130                         S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces);
01131                         setTE(te_num, old_tes[face_mapping[face_bit]]);
01132                 }
01133         }
01134         return TRUE;
01135 }
01136 
01137 BOOL LLPrimitive::setMaterial(U8 material)
01138 {
01139         if (material != mMaterial)
01140         {
01141                 mMaterial = material;
01142                 return TRUE;
01143         }
01144         else
01145         {
01146                 return FALSE;
01147         }
01148 }
01149 
01150 void LLPrimitive::setTEArrays(const U8 size,
01151                                                           const LLUUID* image_ids,
01152                                                           const F32* scale_s,
01153                                                           const F32* scale_t)
01154 {
01155         S32 cur_size = size;
01156         if (cur_size > getNumTEs())
01157         {
01158                 llwarns << "Trying to set more TEs than exist!" << llendl;
01159                 cur_size = getNumTEs();
01160         }
01161 
01162         S32 i;
01163         // Copy over image information
01164         for (i = 0; i < cur_size; i++)
01165         {
01166                 // This is very BAD!!!!!!
01167                 if (image_ids != NULL)
01168                 {
01169                         setTETexture(i,image_ids[i]);
01170                 }
01171                 if (scale_s && scale_t)
01172                 {
01173                         setTEScale(i, scale_s[i], scale_t[i]);
01174                 }
01175         }
01176 
01177         if (i < getNumTEs())
01178         {
01179                 cur_size--;
01180                 for (i=i; i < getNumTEs(); i++)         // the i=i removes a gcc warning
01181                 {
01182                         if (image_ids != NULL)
01183                         {
01184                                 setTETexture(i, image_ids[cur_size]);
01185                         }
01186                         if (scale_s && scale_t)
01187                         {
01188                                 setTEScale(i, scale_s[cur_size], scale_t[cur_size]);
01189                         }
01190                 }
01191         }
01192 }
01193 
01194 const F32 LL_MAX_SCALE_S = 100.0f;
01195 const F32 LL_MAX_SCALE_T = 100.0f;
01196 S32 LLPrimitive::packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const
01197 {
01198         S32 face_index;
01199         S32 i;
01200         U64 exception_faces;
01201         U8 *start_loc = cur_ptr;
01202 
01203         htonmemcpy(cur_ptr,data_ptr + (last_face_index * data_size), type, data_size);
01204         cur_ptr += data_size;
01205         
01206         for (face_index = last_face_index-1; face_index >= 0; face_index--)
01207         {
01208                 BOOL already_sent = FALSE;
01209                 for (i = face_index+1; i <= last_face_index; i++)
01210                 { 
01211                         if (!memcmp(data_ptr+(data_size *face_index), data_ptr+(data_size *i), data_size))
01212                         {
01213                                 already_sent = TRUE;
01214                                 break;
01215                         }
01216                 }
01217 
01218                 if (!already_sent)
01219                 {
01220                         exception_faces = 0;
01221                         for (i = face_index; i >= 0; i--)
01222                         { 
01223                                 if (!memcmp(data_ptr+(data_size *face_index), data_ptr+(data_size *i), data_size))
01224                                 {
01225                                         exception_faces |= ((U64)1 << i); 
01226                                 }
01227                         }
01228                         
01229                         //assign exception faces to cur_ptr
01230                         if (exception_faces >= (0x1 << 7))
01231                         {
01232                                 if (exception_faces >= (0x1 << 14))
01233                                 {
01234                                         if (exception_faces >= (0x1 << 21))
01235                                         {
01236                                                 if (exception_faces >= (0x1 << 28))
01237                                                 {
01238                                                         *cur_ptr++ = (U8)(((exception_faces >> 28) & 0x7F) | 0x80);
01239                                                 }
01240                                                 *cur_ptr++ = (U8)(((exception_faces >> 21) & 0x7F) | 0x80);
01241                                         }
01242                                         *cur_ptr++ = (U8)(((exception_faces >> 14) & 0x7F) | 0x80);
01243                                 }
01244                                 *cur_ptr++ = (U8)(((exception_faces >> 7) & 0x7F) | 0x80);
01245                         }
01246                         
01247                         *cur_ptr++ = (U8)(exception_faces & 0x7F);
01248                         
01249                         htonmemcpy(cur_ptr,data_ptr + (face_index * data_size), type, data_size);
01250                         cur_ptr += data_size;
01251                 }
01252         }
01253         return (S32)(cur_ptr - start_loc);
01254 }
01255 
01256 S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type)
01257 {
01258         U8 *start_loc = cur_ptr;
01259         U64 i;
01260         htonmemcpy(data_ptr,cur_ptr, type,data_size);
01261         cur_ptr += data_size;
01262 
01263         for (i = 1; i < face_count; i++)
01264         {
01265                 // Already unswizzled, don't need to unswizzle it again!
01266                 memcpy(data_ptr+(i*data_size),data_ptr,data_size);      /* Flawfinder: ignore */ 
01267         }
01268         
01269         while ((cur_ptr < buffer_end) && (*cur_ptr != 0))
01270         {
01271 //              llinfos << "TE exception" << llendl;
01272                 i = 0;
01273                 while (*cur_ptr & 0x80)
01274                 {
01275                         i |= ((*cur_ptr++) & 0x7F);
01276                         i = i << 7;
01277                 }
01278 
01279                 i |= *cur_ptr++;
01280 
01281                 for (S32 j = 0; j < face_count; j++)
01282                 {
01283                         if (i & 0x01)
01284                         {
01285                                 htonmemcpy(data_ptr+(j*data_size),cur_ptr,type,data_size);
01286 //                              char foo[64];
01287 //                              sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1));
01288 //                              llinfos << "Assigning " << foo << " to face " << j << llendl;                   
01289                         }
01290                         i = i >> 1;
01291                 }
01292                 cur_ptr += data_size;           
01293         }
01294         return (S32)(cur_ptr - start_loc);
01295 }
01296 
01297 
01298 // Pack information about all texture entries into container:
01299 // { TextureEntry Variable 2 }
01300 // Includes information about image ID, color, scale S,T, offset S,T and rotation
01301 BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
01302 {
01303         const U32 MAX_TES = 32;
01304 
01305         U8     image_ids[MAX_TES*16];
01306         U8     colors[MAX_TES*4];
01307         F32    scale_s[MAX_TES];
01308         F32    scale_t[MAX_TES];
01309         S16    offset_s[MAX_TES];
01310         S16    offset_t[MAX_TES];
01311         S16    image_rot[MAX_TES];
01312         U8         bump[MAX_TES];
01313         U8         media_flags[MAX_TES];
01314     U8     glow[MAX_TES];
01315         
01316         const U32 MAX_TE_BUFFER = 4096;
01317         U8 packed_buffer[MAX_TE_BUFFER];
01318         U8 *cur_ptr = packed_buffer;
01319         
01320         S32 last_face_index = getNumTEs() - 1;
01321         
01322         if (last_face_index > -1)
01323         {
01324                 // ...if we hit the front, send one image id
01325                 S8 face_index;
01326                 LLColor4U coloru;
01327                 for (face_index = 0; face_index <= last_face_index; face_index++)
01328                 {
01329                         // Directly sending image_ids is not safe!
01330                         memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16);  /* Flawfinder: ignore */ 
01331 
01332                         // Cast LLColor4 to LLColor4U
01333                         coloru.setVec( getTE(face_index)->getColor() );
01334 
01335                         // Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
01336                         // as all zeros.  However, the subtraction and addition must be done in unsigned
01337                         // byte space, not in float space, otherwise off-by-one errors occur. JC
01338                         colors[4*face_index]     = 255 - coloru.mV[0];
01339                         colors[4*face_index + 1] = 255 - coloru.mV[1];
01340                         colors[4*face_index + 2] = 255 - coloru.mV[2];
01341                         colors[4*face_index + 3] = 255 - coloru.mV[3];
01342 
01343                         const LLTextureEntry* te = getTE(face_index);
01344                         scale_s[face_index] = (F32) te->mScaleS;
01345                         scale_t[face_index] = (F32) te->mScaleT;
01346                         offset_s[face_index] = (S16) llround((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ;
01347                         offset_t[face_index] = (S16) llround((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ;
01348                         image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * (F32)0x7FFF));
01349                         bump[face_index] = te->getBumpShinyFullbright();
01350                         media_flags[face_index] = te->getMediaTexGen();
01351                         glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
01352                 }
01353 
01354                 cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
01355                 *cur_ptr++ = 0;
01356                 cur_ptr += packTEField(cur_ptr, (U8 *)colors, 4 ,last_face_index, MVT_U8);
01357                 *cur_ptr++ = 0;
01358                 cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 4 ,last_face_index, MVT_F32);
01359                 *cur_ptr++ = 0;
01360                 cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 4 ,last_face_index, MVT_F32);
01361                 *cur_ptr++ = 0;
01362                 cur_ptr += packTEField(cur_ptr, (U8 *)offset_s, 2 ,last_face_index, MVT_S16Array);
01363                 *cur_ptr++ = 0;
01364                 cur_ptr += packTEField(cur_ptr, (U8 *)offset_t, 2 ,last_face_index, MVT_S16Array);
01365                 *cur_ptr++ = 0;
01366                 cur_ptr += packTEField(cur_ptr, (U8 *)image_rot, 2 ,last_face_index, MVT_S16Array);
01367                 *cur_ptr++ = 0;
01368                 cur_ptr += packTEField(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8);
01369                 *cur_ptr++ = 0;
01370                 cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
01371                 *cur_ptr++ = 0;
01372                 cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
01373         }
01374         mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer));
01375 
01376         return FALSE;
01377 }
01378 
01379 
01380 BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
01381 {
01382         const U32 MAX_TES = 32;
01383 
01384         U8     image_ids[MAX_TES*16];
01385         U8     colors[MAX_TES*4];
01386         F32    scale_s[MAX_TES];
01387         F32    scale_t[MAX_TES];
01388         S16    offset_s[MAX_TES];
01389         S16    offset_t[MAX_TES];
01390         S16    image_rot[MAX_TES];
01391         U8         bump[MAX_TES];
01392         U8         media_flags[MAX_TES];
01393     U8     glow[MAX_TES];
01394         
01395         const U32 MAX_TE_BUFFER = 4096;
01396         U8 packed_buffer[MAX_TE_BUFFER];
01397         U8 *cur_ptr = packed_buffer;
01398         
01399         S32 last_face_index = getNumTEs() - 1;
01400         
01401         if (last_face_index > -1)
01402         {
01403                 // ...if we hit the front, send one image id
01404                 S8 face_index;
01405                 LLColor4U coloru;
01406                 for (face_index = 0; face_index <= last_face_index; face_index++)
01407                 {
01408                         // Directly sending image_ids is not safe!
01409                         memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16);  /* Flawfinder: ignore */ 
01410 
01411                         // Cast LLColor4 to LLColor4U
01412                         coloru.setVec( getTE(face_index)->getColor() );
01413 
01414                         // Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
01415                         // as all zeros.  However, the subtraction and addition must be done in unsigned
01416                         // byte space, not in float space, otherwise off-by-one errors occur. JC
01417                         colors[4*face_index]     = 255 - coloru.mV[0];
01418                         colors[4*face_index + 1] = 255 - coloru.mV[1];
01419                         colors[4*face_index + 2] = 255 - coloru.mV[2];
01420                         colors[4*face_index + 3] = 255 - coloru.mV[3];
01421 
01422                         const LLTextureEntry* te = getTE(face_index);
01423                         scale_s[face_index] = (F32) te->mScaleS;
01424                         scale_t[face_index] = (F32) te->mScaleT;
01425                         offset_s[face_index] = (S16) llround((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ;
01426                         offset_t[face_index] = (S16) llround((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ;
01427                         image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * (F32)0x7FFF));
01428                         bump[face_index] = te->getBumpShinyFullbright();
01429                         media_flags[face_index] = te->getMediaTexGen();
01430             glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
01431                 }
01432 
01433                 cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
01434                 *cur_ptr++ = 0;
01435                 cur_ptr += packTEField(cur_ptr, (U8 *)colors, 4 ,last_face_index, MVT_U8);
01436                 *cur_ptr++ = 0;
01437                 cur_ptr += packTEField(cur_ptr, (U8 *)scale_s, 4 ,last_face_index, MVT_F32);
01438                 *cur_ptr++ = 0;
01439                 cur_ptr += packTEField(cur_ptr, (U8 *)scale_t, 4 ,last_face_index, MVT_F32);
01440                 *cur_ptr++ = 0;
01441                 cur_ptr += packTEField(cur_ptr, (U8 *)offset_s, 2 ,last_face_index, MVT_S16Array);
01442                 *cur_ptr++ = 0;
01443                 cur_ptr += packTEField(cur_ptr, (U8 *)offset_t, 2 ,last_face_index, MVT_S16Array);
01444                 *cur_ptr++ = 0;
01445                 cur_ptr += packTEField(cur_ptr, (U8 *)image_rot, 2 ,last_face_index, MVT_S16Array);
01446                 *cur_ptr++ = 0;
01447                 cur_ptr += packTEField(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8);
01448                 *cur_ptr++ = 0;
01449                 cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
01450                 *cur_ptr++ = 0;
01451                 cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
01452         }
01453 
01454         dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry");
01455         return FALSE;
01456 }
01457 
01458 S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name)
01459 {
01460         return(unpackTEMessage(mesgsys,block_name,-1));
01461 }
01462 
01463 S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, const S32 block_num)
01464 {
01465         // use a negative block_num to indicate a single-block read (a non-variable block)
01466         S32 retval = 0;
01467         const U32 MAX_TES = 32;
01468 
01469         // Avoid construction of 32 UUIDs per call. JC
01470 
01471         U8     image_data[MAX_TES*16];
01472         U8        colors[MAX_TES*4];
01473         F32    scale_s[MAX_TES];
01474         F32    scale_t[MAX_TES];
01475         S16    offset_s[MAX_TES];
01476         S16    offset_t[MAX_TES];
01477         S16    image_rot[MAX_TES];
01478         U8         bump[MAX_TES];
01479         U8         media_flags[MAX_TES];
01480     U8     glow[MAX_TES];
01481         
01482         const U32 MAX_TE_BUFFER = 4096;
01483         U8 packed_buffer[MAX_TE_BUFFER];
01484         U8 *cur_ptr = packed_buffer;
01485 
01486         U32 size;
01487         U32 face_count = 0;
01488 
01489         if (block_num < 0)
01490         {
01491                 size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry);
01492         }
01493         else
01494         {
01495                 size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry);
01496         }
01497 
01498         if (size == 0)
01499         {
01500                 return retval;
01501         }
01502 
01503         if (block_num < 0)
01504         {
01505                 mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, 0, MAX_TE_BUFFER);
01506         }
01507         else
01508         {
01509                 mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, block_num, MAX_TE_BUFFER);
01510         }
01511 
01512         face_count = getNumTEs();
01513 
01514         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_data, 16, face_count, MVT_LLUUID);
01515         cur_ptr++;
01516         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8);
01517         cur_ptr++;
01518         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32);
01519         cur_ptr++;
01520         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32);
01521         cur_ptr++;
01522         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array);
01523         cur_ptr++;
01524         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_t, 2, face_count, MVT_S16Array);
01525         cur_ptr++;
01526         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_rot, 2, face_count, MVT_S16Array);
01527         cur_ptr++;
01528         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8);
01529         cur_ptr++;
01530         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
01531         cur_ptr++;
01532         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
01533         
01534         LLColor4 color;
01535         LLColor4U coloru;
01536         for (U32 i = 0; i < face_count; i++)
01537         {
01538                 retval |= setTETexture(i, ((LLUUID*)image_data)[i]);
01539                 retval |= setTEScale(i, scale_s[i], scale_t[i]);
01540                 retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF);
01541                 retval |= setTERotation(i, ((F32)image_rot[i]/ (F32)0x7FFF) * F_TWO_PI);
01542                 retval |= setTEBumpShinyFullbright(i, bump[i]);
01543                 retval |= setTEMediaTexGen(i, media_flags[i]);
01544                 retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
01545                 coloru = LLColor4U(colors + 4*i);
01546 
01547                 // Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
01548                 // as all zeros.  However, the subtraction and addition must be done in unsigned
01549                 // byte space, not in float space, otherwise off-by-one errors occur. JC
01550                 color.mV[VRED]          = F32(255 - coloru.mV[VRED])   / 255.f;
01551                 color.mV[VGREEN]        = F32(255 - coloru.mV[VGREEN]) / 255.f;
01552                 color.mV[VBLUE]         = F32(255 - coloru.mV[VBLUE])  / 255.f;
01553                 color.mV[VALPHA]        = F32(255 - coloru.mV[VALPHA]) / 255.f;
01554 
01555                 retval |= setTEColor(i, color);
01556         }
01557 
01558         return retval;
01559 }
01560 
01561 S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
01562 {
01563         // use a negative block_num to indicate a single-block read (a non-variable block)
01564         S32 retval = 0;
01565         const U32 MAX_TES = 32;
01566 
01567         // Avoid construction of 32 UUIDs per call
01568         static LLUUID image_ids[MAX_TES];
01569 
01570         U8     image_data[MAX_TES*16];
01571         U8         colors[MAX_TES*4];
01572         F32    scale_s[MAX_TES];
01573         F32    scale_t[MAX_TES];
01574         S16    offset_s[MAX_TES];
01575         S16    offset_t[MAX_TES];
01576         S16    image_rot[MAX_TES];
01577         U8         bump[MAX_TES];
01578         U8         media_flags[MAX_TES];
01579     U8     glow[MAX_TES];
01580 
01581         const U32 MAX_TE_BUFFER = 4096;
01582         U8 packed_buffer[MAX_TE_BUFFER];
01583         U8 *cur_ptr = packed_buffer;
01584 
01585         S32 size;
01586         U32 face_count = 0;
01587 
01588         if (!dp.unpackBinaryData(packed_buffer, size, "TextureEntry"))
01589         {
01590                 retval = TEM_INVALID;
01591                 llwarns << "Bad texture entry block!  Abort!" << llendl;
01592                 return retval;
01593         }
01594 
01595         if (size == 0)
01596         {
01597                 return retval;
01598         }
01599 
01600         face_count = getNumTEs();
01601         U32 i;
01602 
01603         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_data, 16, face_count, MVT_LLUUID);
01604         cur_ptr++;
01605         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8);
01606         cur_ptr++;
01607         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32);
01608         cur_ptr++;
01609         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32);
01610         cur_ptr++;
01611         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array);
01612         cur_ptr++;
01613         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_t, 2, face_count, MVT_S16Array);
01614         cur_ptr++;
01615         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_rot, 2, face_count, MVT_S16Array);
01616         cur_ptr++;
01617         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8);
01618         cur_ptr++;
01619         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
01620         cur_ptr++;
01621         cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
01622 
01623         for (i = 0; i < face_count; i++)
01624         {
01625                 memcpy(image_ids[i].mData,&image_data[i*16],16);        /* Flawfinder: ignore */        
01626         }
01627         
01628         LLColor4 color;
01629         LLColor4U coloru;
01630         for (i = 0; i < face_count; i++)
01631         {
01632                 retval |= setTETexture(i, image_ids[i]);
01633                 retval |= setTEScale(i, scale_s[i], scale_t[i]);
01634                 retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF);
01635                 retval |= setTERotation(i, ((F32)image_rot[i]/ (F32)0x7FFF) * F_TWO_PI);
01636                 retval |= setTEBumpShinyFullbright(i, bump[i]);
01637                 retval |= setTEMediaTexGen(i, media_flags[i]);
01638                 retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
01639                 coloru = LLColor4U(colors + 4*i);
01640 
01641                 // Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
01642                 // as all zeros.  However, the subtraction and addition must be done in unsigned
01643                 // byte space, not in float space, otherwise off-by-one errors occur. JC
01644                 color.mV[VRED]          = F32(255 - coloru.mV[VRED])   / 255.f;
01645                 color.mV[VGREEN]        = F32(255 - coloru.mV[VGREEN]) / 255.f;
01646                 color.mV[VBLUE]         = F32(255 - coloru.mV[VBLUE])  / 255.f;
01647                 color.mV[VALPHA]        = F32(255 - coloru.mV[VALPHA]) / 255.f;
01648 
01649                 retval |= setTEColor(i, color);
01650         }
01651 
01652         return retval;
01653 }
01654 
01655 void LLPrimitive::setTextureList(LLTextureEntry *listp)
01656 {
01657         LLTextureEntry* old_texture_list = mTextureList;
01658         mTextureList = listp;
01659         delete[] old_texture_list;
01660 }
01661 
01662 //============================================================================
01663 
01664 // Moved from llselectmgr.cpp
01665 // BUG: Only works for boxes.
01666 // Face numbering for flex boxes as of 1.14.2
01667 
01668 // static
01669 bool LLPrimitive::getTESTAxes(const U8 face, U32* s_axis, U32* t_axis)
01670 {
01671         if (face == 0)
01672         {
01673                 *s_axis = VX; *t_axis = VY;
01674                 return true;
01675         }
01676         else if (face == 1)
01677         {
01678                 *s_axis = VX; *t_axis = VZ;
01679                 return true;
01680         }
01681         else if (face == 2)
01682         {
01683                 *s_axis = VY; *t_axis = VZ;
01684                 return true;
01685         }
01686         else if (face == 3)
01687         {
01688                 *s_axis = VX; *t_axis = VZ;
01689                 return true;
01690         }
01691         else if (face == 4)
01692         {
01693                 *s_axis = VY; *t_axis = VZ;
01694                 return true;
01695         }
01696         else if (face == 5)
01697         {
01698                 *s_axis = VX; *t_axis = VY;
01699                 return true;
01700         }
01701         else
01702         {
01703                 // unknown face
01704                 return false;
01705         }
01706 }
01707 
01708 //============================================================================
01709 
01710 //static 
01711 BOOL LLNetworkData::isValid(U16 param_type, U32 size)
01712 {
01713         // ew - better mechanism needed
01714         
01715         switch(param_type)
01716         {
01717         case PARAMS_FLEXIBLE:
01718                 return (size == 16);
01719         case PARAMS_LIGHT:
01720                 return (size == 16);
01721         case PARAMS_SCULPT:
01722                 return (size == 17);
01723         }
01724         
01725         return FALSE;
01726 }
01727 
01728 //============================================================================
01729 
01730 LLLightParams::LLLightParams()
01731 {
01732         mColor.setToWhite();
01733         mRadius = 10.f;
01734         mCutoff = 0.0f;
01735         mFalloff = 0.75f;
01736 
01737         mType = PARAMS_LIGHT;
01738 }
01739 
01740 BOOL LLLightParams::pack(LLDataPacker &dp) const
01741 {
01742         LLColor4U color4u(mColor);
01743         dp.packColor4U(color4u, "color");
01744         dp.packF32(mRadius, "radius");
01745         dp.packF32(mCutoff, "cutoff");
01746         dp.packF32(mFalloff, "falloff");
01747         return TRUE;
01748 }
01749 
01750 BOOL LLLightParams::unpack(LLDataPacker &dp)
01751 {
01752         LLColor4U color;
01753         dp.unpackColor4U(color, "color");
01754         setColor(LLColor4(color));
01755 
01756         F32 radius;
01757         dp.unpackF32(radius, "radius");
01758         setRadius(radius);
01759 
01760         F32 cutoff;
01761         dp.unpackF32(cutoff, "cutoff");
01762         setCutoff(cutoff);
01763 
01764         F32 falloff;
01765         dp.unpackF32(falloff, "falloff");
01766         setFalloff(falloff);
01767         
01768         return TRUE;
01769 }
01770 
01771 bool LLLightParams::operator==(const LLNetworkData& data) const
01772 {
01773         if (data.mType != PARAMS_LIGHT)
01774         {
01775                 return false;
01776         }
01777         const LLLightParams *param = (const LLLightParams*)&data;
01778         if (param->mColor != mColor ||
01779                 param->mRadius != mRadius ||
01780                 param->mCutoff != mCutoff ||
01781                 param->mFalloff != mFalloff)
01782         {
01783                 return false;
01784         }
01785         return true;
01786 }
01787 
01788 void LLLightParams::copy(const LLNetworkData& data)
01789 {
01790         const LLLightParams *param = (LLLightParams*)&data;
01791         mType = param->mType;
01792         mColor = param->mColor;
01793         mRadius = param->mRadius;
01794         mCutoff = param->mCutoff;
01795         mFalloff = param->mFalloff;
01796 }
01797 
01798 //============================================================================
01799 
01800 LLFlexibleObjectData::LLFlexibleObjectData()
01801 {
01802         mSimulateLOD                            = FLEXIBLE_OBJECT_DEFAULT_NUM_SECTIONS;
01803         mGravity                                        = FLEXIBLE_OBJECT_DEFAULT_GRAVITY;
01804         mAirFriction                            = FLEXIBLE_OBJECT_DEFAULT_AIR_FRICTION;
01805         mWindSensitivity                        = FLEXIBLE_OBJECT_DEFAULT_WIND_SENSITIVITY;
01806         mTension                                        = FLEXIBLE_OBJECT_DEFAULT_TENSION;
01807         //mUsingCollisionSphere         = FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE;
01808         //mRenderingCollisionSphere     = FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE;
01809         mUserForce                                      = LLVector3(0.f, 0.f, 0.f);
01810 
01811         mType = PARAMS_FLEXIBLE;
01812 }
01813 
01814 BOOL LLFlexibleObjectData::pack(LLDataPacker &dp) const
01815 {
01816         // Custom, uber-svelte pack "softness" in upper bits of tension & drag
01817         U8 bit1 = (mSimulateLOD & 2) << 6;
01818         U8 bit2 = (mSimulateLOD & 1) << 7;
01819         dp.packU8((U8)(mTension*10.01f) + bit1, "tension");
01820         dp.packU8((U8)(mAirFriction*10.01f) + bit2, "drag");
01821         dp.packU8((U8)((mGravity+10.f)*10.01f), "gravity");
01822         dp.packU8((U8)(mWindSensitivity*10.01f), "wind");
01823         dp.packVector3(mUserForce, "userforce");
01824         return TRUE;
01825 }
01826 
01827 BOOL LLFlexibleObjectData::unpack(LLDataPacker &dp)
01828 {
01829         U8 tension, friction, gravity, wind;
01830         U8 bit1, bit2;
01831         dp.unpackU8(tension, "tension");        bit1 = (tension >> 6) & 2;
01832                                                                                 mTension = ((F32)(tension&0x7f))/10.f;
01833         dp.unpackU8(friction, "drag");          bit2 = (friction >> 7) & 1;
01834                                                                                 mAirFriction = ((F32)(friction&0x7f))/10.f;
01835                                                                                 mSimulateLOD = bit1 | bit2;
01836         dp.unpackU8(gravity, "gravity");        mGravity = ((F32)gravity)/10.f - 10.f;
01837         dp.unpackU8(wind, "wind");                      mWindSensitivity = ((F32)wind)/10.f;
01838         if (dp.hasNext())
01839         {
01840                 dp.unpackVector3(mUserForce, "userforce");
01841         }
01842         else
01843         {
01844                 mUserForce.setVec(0.f, 0.f, 0.f);
01845         }
01846         return TRUE;
01847 }
01848 
01849 bool LLFlexibleObjectData::operator==(const LLNetworkData& data) const
01850 {
01851         if (data.mType != PARAMS_FLEXIBLE)
01852         {
01853                 return false;
01854         }
01855         LLFlexibleObjectData *flex_data = (LLFlexibleObjectData*)&data;
01856         return (mSimulateLOD == flex_data->mSimulateLOD &&
01857                         mGravity == flex_data->mGravity &&
01858                         mAirFriction == flex_data->mAirFriction &&
01859                         mWindSensitivity == flex_data->mWindSensitivity &&
01860                         mTension == flex_data->mTension &&
01861                         mUserForce == flex_data->mUserForce);
01862                         //mUsingCollisionSphere == flex_data->mUsingCollisionSphere &&
01863                         //mRenderingCollisionSphere == flex_data->mRenderingCollisionSphere
01864 }
01865 
01866 void LLFlexibleObjectData::copy(const LLNetworkData& data)
01867 {
01868         const LLFlexibleObjectData *flex_data = (LLFlexibleObjectData*)&data;
01869         mSimulateLOD = flex_data->mSimulateLOD;
01870         mGravity = flex_data->mGravity;
01871         mAirFriction = flex_data->mAirFriction;
01872         mWindSensitivity = flex_data->mWindSensitivity;
01873         mTension = flex_data->mTension;
01874         mUserForce = flex_data->mUserForce;
01875         //mUsingCollisionSphere = flex_data->mUsingCollisionSphere;
01876         //mRenderingCollisionSphere = flex_data->mRenderingCollisionSphere;
01877 }
01878 
01879 
01880 //============================================================================
01881 
01882 LLSculptParams::LLSculptParams()
01883 {
01884         mType = PARAMS_SCULPT;
01885         mSculptTexture.set(SCULPT_DEFAULT_TEXTURE);
01886         mSculptType = LL_SCULPT_TYPE_SPHERE;
01887 }
01888 
01889 BOOL LLSculptParams::pack(LLDataPacker &dp) const
01890 {
01891         dp.packUUID(mSculptTexture, "texture");
01892         dp.packU8(mSculptType, "type");
01893         
01894         return TRUE;
01895 }
01896 
01897 BOOL LLSculptParams::unpack(LLDataPacker &dp)
01898 {
01899         dp.unpackUUID(mSculptTexture, "texture");
01900         dp.unpackU8(mSculptType, "type");
01901         
01902         return TRUE;
01903 }
01904 
01905 bool LLSculptParams::operator==(const LLNetworkData& data) const
01906 {
01907         if (data.mType != PARAMS_SCULPT)
01908         {
01909                 return false;
01910         }
01911         
01912         const LLSculptParams *param = (const LLSculptParams*)&data;
01913         if ( (param->mSculptTexture != mSculptTexture) ||
01914                  (param->mSculptType != mSculptType) )
01915                  
01916         {
01917                 return false;
01918         }
01919         
01920         return true;
01921 }
01922 
01923 void LLSculptParams::copy(const LLNetworkData& data)
01924 {
01925         const LLSculptParams *param = (LLSculptParams*)&data;
01926         mSculptTexture = param->mSculptTexture;
01927         mSculptType = param->mSculptType;
01928 }
01929 

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