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 
00060 
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 
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 
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 
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 
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 
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 
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 
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"; 
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         
00149         if (mVolumep)
00150         {
00151                 gVolumeMgr->cleanupVolume(mVolumep);
00152         }
00153         mVolumep = NULL;
00154 }
00155 
00156 
00157 
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         
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         
00217         
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     
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     
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     
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     
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     
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 
00332 
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 
00348 
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     
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 
00378 
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 
00394 
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      
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     
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     
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     
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     
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     
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     
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     
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     
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         
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 
00541 
00542 
00543 
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554 
00555 
00556 
00557 
00558 
00559 
00560 
00561 
00562 
00563 
00564 
00565 
00566 
00567 
00568 
00569 
00570 
00571 
00572 
00573 
00574 
00575 
00576 
00577 
00578 
00579 
00580 
00581 
00582 
00583 
00584 
00585 
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 
00599 
00600 
00601 
00602 
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 
00636 
00637 
00638 
00639 
00640 
00641 
00642 
00643 
00644 
00645 
00646 
00647 
00648 
00649 
00650 
00651 
00652 
00653 
00654 
00655 
00656 
00657 
00658 
00659 
00660 
00661 
00662 
00663 
00664 
00665 
00666 
00667 
00668 
00669 
00670 
00671 
00672 
00673 
00674 
00675 
00676 
00677 
00678 
00679 
00680 
00681 
00682 
00683 
00684 
00685 
00686 
00687 
00688 
00689 
00690 
00691 
00692 
00693 
00694 
00695 
00696 
00697 
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 
00726 
00727 const char * LLPrimitive::pCodeToString(const LLPCode pcode)
00728 {
00729         static char pcode_string[255];  
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");   
00736         }
00737         else if ((base_code) == LL_PCODE_LEGACY)
00738         {
00739                 
00740                 switch (pcode)
00741                 {
00742                 case LL_PCODE_LEGACY_GRASS:
00743                         snprintf(pcode_string, sizeof(pcode_string), "grass");  
00744                         break;
00745                 case LL_PCODE_LEGACY_PART_SYS:
00746                         snprintf(pcode_string, sizeof(pcode_string), "particle system");        
00747                         break;
00748                 case LL_PCODE_LEGACY_AVATAR:
00749                         snprintf(pcode_string, sizeof(pcode_string), "avatar"); 
00750                         break;
00751                 case LL_PCODE_LEGACY_TEXT_BUBBLE:
00752                         snprintf(pcode_string, sizeof(pcode_string), "text bubble");    
00753                         break;
00754                 case LL_PCODE_LEGACY_TREE:
00755                         snprintf(pcode_string, sizeof(pcode_string), "tree");           
00756                         break;
00757                 case LL_PCODE_TREE_NEW:
00758                         snprintf(pcode_string, sizeof(pcode_string), "tree_new");       
00759                         break;
00760                 default:
00761                         snprintf(pcode_string, sizeof(pcode_string), "unknown legacy pcode %i",(U32)pcode);     
00762                 }
00763         }
00764         else
00765         {
00766                 char shape[32]; 
00767                 char mask[32];  
00768                 if (base_code == LL_PCODE_CUBE)
00769                 {
00770                         snprintf(shape, sizeof(shape), "cube"); 
00771                 }
00772                 else if (base_code == LL_PCODE_CYLINDER)
00773                 {
00774                         snprintf(shape, sizeof(shape), "cylinder");     
00775                 }
00776                 else if (base_code == LL_PCODE_CONE)
00777                 {
00778                         snprintf(shape, sizeof(shape), "cone"); 
00779                 }
00780                 else if (base_code == LL_PCODE_PRISM)
00781                 {
00782                         snprintf(shape, sizeof(shape), "prism");        
00783                 }
00784                 else if (base_code == LL_PCODE_PYRAMID)
00785                 {
00786                         snprintf(shape, sizeof(shape), "pyramid");              
00787                 }
00788                 else if (base_code == LL_PCODE_SPHERE)
00789                 {
00790                         snprintf(shape, sizeof(shape), "sphere");               
00791                 }
00792                 else if (base_code == LL_PCODE_TETRAHEDRON)
00793                 {
00794                         snprintf(shape, sizeof(shape), "tetrahedron");          
00795                 }
00796                 else if (base_code == LL_PCODE_VOLUME)
00797                 {
00798                         snprintf(shape, sizeof(shape), "volume");               
00799                 }
00800                 else if (base_code == LL_PCODE_APP)
00801                 {
00802                         snprintf(shape, sizeof(shape), "app");          
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);          
00813                 }
00814                 else if (mask_code & LL_PCODE_HEMI_MASK)
00815                 {
00816                         snprintf(mask, sizeof(mask), "hemi");           
00817                 }
00818                 else 
00819                 {
00820                         snprintf(mask, sizeof(mask), "%x", mask_code);          
00821                 }
00822 
00823                 
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);             
00830                 }
00831                 else
00832                 {
00833                         snprintf(pcode_string, sizeof(pcode_string), "%s", shape);              
00834                 }
00835         }
00836 
00837         
00838         
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 );  
00910                         return TRUE;
00911                 }
00912         }
00913 
00914         setChanged(GEOMETRY);
00915 
00916         
00917         if (!mVolumep)
00918         {
00919                 mVolumep = volumep;
00920                 
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         
00931         std::vector<LLProfile::Face> old_faces; 
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                         
00947                 }
00948         }
00949 
00950 
00951         
00952         gVolumeMgr->cleanupVolume(mVolumep);
00953         mVolumep = volumep;
00954         
00955         U32 new_face_mask = mVolumep->mFaceMask;
00956         S32 i;
00957 
00958         
00959 
00960 
00961 
00962 
00963 
00964 
00965 
00966 
00967 
00968 
00969 
00970 
00971 
00972 
00973 
00974 
00975 
00976 
00977 
00978 
00979 
00980 
00981 
00982 
00983 
00984 
00985 
00986 
00987 
00988 
00989         if (old_face_mask == new_face_mask) 
00990         {
00991                 
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         
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                         
01016                         face_mapping[face_bit] = -1;
01017                         continue;
01018                 }
01019                 else if (old_face_mask & cur_mask)
01020                 {
01021                         
01022                         face_mapping[face_bit] = face_bit;
01023                         continue;
01024                 }
01025 
01026                 
01027                 
01028                 if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE))
01029                 {
01030                         
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                         
01059                         if (old_face_mask & LL_FACE_INNER_SIDE)
01060                         {
01061                                 face_mapping[face_bit] = 2;
01062                                 continue;
01063                         }
01064 
01065                         
01066                         
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                 
01093                 
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         
01164         for (i = 0; i < cur_size; i++)
01165         {
01166                 
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++)         
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                         
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                 
01266                 memcpy(data_ptr+(i*data_size),data_ptr,data_size);       
01267         }
01268         
01269         while ((cur_ptr < buffer_end) && (*cur_ptr != 0))
01270         {
01271 
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 
01287 
01288 
01289                         }
01290                         i = i >> 1;
01291                 }
01292                 cur_ptr += data_size;           
01293         }
01294         return (S32)(cur_ptr - start_loc);
01295 }
01296 
01297 
01298 
01299 
01300 
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                 
01325                 S8 face_index;
01326                 LLColor4U coloru;
01327                 for (face_index = 0; face_index <= last_face_index; face_index++)
01328                 {
01329                         
01330                         memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16);   
01331 
01332                         
01333                         coloru.setVec( getTE(face_index)->getColor() );
01334 
01335                         
01336                         
01337                         
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                 
01404                 S8 face_index;
01405                 LLColor4U coloru;
01406                 for (face_index = 0; face_index <= last_face_index; face_index++)
01407                 {
01408                         
01409                         memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16);   
01410 
01411                         
01412                         coloru.setVec( getTE(face_index)->getColor() );
01413 
01414                         
01415                         
01416                         
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         
01466         S32 retval = 0;
01467         const U32 MAX_TES = 32;
01468 
01469         
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                 
01548                 
01549                 
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         
01564         S32 retval = 0;
01565         const U32 MAX_TES = 32;
01566 
01567         
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);                
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                 
01642                 
01643                 
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 
01665 
01666 
01667 
01668 
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                 
01704                 return false;
01705         }
01706 }
01707 
01708 
01709 
01710 
01711 BOOL LLNetworkData::isValid(U16 param_type, U32 size)
01712 {
01713         
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         
01808         
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         
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                         
01863                         
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         
01876         
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