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
00062
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
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
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
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
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
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
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
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";
00116
00117
00118
00119
00120 LLVolumeMgr* LLPrimitive::sVolumeManager = NULL;
00121
00122
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
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
00180 if (mVolumep)
00181 {
00182 sVolumeManager->unrefVolume(mVolumep);
00183 }
00184 mVolumep = NULL;
00185 }
00186
00187
00188
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
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
00250
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
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
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
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
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
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
00366
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
00382
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
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
00412
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
00428
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
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
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
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
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
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
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
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
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
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
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
00570
00571 LLPCode pcode = 0;
00572
00573 switch (legacy)
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
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
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
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
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
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
00762
00763 const char * LLPrimitive::pCodeToString(const LLPCode pcode)
00764 {
00765 static char pcode_string[255];
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");
00772 }
00773 else if ((base_code) == LL_PCODE_LEGACY)
00774 {
00775
00776 switch (pcode)
00777 {
00778 case LL_PCODE_LEGACY_GRASS:
00779 snprintf(pcode_string, sizeof(pcode_string), "grass");
00780 break;
00781 case LL_PCODE_LEGACY_PART_SYS:
00782 snprintf(pcode_string, sizeof(pcode_string), "particle system");
00783 break;
00784 case LL_PCODE_LEGACY_AVATAR:
00785 snprintf(pcode_string, sizeof(pcode_string), "avatar");
00786 break;
00787 case LL_PCODE_LEGACY_TEXT_BUBBLE:
00788 snprintf(pcode_string, sizeof(pcode_string), "text bubble");
00789 break;
00790 case LL_PCODE_LEGACY_TREE:
00791 snprintf(pcode_string, sizeof(pcode_string), "tree");
00792 break;
00793 case LL_PCODE_TREE_NEW:
00794 snprintf(pcode_string, sizeof(pcode_string), "tree_new");
00795 break;
00796 default:
00797 snprintf(pcode_string, sizeof(pcode_string), "unknown legacy pcode %i",(U32)pcode);
00798 }
00799 }
00800 else
00801 {
00802 char shape[32];
00803 char mask[32];
00804 if (base_code == LL_PCODE_CUBE)
00805 {
00806 snprintf(shape, sizeof(shape), "cube");
00807 }
00808 else if (base_code == LL_PCODE_CYLINDER)
00809 {
00810 snprintf(shape, sizeof(shape), "cylinder");
00811 }
00812 else if (base_code == LL_PCODE_CONE)
00813 {
00814 snprintf(shape, sizeof(shape), "cone");
00815 }
00816 else if (base_code == LL_PCODE_PRISM)
00817 {
00818 snprintf(shape, sizeof(shape), "prism");
00819 }
00820 else if (base_code == LL_PCODE_PYRAMID)
00821 {
00822 snprintf(shape, sizeof(shape), "pyramid");
00823 }
00824 else if (base_code == LL_PCODE_SPHERE)
00825 {
00826 snprintf(shape, sizeof(shape), "sphere");
00827 }
00828 else if (base_code == LL_PCODE_TETRAHEDRON)
00829 {
00830 snprintf(shape, sizeof(shape), "tetrahedron");
00831 }
00832 else if (base_code == LL_PCODE_VOLUME)
00833 {
00834 snprintf(shape, sizeof(shape), "volume");
00835 }
00836 else if (base_code == LL_PCODE_APP)
00837 {
00838 snprintf(shape, sizeof(shape), "app");
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);
00849 }
00850 else if (mask_code & LL_PCODE_HEMI_MASK)
00851 {
00852 snprintf(mask, sizeof(mask), "hemi");
00853 }
00854 else
00855 {
00856 snprintf(mask, sizeof(mask), "%x", mask_code);
00857 }
00858
00859
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);
00866 }
00867 else
00868 {
00869 snprintf(pcode_string, sizeof(pcode_string), "%s", shape);
00870 }
00871 }
00872
00873
00874
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 );
00947 return TRUE;
00948 }
00949 }
00950
00951 setChanged(GEOMETRY);
00952
00953
00954 if (!mVolumep)
00955 {
00956 mVolumep = volumep;
00957
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
00968 std::vector<LLProfile::Face> old_faces;
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
00984 }
00985 }
00986
00987
00988
00989 sVolumeManager->unrefVolume(mVolumep);
00990 mVolumep = volumep;
00991
00992 U32 new_face_mask = mVolumep->mFaceMask;
00993 S32 i;
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026 if (old_face_mask == new_face_mask)
01027 {
01028
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
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
01053 face_mapping[face_bit] = -1;
01054 continue;
01055 }
01056 else if (old_face_mask & cur_mask)
01057 {
01058
01059 face_mapping[face_bit] = face_bit;
01060 continue;
01061 }
01062
01063
01064
01065 if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE))
01066 {
01067
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
01096 if (old_face_mask & LL_FACE_INNER_SIDE)
01097 {
01098 face_mapping[face_bit] = 2;
01099 continue;
01100 }
01101
01102
01103
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
01130
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
01201 for (i = 0; i < cur_size; i++)
01202 {
01203
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++)
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
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
01303 memcpy(data_ptr+(i*data_size),data_ptr,data_size);
01304 }
01305
01306 while ((cur_ptr < buffer_end) && (*cur_ptr != 0))
01307 {
01308
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
01324
01325
01326 }
01327 i = i >> 1;
01328 }
01329 cur_ptr += data_size;
01330 }
01331 return (S32)(cur_ptr - start_loc);
01332 }
01333
01334
01335
01336
01337
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
01362 S8 face_index;
01363 LLColor4U coloru;
01364 for (face_index = 0; face_index <= last_face_index; face_index++)
01365 {
01366
01367 memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16);
01368
01369
01370 coloru.setVec( getTE(face_index)->getColor() );
01371
01372
01373
01374
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
01441 S8 face_index;
01442 LLColor4U coloru;
01443 for (face_index = 0; face_index <= last_face_index; face_index++)
01444 {
01445
01446 memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16);
01447
01448
01449 coloru.setVec( getTE(face_index)->getColor() );
01450
01451
01452
01453
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
01503 S32 retval = 0;
01504 const U32 MAX_TES = 32;
01505
01506
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
01585
01586
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
01601 S32 retval = 0;
01602 const U32 MAX_TES = 32;
01603
01604
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);
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
01679
01680
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
01702
01703
01704
01705
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
01741 return false;
01742 }
01743 }
01744
01745
01746
01747
01748 BOOL LLNetworkData::isValid(U16 param_type, U32 size)
01749 {
01750
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
01886
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
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
01941
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
01954
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