llprimitive.cpp

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

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