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