00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llviewerobject.h"
00035
00036 #include "audioengine.h"
00037 #include "imageids.h"
00038 #include "indra_constants.h"
00039 #include "llmath.h"
00040 #include "llflexibleobject.h"
00041 #include "llviewercontrol.h"
00042 #include "lldatapacker.h"
00043 #include "llfasttimer.h"
00044 #include "llfontgl.h"
00045 #include "llframetimer.h"
00046 #include "llinventory.h"
00047 #include "llmaterialtable.h"
00048 #include "llmutelist.h"
00049 #include "llnamevalue.h"
00050 #include "llprimitive.h"
00051 #include "llquantize.h"
00052 #include "llregionhandle.h"
00053 #include "lltree_common.h"
00054 #include "llxfermanager.h"
00055 #include "message.h"
00056 #include "object_flags.h"
00057 #include "timing.h"
00058
00059 #include "llaudiosourcevo.h"
00060 #include "llagent.h"
00061 #include "llbbox.h"
00062 #include "llbox.h"
00063 #include "llcylinder.h"
00064 #include "lldrawable.h"
00065 #include "llface.h"
00066 #include "llfloaterproperties.h"
00067 #include "llfollowcam.h"
00068 #include "llnetmap.h"
00069 #include "llselectmgr.h"
00070 #include "llrendersphere.h"
00071 #include "lltooldraganddrop.h"
00072 #include "llviewercamera.h"
00073 #include "llviewerimagelist.h"
00074 #include "llviewerinventory.h"
00075 #include "llviewerobjectlist.h"
00076 #include "llviewerparceloverlay.h"
00077 #include "llviewerpartsource.h"
00078 #include "llviewerregion.h"
00079 #include "llviewertextureanim.h"
00080 #include "llviewerwindow.h"
00081 #include "llvoavatar.h"
00082 #include "llvoclouds.h"
00083 #include "llvograss.h"
00084 #include "llvoground.h"
00085 #include "llvolume.h"
00086 #include "llvolumemessage.h"
00087 #include "llvopartgroup.h"
00088 #include "llvosky.h"
00089 #include "llvosurfacepatch.h"
00090 #include "llvotextbubble.h"
00091 #include "llvotree.h"
00092 #include "llvovolume.h"
00093 #include "llvowater.h"
00094 #include "llworld.h"
00095 #include "llui.h"
00096 #include "pipeline.h"
00097 #include "llappviewer.h"
00098 #include "llvowlsky.h"
00099
00100
00101
00102 BOOL gVelocityInterpolate = TRUE;
00103 BOOL gPingInterpolate = TRUE;
00104
00105 U32 LLViewerObject::sNumZombieObjects = 0;
00106 S32 LLViewerObject::sNumObjects = 0;
00107 BOOL LLViewerObject::sMapDebug = TRUE;
00108 LLColor4 LLViewerObject::sEditSelectColor( 1.0f, 1.f, 0.f, 0.3f);
00109 LLColor4 LLViewerObject::sNoEditSelectColor( 1.0f, 0.f, 0.f, 0.3f);
00110 S32 LLViewerObject::sAxisArrowLength(50);
00111 BOOL LLViewerObject::sPulseEnabled(FALSE);
00112 BOOL LLViewerObject::sUseSharedDrawables(FALSE);
00113
00114
00115 LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
00116 {
00117 LLViewerObject *res = NULL;
00118 LLFastTimer t1(LLFastTimer::FTM_CREATE_OBJECT);
00119
00120 switch (pcode)
00121 {
00122 case LL_PCODE_VOLUME:
00123 res = new LLVOVolume(id, pcode, regionp); break;
00124 case LL_PCODE_LEGACY_AVATAR:
00125 res = new LLVOAvatar(id, pcode, regionp); break;
00126 case LL_PCODE_LEGACY_GRASS:
00127 res = new LLVOGrass(id, pcode, regionp); break;
00128 case LL_PCODE_LEGACY_PART_SYS:
00129
00130
00131 res = NULL; break;
00132 case LL_PCODE_LEGACY_TREE:
00133 res = new LLVOTree(id, pcode, regionp); break;
00134 case LL_PCODE_TREE_NEW:
00135
00136
00137 res = NULL; break;
00138 case LL_PCODE_LEGACY_TEXT_BUBBLE:
00139 res = new LLVOTextBubble(id, pcode, regionp); break;
00140 case LL_VO_CLOUDS:
00141 res = new LLVOClouds(id, pcode, regionp); break;
00142 case LL_VO_SURFACE_PATCH:
00143 res = new LLVOSurfacePatch(id, pcode, regionp); break;
00144 case LL_VO_SKY:
00145 res = new LLVOSky(id, pcode, regionp); break;
00146 case LL_VO_WATER:
00147 res = new LLVOWater(id, pcode, regionp); break;
00148 case LL_VO_GROUND:
00149 res = new LLVOGround(id, pcode, regionp); break;
00150 case LL_VO_PART_GROUP:
00151 res = new LLVOPartGroup(id, pcode, regionp); break;
00152 case LL_VO_WL_SKY:
00153 res = new LLVOWLSky(id, pcode, regionp); break;
00154 default:
00155 llwarns << "Unknown object pcode " << (S32)pcode << llendl;
00156 res = NULL; break;
00157 }
00158 return res;
00159 }
00160
00161 LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
00162 : LLPrimitive(),
00163 mChildList(),
00164 mID(id),
00165 mLocalID(0),
00166 mTotalCRC(0),
00167 mTEImages(NULL),
00168 mGLName(0),
00169 mbCanSelect(TRUE),
00170 mFlags(0),
00171 mDrawable(),
00172 mCreateSelected(FALSE),
00173 mRenderMedia(FALSE),
00174 mBestUpdatePrecision(0),
00175 mText(),
00176 mLastInterpUpdateSecs(0.f),
00177 mLastMessageUpdateSecs(0.f),
00178 mLatestRecvPacketID(0),
00179 mData(NULL),
00180 mAudioSourcep(NULL),
00181 mAudioGain(1.f),
00182 mAppAngle(0.f),
00183 mPixelArea(1024.f),
00184 mInventory(NULL),
00185 mInventorySerialNum(0),
00186 mRegionp( regionp ),
00187 mInventoryPending(FALSE),
00188 mInventoryDirty(FALSE),
00189 mDead(FALSE),
00190 mOrphaned(FALSE),
00191 mUserSelected(FALSE),
00192 mOnActiveList(FALSE),
00193 mOnMap(FALSE),
00194 mStatic(FALSE),
00195 mNumFaces(0),
00196 mTimeDilation(1.f),
00197 mRotTime(0.f),
00198 mJointInfo(NULL),
00199 mState(0),
00200 mMedia(NULL),
00201 mClickAction(0)
00202 {
00203 llassert(mRegionp);
00204
00205 LLPrimitive::init_primitive(pcode);
00206
00207
00208 mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds();
00209
00210 mPositionRegion = LLVector3(0.f, 0.f, 0.f);
00211 mPositionAgent = mRegionp->getOriginAgent();
00212
00213 LLViewerObject::sNumObjects++;
00214 }
00215
00216 LLViewerObject::~LLViewerObject()
00217 {
00218 deleteTEImages();
00219
00220 if(mInventory)
00221 {
00222 mInventory->clear();
00223 delete mInventory;
00224 mInventory = NULL;
00225 }
00226
00227 if (mJointInfo)
00228 {
00229 delete mJointInfo;
00230 mJointInfo = NULL;
00231 }
00232
00233 if (mPartSourcep)
00234 {
00235 mPartSourcep->setDead();
00236 mPartSourcep = NULL;
00237 }
00238
00239
00240 std::map<U16, ExtraParameter*>::iterator iter;
00241 for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
00242 {
00243 if(iter->second != NULL)
00244 {
00245 delete iter->second->data;
00246 delete iter->second;
00247 }
00248 }
00249 mExtraParameterList.clear();
00250
00251 for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ;
00252 mNameValuePairs.clear();
00253
00254 delete[] mData;
00255 mData = NULL;
00256
00257 delete mMedia;
00258 mMedia = NULL;
00259
00260 sNumObjects--;
00261 sNumZombieObjects--;
00262 llassert(mChildList.size() == 0);
00263
00264 clearInventoryListeners();
00265 }
00266
00267 void LLViewerObject::deleteTEImages()
00268 {
00269 delete[] mTEImages;
00270 mTEImages = NULL;
00271 }
00272
00273 void LLViewerObject::markDead()
00274 {
00275 if (!mDead)
00276 {
00277
00278
00279
00280 if (getParent())
00281 {
00282 ((LLViewerObject *)getParent())->removeChild(this);
00283
00284 delete mJointInfo;
00285 mJointInfo = NULL;
00286 }
00287
00288
00289 mDead = TRUE;
00290 gObjectList.cleanupReferences(this);
00291
00292 LLViewerObject *childp;
00293 while (mChildList.size() > 0)
00294 {
00295 childp = mChildList[0];
00296 if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR)
00297 {
00298
00299 childp->setParent(NULL);
00300 childp->markDead();
00301 }
00302 else
00303 {
00304
00305
00306 childp->setDrawableParent(NULL);
00307 ((LLVOAvatar*)childp)->getOffObject();
00308 childp->setParent(NULL);
00309 }
00310 mChildList.erase(mChildList.begin());
00311 }
00312
00313 if (mDrawable.notNull())
00314 {
00315
00316 mDrawable->markDead();
00317 mDrawable = NULL;
00318 }
00319
00320 if (mText)
00321 {
00322 mText->markDead();
00323 mText = NULL;
00324 }
00325
00326 if (mIcon)
00327 {
00328 mIcon->markDead();
00329 mIcon = NULL;
00330 }
00331
00332 if (mPartSourcep)
00333 {
00334 mPartSourcep->setDead();
00335 mPartSourcep = NULL;
00336 }
00337
00338 if (mAudioSourcep)
00339 {
00340
00341 if (gAudiop)
00342 {
00343 gAudiop->cleanupAudioSource(mAudioSourcep);
00344 }
00345 mAudioSourcep = NULL;
00346 }
00347
00348 if (flagAnimSource())
00349 {
00350 LLVOAvatar* avatarp = gAgent.getAvatarObject();
00351 if (avatarp && !avatarp->isDead())
00352 {
00353
00354 avatarp->stopMotionFromSource(mID);
00355 }
00356 }
00357
00358 if (flagCameraSource())
00359 {
00360 LLFollowCamMgr::removeFollowCamParams(mID);
00361 }
00362
00363 sNumZombieObjects++;
00364 }
00365 }
00366
00367 void LLViewerObject::dump() const
00368 {
00369 llinfos << "Type: " << pCodeToString(mPrimitiveCode) << llendl;
00370 llinfos << "Drawable: " << (LLDrawable *)mDrawable << llendl;
00371 llinfos << "Update Age: " << LLFrameTimer::getElapsedSeconds() - mLastMessageUpdateSecs << llendl;
00372
00373 llinfos << "Parent: " << getParent() << llendl;
00374 llinfos << "ID: " << mID << llendl;
00375 llinfos << "LocalID: " << mLocalID << llendl;
00376 llinfos << "PositionRegion: " << getPositionRegion() << llendl;
00377 llinfos << "PositionAgent: " << getPositionAgent() << llendl;
00378 llinfos << "PositionGlobal: " << getPositionGlobal() << llendl;
00379 llinfos << "Velocity: " << getVelocity() << llendl;
00380 if (mDrawable.notNull() && mDrawable->getNumFaces())
00381 {
00382 LLFacePool *poolp = mDrawable->getFace(0)->getPool();
00383 if (poolp)
00384 {
00385 llinfos << "Pool: " << poolp << llendl;
00386 llinfos << "Pool reference count: " << poolp->mReferences.size() << llendl;
00387 }
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 }
00416
00417 void LLViewerObject::printNameValuePairs() const
00418 {
00419 for (name_value_map_t::const_iterator iter = mNameValuePairs.begin();
00420 iter != mNameValuePairs.end(); iter++)
00421 {
00422 LLNameValue* nv = iter->second;
00423 llinfos << nv->printNameValue() << llendl;
00424 }
00425 }
00426
00427 void LLViewerObject::initVOClasses()
00428 {
00429
00430 LLVOAvatar::initClass();
00431 LLVOTree::initClass();
00432 if (gNoRender)
00433 {
00434
00435 return;
00436 }
00437 llinfos << "Viewer Object size: " << sizeof(LLViewerObject) << llendl;
00438 LLVOGrass::initClass();
00439 LLVOWater::initClass();
00440 LLVOSky::initClass();
00441 LLVOVolume::initClass();
00442 }
00443
00444 void LLViewerObject::cleanupVOClasses()
00445 {
00446 LLVOGrass::cleanupClass();
00447 LLVOWater::cleanupClass();
00448 LLVOTree::cleanupClass();
00449 LLVOAvatar::cleanupClass();
00450 }
00451
00452
00453
00454 void LLViewerObject::setNameValueList(const std::string& name_value_list)
00455 {
00456
00457 for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ;
00458 mNameValuePairs.clear();
00459
00460
00461 std::string::size_type length = name_value_list.length();
00462 std::string::size_type start = 0;
00463 while (start < length)
00464 {
00465 std::string::size_type end = name_value_list.find_first_of("\n", start);
00466 if (end == std::string::npos) end = length;
00467 if (end > start)
00468 {
00469 std::string tok = name_value_list.substr(start, end - start);
00470 addNVPair(tok.c_str());
00471 }
00472 start = end+1;
00473 }
00474 }
00475
00476
00477
00478
00479 BOOL LLViewerObject::isOverAgentOwnedLand() const
00480 {
00481 return mRegionp
00482 && mRegionp->getParcelOverlay()
00483 && mRegionp->getParcelOverlay()->isOwnedSelf(getPositionRegion());
00484 }
00485
00486
00487
00488 BOOL LLViewerObject::isOverGroupOwnedLand() const
00489 {
00490 return mRegionp
00491 && mRegionp->getParcelOverlay()
00492 && mRegionp->getParcelOverlay()->isOwnedGroup(getPositionRegion());
00493 }
00494
00495 void LLViewerObject::setParent(LLViewerObject* parent)
00496 {
00497 LLPrimitive::setParent(parent);
00498 }
00499
00500 void LLViewerObject::addChild(LLViewerObject *childp)
00501 {
00502 BOOL result = TRUE;
00503
00504 for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
00505 {
00506 if (*i == childp)
00507 {
00508 return;
00509 }
00510 }
00511
00512 if (!isAvatar())
00513 {
00514
00515 childp->mbCanSelect = mbCanSelect;
00516 }
00517
00518 childp->setParent(this);
00519 mChildList.push_back(childp);
00520
00521 if (!result)
00522 {
00523 llwarns << "Failed to attach child " << childp->getID() << " to object " << getID() << llendl;
00524 removeChild(childp);
00525 if (mJointInfo)
00526 {
00527 delete mJointInfo;
00528 mJointInfo = NULL;
00529 }
00530 }
00531 }
00532
00533 void LLViewerObject::removeChild(LLViewerObject *childp)
00534 {
00535 for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
00536 {
00537 if (*i == childp)
00538 {
00539 if (!childp->isAvatar() && mDrawable.notNull() && mDrawable->isActive() && childp->mDrawable.notNull() && !isAvatar())
00540 {
00541 gPipeline.markRebuild(childp->mDrawable, LLDrawable::REBUILD_VOLUME);
00542 }
00543
00544 mChildList.erase(i);
00545 childp->setParent(NULL);
00546 break;
00547 }
00548 }
00549
00550 if (childp->isSelected())
00551 {
00552 LLSelectMgr::getInstance()->deselectObjectAndFamily(childp);
00553 BOOL add_to_end = TRUE;
00554 LLSelectMgr::getInstance()->selectObjectAndFamily(childp, add_to_end);
00555 }
00556 }
00557
00558 LLViewerObject::child_list_t& LLViewerObject::getChildren()
00559 {
00560 return mChildList;
00561 }
00562
00563 void LLViewerObject::addThisAndAllChildren(LLDynamicArray<LLViewerObject*>& objects)
00564 {
00565 objects.put(this);
00566 S32 count = mChildList.size();
00567 for(S32 i = 0; i < count; i++)
00568 {
00569 if (!mChildList[i]->isAvatar())
00570 {
00571 (mChildList[i])->addThisAndAllChildren(objects);
00572 }
00573 }
00574 }
00575
00576 void LLViewerObject::addThisAndNonJointChildren(LLDynamicArray<LLViewerObject*>& objects)
00577 {
00578 objects.put(this);
00579
00580 if (isAvatar())
00581 {
00582 return;
00583 }
00584 S32 count = mChildList.size();
00585 for(S32 i = 0; i < count; i++)
00586 {
00587 if ( (!mChildList[i]->isAvatar())
00588 && (!mChildList[i]->isJointChild()))
00589 {
00590 (mChildList[i])->addThisAndNonJointChildren(objects);
00591 }
00592 }
00593 }
00594
00595 BOOL LLViewerObject::isChild(LLViewerObject *childp) const
00596 {
00597 S32 count = mChildList.size();
00598 for(S32 i = 0; i < count; i++)
00599 {
00600 const LLViewerObject *testChildp = &(*mChildList[i]);
00601 if (testChildp == childp) return TRUE;
00602 }
00603 return FALSE;
00604 }
00605
00606
00607
00608 BOOL LLViewerObject::isSeat() const
00609 {
00610 S32 count = mChildList.size();
00611 for(S32 i = 0; i < count; i++)
00612 {
00613 const LLViewerObject *childp = &(*mChildList[i]);
00614 if (childp->isAvatar())
00615 {
00616 return TRUE;
00617 }
00618 }
00619 return FALSE;
00620
00621 }
00622
00623 BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp)
00624 {
00625 if (mDrawable.isNull())
00626 {
00627 return FALSE;
00628 }
00629
00630 LLDrawable* old_parent = mDrawable->mParent;
00631
00632 mDrawable->mParent = parentp;
00633
00634 BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL);
00635 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
00636 if( old_parent != parentp &&
00637 old_parent || (parentp && parentp->isActive()))
00638 {
00639
00640 gPipeline.markMoved(mDrawable, FALSE);
00641 }
00642 else if (!mDrawable->isAvatar())
00643 {
00644 mDrawable->updateXform(TRUE);
00645
00646
00647
00648
00649 }
00650
00651 return ret;
00652 }
00653
00654
00655 void LLViewerObject::hideExtraDisplayItems( BOOL hidden )
00656 {
00657 if( mPartSourcep.notNull() )
00658 {
00659 LLViewerPartSourceScript *partSourceScript = mPartSourcep.get();
00660 partSourceScript->setSuspended( hidden );
00661 }
00662
00663 if( mText.notNull() )
00664 {
00665 LLHUDText *hudText = mText.get();
00666 hudText->setHidden( hidden );
00667 }
00668
00669 if( mIcon.notNull() )
00670 {
00671 LLHUDIcon *hudIcon = mIcon.get();
00672 hudIcon->setHidden( hidden );
00673 }
00674 }
00675
00676
00677 U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
00678 void **user_data,
00679 U32 block_num,
00680 const EObjectUpdateType update_type,
00681 LLDataPacker *dp)
00682 {
00683 LLMemType mt(LLMemType::MTYPE_OBJECT);
00684 U32 retval = 0x0;
00685
00686
00687 U64 region_handle;
00688 mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
00689 mRegionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
00690 if (!mRegionp)
00691 {
00692 U32 x, y;
00693 from_region_handle(region_handle, &x, &y);
00694
00695 llerrs << "Object has invalid region " << x << ":" << y << "!" << llendl;
00696 return retval;
00697 }
00698
00699 U16 time_dilation16;
00700 mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16);
00701 F32 time_dilation = ((F32) time_dilation16) / 65535.f;
00702 mTimeDilation = time_dilation;
00703 mRegionp->setTimeDilation(time_dilation);
00704
00705
00706
00707 LLVector3 test_pos_parent = getPosition();
00708
00709 U8 data[60+16];
00710 #ifdef LL_BIG_ENDIAN
00711 U16 valswizzle[4];
00712 #endif
00713 U16 *val;
00714 const F32 size = LLWorld::getInstance()->getRegionWidthInMeters();
00715 const F32 MAX_HEIGHT = LLWorld::getInstance()->getRegionMaxHeight();
00716 const F32 MIN_HEIGHT = LLWorld::getInstance()->getRegionMinHeight();
00717 S32 length;
00718 S32 count;
00719 S32 this_update_precision = 32;
00720
00721
00722 LLVector3 new_pos_parent;
00723 LLVector3 new_vel;
00724 LLVector3 new_acc;
00725 LLVector3 new_angv;
00726 LLVector3 old_angv = getAngularVelocity();
00727 LLQuaternion new_rot;
00728 LLVector3 new_scale = getScale();
00729
00730 U32 parent_id = 0;
00731 U8 material = 0;
00732 U8 click_action = 0;
00733 U32 crc = 0;
00734
00735 bool old_special_hover_cursor = specialHoverCursor();
00736
00737 LLViewerObject *cur_parentp = (LLViewerObject *)getParent();
00738
00739 if (cur_parentp)
00740 {
00741 parent_id = cur_parentp->mLocalID;
00742 }
00743
00744 if (!dp)
00745 {
00746 switch(update_type)
00747 {
00748 case OUT_FULL:
00749 {
00750 #ifdef DEBUG_UPDATE_TYPE
00751 llinfos << "Full:" << getID() << llendl;
00752 #endif
00753 LLUUID audio_uuid;
00754 LLUUID owner_id;
00755 F32 gain;
00756 U8 sound_flags;
00757
00758 mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_CRC, crc, block_num);
00759 mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_ParentID, parent_id, block_num);
00760 mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_Sound, audio_uuid, block_num );
00761
00762 mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, block_num );
00763 mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Gain, gain, block_num );
00764 mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Flags, sound_flags, block_num );
00765 mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Material, material, block_num );
00766 mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_ClickAction, click_action, block_num);
00767 mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_Scale, new_scale, block_num );
00768 length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);
00769 mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num);
00770
00771 mTotalCRC = crc;
00772
00773
00774 setAttachedSound(audio_uuid, owner_id, gain, sound_flags);
00775
00776 U8 old_material = getMaterial();
00777 if (old_material != material)
00778 {
00779 setMaterial(material);
00780 if (mDrawable.notNull())
00781 {
00782 gPipeline.markMoved(mDrawable, FALSE);
00783 }
00784 }
00785 setClickAction(click_action);
00786
00787 count = 0;
00788 LLVector4 collision_plane;
00789
00790 switch(length)
00791 {
00792 case (60 + 16):
00793
00794 htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
00795 ((LLVOAvatar*)this)->setFootPlane(collision_plane);
00796 count += sizeof(LLVector4);
00797 case 60:
00798 this_update_precision = 32;
00799
00800
00801 htonmemcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
00802 count += sizeof(LLVector3);
00803
00804 htonmemcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
00805 count += sizeof(LLVector3);
00806
00807 htonmemcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
00808 count += sizeof(LLVector3);
00809
00810 {
00811 LLVector3 vec;
00812 htonmemcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
00813 new_rot.unpackFromVector3(vec);
00814 }
00815 count += sizeof(LLVector3);
00816
00817 htonmemcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
00818 if (new_angv.isExactlyZero())
00819 {
00820
00821 resetRot();
00822 }
00823 setAngularVelocity(new_angv);
00824 #if LL_DARWIN
00825 if (length == 76)
00826 {
00827 setAngularVelocity(LLVector3::zero);
00828 }
00829 #endif
00830 break;
00831 case(32 + 16):
00832
00833 htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
00834 ((LLVOAvatar*)this)->setFootPlane(collision_plane);
00835 count += sizeof(LLVector4);
00836 case 32:
00837 this_update_precision = 16;
00838 test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
00839
00840
00841 #ifdef LL_BIG_ENDIAN
00842 htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
00843 val = valswizzle;
00844 #else
00845 val = (U16 *) &data[count];
00846 #endif
00847 count += sizeof(U16)*3;
00848 new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size);
00849 new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size);
00850 new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
00851
00852 #ifdef LL_BIG_ENDIAN
00853 htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
00854 val = valswizzle;
00855 #else
00856 val = (U16 *) &data[count];
00857 #endif
00858 count += sizeof(U16)*3;
00859 setVelocity(LLVector3(U16_to_F32(val[VX], -size, size),
00860 U16_to_F32(val[VY], -size, size),
00861 U16_to_F32(val[VZ], -size, size)));
00862
00863 #ifdef LL_BIG_ENDIAN
00864 htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
00865 val = valswizzle;
00866 #else
00867 val = (U16 *) &data[count];
00868 #endif
00869 count += sizeof(U16)*3;
00870 setAcceleration(LLVector3(U16_to_F32(val[VX], -size, size),
00871 U16_to_F32(val[VY], -size, size),
00872 U16_to_F32(val[VZ], -size, size)));
00873
00874 #ifdef LL_BIG_ENDIAN
00875 htonmemcpy(valswizzle, &data[count], MVT_U16Quat, 4);
00876 val = valswizzle;
00877 #else
00878 val = (U16 *) &data[count];
00879 #endif
00880 count += sizeof(U16)*4;
00881 new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
00882 new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
00883 new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
00884 new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
00885
00886 #ifdef LL_BIG_ENDIAN
00887 htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
00888 val = valswizzle;
00889 #else
00890 val = (U16 *) &data[count];
00891 #endif
00892 new_angv.setVec(U16_to_F32(val[VX], -size, size),
00893 U16_to_F32(val[VY], -size, size),
00894 U16_to_F32(val[VZ], -size, size));
00895 if (new_angv.isExactlyZero())
00896 {
00897
00898 resetRot();
00899 }
00900 setAngularVelocity(new_angv);
00901 break;
00902
00903 case 16:
00904 this_update_precision = 8;
00905 test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
00906
00907 new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size);
00908 new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size);
00909 new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT);
00910
00911 setVelocity(U8_to_F32(data[3], -size, size),
00912 U8_to_F32(data[4], -size, size),
00913 U8_to_F32(data[5], -size, size) );
00914
00915 setAcceleration(U8_to_F32(data[6], -size, size),
00916 U8_to_F32(data[7], -size, size),
00917 U8_to_F32(data[8], -size, size) );
00918
00919 new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f);
00920 new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f);
00921 new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
00922 new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
00923
00924 new_angv.setVec(U8_to_F32(data[13], -size, size),
00925 U8_to_F32(data[14], -size, size),
00926 U8_to_F32(data[15], -size, size) );
00927 if (new_angv.isExactlyZero())
00928 {
00929
00930 resetRot();
00931 }
00932 setAngularVelocity(new_angv);
00933 break;
00934 }
00935
00937
00938
00939
00940
00941 U32 flags;
00942 mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
00943
00944 mFlags &= FLAGS_LOCAL;
00945 mFlags |= flags;
00946
00947 U8 state;
00948 mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
00949 mState = state;
00950
00951
00952 mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
00953
00954
00955 S32 nv_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_NameValue);
00956 if (nv_size > 0)
00957 {
00958 char* name_value_list = new char[nv_size];
00959 mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_NameValue, nv_size, name_value_list, block_num);
00960
00961 setNameValueList(name_value_list);
00962
00963 delete [] name_value_list;
00964 }
00965
00966
00967 if (mData)
00968 {
00969 delete [] mData;
00970 }
00971
00972
00973 S32 data_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Data);
00974 if (data_size <= 0)
00975 {
00976 mData = NULL;
00977 }
00978 else
00979 {
00980
00981 mData = new U8[data_size];
00982 mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, mData, data_size, block_num);
00983 }
00984
00985 S32 text_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Text);
00986 if (text_size > 1)
00987 {
00988
00989 if (!mText)
00990 {
00991 mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
00992 mText->setFont(LLFontGL::sSansSerif);
00993 mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
00994 mText->setMaxLines(-1);
00995 mText->setSourceObject(this);
00996 mText->setOnHUDAttachment(isHUDAttachment());
00997 }
00998
00999 char temp_string[256];
01000 mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_Text, 256, temp_string, block_num );
01001
01002 LLColor4U coloru;
01003 mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextColor, coloru.mV, 4, block_num);
01004
01005
01006 coloru.mV[3] = 255 - coloru.mV[3];
01007 mText->setColor(LLColor4(coloru));
01008 mText->setStringUTF8(temp_string);
01009
01010 if (mDrawable.notNull())
01011 {
01012 setChanged(MOVED | SILHOUETTE);
01013 gPipeline.markMoved(mDrawable, FALSE);
01014 }
01015 }
01016 else if (mText.notNull())
01017 {
01018 mText->markDead();
01019 mText = NULL;
01020 }
01021
01022 char media_url[MAX_STRING+1];
01023 mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_MediaURL, MAX_STRING+1, media_url, block_num);
01024
01025
01026
01027
01028 if (!mMedia && media_url[0] != '\0')
01029 {
01030 retval |= MEDIA_URL_ADDED;
01031 mMedia = new LLViewerObjectMedia;
01032 mMedia->mMediaURL = media_url;
01033 mMedia->mMediaType = LLViewerObject::MEDIA_TYPE_WEB_PAGE;
01034 mMedia->mPassedWhitelist = FALSE;
01035 }
01036 else if (mMedia)
01037 {
01038 if (media_url[0] == '\0')
01039 {
01040 retval |= MEDIA_URL_REMOVED;
01041 delete mMedia;
01042 mMedia = NULL;
01043 }
01044 else if (mMedia->mMediaURL != media_url)
01045 {
01046
01047 retval |= MEDIA_URL_UPDATED;
01048 mMedia->mMediaURL = media_url;
01049 mMedia->mPassedWhitelist = FALSE;
01050 }
01051 }
01052
01053
01054
01055
01056 unpackParticleSource(block_num, owner_id);
01057
01058
01059 std::map<U16, ExtraParameter*>::iterator iter;
01060 for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
01061 {
01062 iter->second->in_use = FALSE;
01063 }
01064
01065
01066 S32 size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ExtraParams);
01067 if (size > 0)
01068 {
01069 U8 *buffer = new U8[size];
01070 mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ExtraParams, buffer, size, block_num);
01071 LLDataPackerBinaryBuffer dp(buffer, size);
01072
01073 U8 num_parameters;
01074 dp.unpackU8(num_parameters, "num_params");
01075 U8 param_block[MAX_OBJECT_PARAMS_SIZE];
01076 for (U8 param=0; param<num_parameters; ++param)
01077 {
01078 U16 param_type;
01079 S32 param_size;
01080 dp.unpackU16(param_type, "param_type");
01081 dp.unpackBinaryData(param_block, param_size, "param_data");
01082
01083 LLDataPackerBinaryBuffer dp2(param_block, param_size);
01084 unpackParameterEntry(param_type, &dp2);
01085 }
01086 delete[] buffer;
01087 }
01088
01089 for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
01090 {
01091 if (!iter->second->in_use)
01092 {
01093
01094 parameterChanged(iter->first, iter->second->data, FALSE, false);
01095 }
01096 }
01097
01098 U8 joint_type = 0;
01099 mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_JointType, joint_type, block_num);
01100 if (joint_type)
01101 {
01102
01103 if (!mJointInfo)
01104 {
01105 mJointInfo = new LLVOJointInfo;
01106 }
01107 mJointInfo->mJointType = (EHavokJointType) joint_type;
01108 mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_JointPivot, mJointInfo->mPivot, block_num);
01109 mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_JointAxisOrAnchor, mJointInfo->mAxisOrAnchor, block_num);
01110 }
01111 else if (mJointInfo)
01112 {
01113
01114 delete mJointInfo;
01115 mJointInfo = NULL;
01116 }
01117
01118 break;
01119 }
01120
01121 case OUT_TERSE_IMPROVED:
01122 {
01123 #ifdef DEBUG_UPDATE_TYPE
01124 llinfos << "TI:" << getID() << llendl;
01125 #endif
01126 length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);
01127 mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num);
01128 count = 0;
01129 LLVector4 collision_plane;
01130
01131 switch(length)
01132 {
01133 case(60 + 16):
01134
01135 htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
01136 ((LLVOAvatar*)this)->setFootPlane(collision_plane);
01137 count += sizeof(LLVector4);
01138 case 60:
01139
01140
01141 this_update_precision = 32;
01142 htonmemcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
01143 count += sizeof(LLVector3);
01144
01145 htonmemcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
01146 count += sizeof(LLVector3);
01147
01148 htonmemcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
01149 count += sizeof(LLVector3);
01150
01151 {
01152 LLVector3 vec;
01153 htonmemcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
01154 new_rot.unpackFromVector3(vec);
01155 }
01156 count += sizeof(LLVector3);
01157
01158 htonmemcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
01159 if (new_angv.isExactlyZero())
01160 {
01161
01162 resetRot();
01163 }
01164 setAngularVelocity(new_angv);
01165 #if LL_DARWIN
01166 if (length == 76)
01167 {
01168 setAngularVelocity(LLVector3::zero);
01169 }
01170 #endif
01171 break;
01172 case(32 + 16):
01173
01174 htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
01175 ((LLVOAvatar*)this)->setFootPlane(collision_plane);
01176 count += sizeof(LLVector4);
01177 case 32:
01178
01179 this_update_precision = 16;
01180 test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
01181
01182 #ifdef LL_BIG_ENDIAN
01183 htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
01184 val = valswizzle;
01185 #else
01186 val = (U16 *) &data[count];
01187 #endif
01188 count += sizeof(U16)*3;
01189 new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size);
01190 new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size);
01191 new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
01192
01193 #ifdef LL_BIG_ENDIAN
01194 htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
01195 val = valswizzle;
01196 #else
01197 val = (U16 *) &data[count];
01198 #endif
01199 count += sizeof(U16)*3;
01200 setVelocity(U16_to_F32(val[VX], -size, size),
01201 U16_to_F32(val[VY], -size, size),
01202 U16_to_F32(val[VZ], -size, size));
01203
01204 #ifdef LL_BIG_ENDIAN
01205 htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
01206 val = valswizzle;
01207 #else
01208 val = (U16 *) &data[count];
01209 #endif
01210 count += sizeof(U16)*3;
01211 setAcceleration(U16_to_F32(val[VX], -size, size),
01212 U16_to_F32(val[VY], -size, size),
01213 U16_to_F32(val[VZ], -size, size));
01214
01215 #ifdef LL_BIG_ENDIAN
01216 htonmemcpy(valswizzle, &data[count], MVT_U16Quat, 8);
01217 val = valswizzle;
01218 #else
01219 val = (U16 *) &data[count];
01220 #endif
01221 count += sizeof(U16)*4;
01222 new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
01223 new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
01224 new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
01225 new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
01226
01227 #ifdef LL_BIG_ENDIAN
01228 htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
01229 val = valswizzle;
01230 #else
01231 val = (U16 *) &data[count];
01232 #endif
01233 setAngularVelocity( U16_to_F32(val[VX], -size, size),
01234 U16_to_F32(val[VY], -size, size),
01235 U16_to_F32(val[VZ], -size, size));
01236 break;
01237
01238 case 16:
01239
01240 this_update_precision = 8;
01241 test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
01242 new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size);
01243 new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size);
01244 new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT);
01245
01246 setVelocity(U8_to_F32(data[3], -size, size),
01247 U8_to_F32(data[4], -size, size),
01248 U8_to_F32(data[5], -size, size) );
01249
01250 setAcceleration(U8_to_F32(data[6], -size, size),
01251 U8_to_F32(data[7], -size, size),
01252 U8_to_F32(data[8], -size, size) );
01253
01254 new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f);
01255 new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f);
01256 new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
01257 new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
01258
01259 setAngularVelocity( U8_to_F32(data[13], -size, size),
01260 U8_to_F32(data[14], -size, size),
01261 U8_to_F32(data[15], -size, size) );
01262 break;
01263 }
01264
01265 U8 state;
01266 mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
01267 mState = state;
01268 break;
01269 }
01270
01271 default:
01272 break;
01273
01274 }
01275 }
01276 else
01277 {
01278
01279 LLUUID sound_uuid;
01280 LLUUID owner_id;
01281 F32 gain = 0;
01282 U8 sound_flags = 0;
01283 F32 cutoff = 0;
01284
01285 U16 val[4];
01286
01287 U8 state;
01288
01289 dp->unpackU8(state, "State");
01290 mState = state;
01291
01292 switch(update_type)
01293 {
01294 case OUT_TERSE_IMPROVED:
01295 {
01296 #ifdef DEBUG_UPDATE_TYPE
01297 llinfos << "CompTI:" << getID() << llendl;
01298 #endif
01299 U8 value;
01300 dp->unpackU8(value, "agent");
01301 if (value)
01302 {
01303 LLVector4 collision_plane;
01304 dp->unpackVector4(collision_plane, "Plane");
01305 ((LLVOAvatar*)this)->setFootPlane(collision_plane);
01306 }
01307 test_pos_parent = getPosition();
01308 dp->unpackVector3(new_pos_parent, "Pos");
01309 dp->unpackU16(val[VX], "VelX");
01310 dp->unpackU16(val[VY], "VelY");
01311 dp->unpackU16(val[VZ], "VelZ");
01312 setVelocity(U16_to_F32(val[VX], -128.f, 128.f),
01313 U16_to_F32(val[VY], -128.f, 128.f),
01314 U16_to_F32(val[VZ], -128.f, 128.f));
01315 dp->unpackU16(val[VX], "AccX");
01316 dp->unpackU16(val[VY], "AccY");
01317 dp->unpackU16(val[VZ], "AccZ");
01318 setAcceleration(U16_to_F32(val[VX], -64.f, 64.f),
01319 U16_to_F32(val[VY], -64.f, 64.f),
01320 U16_to_F32(val[VZ], -64.f, 64.f));
01321
01322 dp->unpackU16(val[VX], "ThetaX");
01323 dp->unpackU16(val[VY], "ThetaY");
01324 dp->unpackU16(val[VZ], "ThetaZ");
01325 dp->unpackU16(val[VS], "ThetaS");
01326 new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
01327 new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
01328 new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
01329 new_rot.mQ[VS] = U16_to_F32(val[VS], -1.f, 1.f);
01330 dp->unpackU16(val[VX], "AccX");
01331 dp->unpackU16(val[VY], "AccY");
01332 dp->unpackU16(val[VZ], "AccZ");
01333 setAngularVelocity( U16_to_F32(val[VX], -64.f, 64.f),
01334 U16_to_F32(val[VY], -64.f, 64.f),
01335 U16_to_F32(val[VZ], -64.f, 64.f));
01336 }
01337 break;
01338 case OUT_FULL_COMPRESSED:
01339 case OUT_FULL_CACHED:
01340 {
01341 #ifdef DEBUG_UPDATE_TYPE
01342 llinfos << "CompFull:" << getID() << llendl;
01343 #endif
01344 dp->unpackU32(crc, "CRC");
01345 mTotalCRC = crc;
01346 dp->unpackU8(material, "Material");
01347 U8 old_material = getMaterial();
01348 if (old_material != material)
01349 {
01350 setMaterial(material);
01351 if (mDrawable.notNull())
01352 {
01353 gPipeline.markMoved(mDrawable, FALSE);
01354 }
01355 }
01356 dp->unpackU8(click_action, "ClickAction");
01357 setClickAction(click_action);
01358 dp->unpackVector3(new_scale, "Scale");
01359 dp->unpackVector3(new_pos_parent, "Pos");
01360 LLVector3 vec;
01361 dp->unpackVector3(vec, "Rot");
01362 new_rot.unpackFromVector3(vec);
01363 setAcceleration(LLVector3::zero);
01364
01365 U32 value;
01366 dp->unpackU32(value, "SpecialCode");
01367 dp->setPassFlags(value);
01368 dp->unpackUUID(owner_id, "Owner");
01369
01370 if (value & 0x80)
01371 {
01372 dp->unpackVector3(vec, "Omega");
01373 setAngularVelocity(vec);
01374 }
01375
01376 if (value & 0x20)
01377 {
01378 dp->unpackU32(parent_id, "ParentID");
01379 }
01380 else
01381 {
01382 parent_id = 0;
01383 }
01384
01385 S32 sp_size;
01386 U32 size;
01387 if (value & 0x2)
01388 {
01389 sp_size = 1;
01390 delete [] mData;
01391 mData = new U8[1];
01392 dp->unpackU8(((U8*)mData)[0], "TreeData");
01393 }
01394 else if (value & 0x1)
01395 {
01396 dp->unpackU32(size, "ScratchPadSize");
01397 delete [] mData;
01398 mData = new U8[size];
01399 dp->unpackBinaryData((U8 *)mData, sp_size, "PartData");
01400 }
01401 else
01402 {
01403 mData = NULL;
01404 }
01405
01406
01407 if (!mText)
01408 {
01409 mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
01410 mText->setFont(LLFontGL::sSansSerif);
01411 mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
01412 mText->setMaxLines(-1);
01413 mText->setSourceObject(this);
01414 mText->setOnHUDAttachment(isHUDAttachment());
01415 }
01416
01417 if (value & 0x4)
01418 {
01419 std::string temp_string;
01420 dp->unpackString(temp_string, "Text");
01421 LLColor4U coloru;
01422 dp->unpackBinaryDataFixed(coloru.mV, 4, "Color");
01423 coloru.mV[3] = 255 - coloru.mV[3];
01424 mText->setColor(LLColor4(coloru));
01425 mText->setStringUTF8(temp_string);
01426
01427 setChanged(TEXTURE);
01428 }
01429 else
01430 {
01431 mText->markDead();
01432 mText = NULL;
01433 }
01434
01435 if (value & 0x200)
01436 {
01437 std::string media_url;
01438 dp->unpackString(media_url, "MediaURL");
01439 if (!mMedia)
01440 {
01441 retval |= MEDIA_URL_ADDED;
01442 mMedia = new LLViewerObjectMedia;
01443 mMedia->mMediaURL = media_url;
01444 mMedia->mMediaType = LLViewerObject::MEDIA_TYPE_WEB_PAGE;
01445 mMedia->mPassedWhitelist = FALSE;
01446 }
01447 else if (mMedia->mMediaURL != media_url)
01448 {
01449 retval |= MEDIA_URL_UPDATED;
01450 mMedia->mMediaURL = media_url;
01451 mMedia->mPassedWhitelist = FALSE;
01452 }
01453 }
01454 else if (mMedia)
01455 {
01456 retval |= MEDIA_URL_REMOVED;
01457 delete mMedia;
01458 mMedia = NULL;
01459 }
01460
01461
01462
01463
01464 if (value & 0x8)
01465 {
01466 unpackParticleSource(*dp, owner_id);
01467 }
01468 else
01469 {
01470 deleteParticleSource();
01471 }
01472
01473
01474 std::map<U16, ExtraParameter*>::iterator iter;
01475 for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
01476 {
01477 iter->second->in_use = FALSE;
01478 }
01479
01480
01481 U8 num_parameters;
01482 dp->unpackU8(num_parameters, "num_params");
01483 U8 param_block[MAX_OBJECT_PARAMS_SIZE];
01484 for (U8 param=0; param<num_parameters; ++param)
01485 {
01486 U16 param_type;
01487 S32 param_size;
01488 dp->unpackU16(param_type, "param_type");
01489 dp->unpackBinaryData(param_block, param_size, "param_data");
01490
01491 LLDataPackerBinaryBuffer dp2(param_block, param_size);
01492 unpackParameterEntry(param_type, &dp2);
01493 }
01494
01495 for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
01496 {
01497 if (!iter->second->in_use)
01498 {
01499
01500 parameterChanged(iter->first, iter->second->data, FALSE, false);
01501 }
01502 }
01503
01504 if (value & 0x10)
01505 {
01506 dp->unpackUUID(sound_uuid, "SoundUUID");
01507 dp->unpackF32(gain, "SoundGain");
01508 dp->unpackU8(sound_flags, "SoundFlags");
01509 dp->unpackF32(cutoff, "SoundRadius");
01510 }
01511
01512 if (value & 0x100)
01513 {
01514 std::string name_value_list;
01515 dp->unpackString(name_value_list, "NV");
01516
01517 setNameValueList(name_value_list.c_str());
01518 }
01519
01520 mTotalCRC = crc;
01521
01522 setAttachedSound(sound_uuid, owner_id, gain, sound_flags);
01523
01524
01525
01526
01527
01528 U32 flags;
01529 mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
01530
01531 mFlags = (mFlags & FLAGS_LOCAL) | flags;
01532
01533
01534 mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
01535 }
01536 break;
01537
01538 default:
01539 break;
01540 }
01541 }
01542
01543
01544
01545
01546 BOOL b_changed_status = FALSE;
01547
01548 if (OUT_TERSE_IMPROVED != update_type)
01549 {
01550
01551
01552 if (!cur_parentp)
01553 {
01554 if (parent_id == 0)
01555 {
01556
01557 }
01558 else
01559 {
01560
01561 LLUUID parent_uuid;
01562 LLViewerObjectList::getUUIDFromLocal(parent_uuid,
01563 parent_id,
01564 mesgsys->getSenderIP(),
01565 mesgsys->getSenderPort());
01566
01567 LLViewerObject *sent_parentp = gObjectList.findObject(parent_uuid);
01568
01569
01570
01571
01572 if (sent_parentp && sent_parentp->getParent() == this)
01573 {
01574
01575 llwarns << "Attempt to attach a parent to it's child: " << this->getID() << " to " << sent_parentp->getID() << llendl;
01576 this->removeChild(sent_parentp);
01577 sent_parentp->setDrawableParent(NULL);
01578 }
01579
01580 if (sent_parentp && (sent_parentp != this) && !sent_parentp->isDead())
01581 {
01582
01583
01584
01585
01586
01587
01588 b_changed_status = TRUE;
01589
01590 if (mDrawable.notNull())
01591 {
01592 if (mDrawable->isDead() || !mDrawable->getVObj())
01593 {
01594 llwarns << "Drawable is dead or no VObj!" << llendl;
01595 sent_parentp->addChild(this);
01596 }
01597 else
01598 {
01599 if (!setDrawableParent(sent_parentp->mDrawable))
01600 {
01601
01602
01603
01604 llwarns << "Attempting to recover from parenting cycle!" << llendl;
01605 llwarns << "Killing " << sent_parentp->getID() << " and " << getID() << llendl;
01606 llwarns << "Adding to cache miss list" << llendl;
01607 setParent(NULL);
01608 sent_parentp->setParent(NULL);
01609 getRegion()->addCacheMissFull(getLocalID());
01610 getRegion()->addCacheMissFull(sent_parentp->getLocalID());
01611 gObjectList.killObject(sent_parentp);
01612 gObjectList.killObject(this);
01613 return retval;
01614 }
01615 sent_parentp->addChild(this);
01616
01617 if (sent_parentp->mDrawable.notNull())
01618 {
01619 gPipeline.markMoved(sent_parentp->mDrawable, FALSE);
01620 }
01621 }
01622 }
01623 else
01624 {
01625 sent_parentp->addChild(this);
01626 }
01627
01628
01629 hideExtraDisplayItems( FALSE );
01630
01631 setChanged(MOVED | SILHOUETTE);
01632 }
01633 else
01634 {
01635
01636
01637
01638
01639
01640
01641 U32 ip = mesgsys->getSenderIP();
01642 U32 port = mesgsys->getSenderPort();
01643
01644 gObjectList.orphanize(this, parent_id, ip, port);
01645
01646
01647 hideExtraDisplayItems( TRUE );
01648 }
01649 }
01650 }
01651 else
01652 {
01653
01654 if ( (parent_id == cur_parentp->mLocalID)
01655 &&(update_type == OUT_TERSE_IMPROVED))
01656 {
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666 }
01667 else
01668 {
01669
01670 LLViewerObject *sent_parentp;
01671 if (parent_id == 0)
01672 {
01673
01674
01675
01676 sent_parentp = NULL;
01677 }
01678 else
01679 {
01680 LLUUID parent_uuid;
01681 LLViewerObjectList::getUUIDFromLocal(parent_uuid,
01682 parent_id,
01683 gMessageSystem->getSenderIP(),
01684 gMessageSystem->getSenderPort());
01685 sent_parentp = gObjectList.findObject(parent_uuid);
01686
01687 if (isAvatar())
01688 {
01689
01690
01691
01692
01693
01694
01695 if (!sent_parentp)
01696 {
01697 sent_parentp = cur_parentp;
01698 }
01699 }
01700 else if (!sent_parentp)
01701 {
01702
01703
01704
01705 U32 ip = mesgsys->getSenderIP();
01706 U32 port = mesgsys->getSenderPort();
01707
01708
01709 gObjectList.orphanize(this, parent_id, ip, port);
01710 }
01711 }
01712
01713
01714 if (sent_parentp && sent_parentp != cur_parentp && sent_parentp != this)
01715 {
01716
01717 b_changed_status = TRUE;
01718 if (mDrawable.notNull())
01719 {
01720 if (!setDrawableParent(sent_parentp->mDrawable))
01721 {
01722
01723
01724
01725 llwarns << "Attempting to recover from parenting cycle!" << llendl;
01726 llwarns << "Killing " << sent_parentp->getID() << " and " << getID() << llendl;
01727 llwarns << "Adding to cache miss list" << llendl;
01728 setParent(NULL);
01729 sent_parentp->setParent(NULL);
01730 getRegion()->addCacheMissFull(getLocalID());
01731 getRegion()->addCacheMissFull(sent_parentp->getLocalID());
01732 gObjectList.killObject(sent_parentp);
01733 gObjectList.killObject(this);
01734 return retval;
01735 }
01736
01737 }
01738 cur_parentp->removeChild(this);
01739 sent_parentp->addChild(this);
01740 setChanged(MOVED | SILHOUETTE);
01741 sent_parentp->setChanged(MOVED | SILHOUETTE);
01742 if (sent_parentp->mDrawable.notNull())
01743 {
01744 gPipeline.markMoved(sent_parentp->mDrawable, FALSE);
01745 }
01746 }
01747 else if (!sent_parentp)
01748 {
01749 bool remove_parent = true;
01750
01751 LLViewerObject *parentp = (LLViewerObject *)getParent();
01752 if (parentp)
01753 {
01754 if (parentp->getRegion() != getRegion())
01755 {
01756
01757
01758
01759
01760 remove_parent = false;
01761 }
01762 }
01763
01764 if (remove_parent)
01765 {
01766 b_changed_status = TRUE;
01767 if (mDrawable.notNull())
01768 {
01769
01770 setDrawableParent(NULL);
01771 }
01772
01773 cur_parentp->removeChild(this);
01774
01775 if (mJointInfo && !parent_id)
01776 {
01777
01778
01779 delete mJointInfo;
01780 mJointInfo = NULL;
01781 }
01782
01783 setChanged(MOVED | SILHOUETTE);
01784
01785 if (mDrawable.notNull())
01786 {
01787
01788 gPipeline.markMoved(mDrawable, FALSE);
01789 }
01790 }
01791 }
01792 }
01793 }
01794 }
01795
01796 new_rot.normQuat();
01797
01798 if (gPingInterpolate)
01799 {
01800 LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender());
01801 if (cdp)
01802 {
01803 F32 ping_delay = 0.5f * mTimeDilation * ( ((F32)cdp->getPingDelay()) * 0.001f + gFrameDTClamped);
01804 LLVector3 diff = getVelocity() * (0.5f*mTimeDilation*(gFrameDTClamped + ((F32)ping_delay)*0.001f));
01805 new_pos_parent += diff;
01806 }
01807 else
01808 {
01809 llwarns << "findCircuit() returned NULL; skipping interpolation" << llendl;
01810 }
01811 }
01812
01814
01815
01816
01817
01818
01819 U32 packet_id = mesgsys->getCurrentRecvPacketID();
01820 if (packet_id < mLatestRecvPacketID &&
01821 mLatestRecvPacketID - packet_id < 65536)
01822 {
01823
01824 return retval;
01825 }
01826
01827 mLatestRecvPacketID = packet_id;
01828
01829
01830 if (new_scale != getScale())
01831 {
01832 setChanged(SCALED | SILHOUETTE);
01833 setScale(new_scale);
01834 }
01835
01836
01837
01838
01839
01840 F32 vel_mag_sq = getVelocity().magVecSquared();
01841 F32 accel_mag_sq = getAcceleration().magVecSquared();
01842
01843 if ( ((b_changed_status)||(test_pos_parent != new_pos_parent))
01844 ||( (!isSelected())
01845 &&( (vel_mag_sq != 0.f)
01846 ||(accel_mag_sq != 0.f)
01847 ||(this_update_precision > mBestUpdatePrecision))))
01848 {
01849 mBestUpdatePrecision = this_update_precision;
01850 setPositionParent(new_pos_parent);
01851
01852 if (mParent && ((LLViewerObject*)mParent)->isAvatar())
01853 {
01854
01855 LLVOAvatar *avatar = (LLVOAvatar*)mParent;
01856
01857 avatar->clampAttachmentPositions();
01858 }
01859 }
01860
01861 if (new_rot != mLastRot
01862 || new_angv != old_angv)
01863 {
01864 if (new_rot != mLastRot)
01865 {
01866 mLastRot = new_rot;
01867 setRotation(new_rot);
01868 }
01869
01870 setChanged(ROTATED | SILHOUETTE);
01871
01872 resetRot();
01873 }
01874
01875
01876 if ( gShowObjectUpdates )
01877 {
01878 if (!((mPrimitiveCode == LL_PCODE_LEGACY_AVATAR) && (((LLVOAvatar *) this)->mIsSelf))
01879 && mRegionp)
01880 {
01881 LLViewerObject* object = gObjectList.createObjectViewer(LL_PCODE_LEGACY_TEXT_BUBBLE, mRegionp);
01882 LLVOTextBubble* bubble = (LLVOTextBubble*) object;
01883
01884 if (update_type == OUT_TERSE_IMPROVED)
01885 {
01886 bubble->mColor.setVec(0.f, 0.f, 1.f, 1.f);
01887 }
01888 else
01889 {
01890 bubble->mColor.setVec(1.f, 0.f, 0.f, 1.f);
01891 }
01892 object->setPositionGlobal(getPositionGlobal());
01893 gPipeline.addObject(object);
01894 }
01895 }
01896
01897 if ((0.0f == vel_mag_sq) &&
01898 (0.0f == accel_mag_sq) &&
01899 (0.0f == getAngularVelocity().magVecSquared()))
01900 {
01901 mStatic = TRUE;
01902 }
01903 else
01904 {
01905 mStatic = FALSE;
01906 }
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920 BOOL needs_refresh = mUserSelected;
01921 LLViewerObject *childp;
01922 for (U32 i = 0; i < mChildList.size(); i++)
01923 {
01924 childp = mChildList[i];
01925 needs_refresh = needs_refresh || childp->mUserSelected;
01926 }
01927
01928 if (needs_refresh)
01929 {
01930 LLSelectMgr::getInstance()->updateSelectionCenter();
01931 dialog_refresh_all();
01932 }
01933
01934
01935
01936
01937
01938
01939
01940 mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds();
01941 mLastMessageUpdateSecs = LLFrameTimer::getElapsedSeconds();
01942 if (mDrawable.notNull())
01943 {
01944
01945 if (mDrawable->isState(LLDrawable::FORCE_INVISIBLE) && !mOrphaned)
01946 {
01947
01948 mDrawable->setState(LLDrawable::CLEAR_INVISIBLE);
01949 }
01950 }
01951
01952
01953 bool special_hover_cursor = specialHoverCursor();
01954 if (old_special_hover_cursor != special_hover_cursor
01955 && mDrawable.notNull())
01956 {
01957 mDrawable->updateSpecialHoverCursor(special_hover_cursor);
01958 }
01959
01960 return retval;
01961 }
01962
01963 BOOL LLViewerObject::isActive() const
01964 {
01965 return TRUE;
01966 }
01967
01968 BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
01969 {
01970 if (mDead)
01971 {
01972
01973 return TRUE;
01974 }
01975
01976
01977
01978 if (!mStatic && gVelocityInterpolate && !isSelected())
01979 {
01980
01981 F32 dt_raw = (F32)(time - mLastInterpUpdateSecs);
01982 F32 dt = mTimeDilation * dt_raw;
01983
01984 if (!mJointInfo)
01985 {
01986 applyAngularVelocity(dt);
01987 }
01988
01989 LLViewerObject *parentp = (LLViewerObject *) getParent();
01990 if (mJointInfo)
01991 {
01992 if (parentp)
01993 {
01994
01995 LLVector3 ang_vel = getAngularVelocity();
01996 F32 omega = ang_vel.magVecSquared();
01997 F32 angle = 0.0f;
01998 LLQuaternion dQ;
01999 if (omega > 0.00001f)
02000 {
02001 omega = sqrt(omega);
02002 angle = omega * dt;
02003 dQ.setQuat(angle, ang_vel);
02004 }
02005 LLVector3 pos = getPosition();
02006
02007 if (HJT_HINGE == mJointInfo->mJointType)
02008 {
02009
02010 LLVector3 parent_pivot = getVelocity();
02011 LLVector3 parent_axis = getAcceleration();
02012
02013 angle = dt * (ang_vel * mJointInfo->mAxisOrAnchor);
02014 dQ.setQuat(angle, mJointInfo->mAxisOrAnchor);
02015 LLVector3 pivot_offset = pos - mJointInfo->mPivot;
02016 pivot_offset = pivot_offset * dQ;
02017 pos = mJointInfo->mPivot + pivot_offset;
02018 LLViewerObject::setPosition(pos);
02019 LLQuaternion Q_PC = getRotation();
02020 setRotation(Q_PC * dQ);
02021 mLastInterpUpdateSecs = time;
02022 }
02023 else if (HJT_POINT == mJointInfo->mJointType)
02024
02025 {
02026
02027
02028
02029
02030
02031
02032
02033 LLQuaternion Q_PC = getRotation();
02034 Q_PC = Q_PC * dQ;
02035 setRotation(Q_PC);
02036
02037 LLVector3 pivot_to_child = - mJointInfo->mAxisOrAnchor;
02038 pos = mJointInfo->mPivot + pivot_to_child * Q_PC;
02039 LLViewerObject::setPosition(pos);
02040 mLastInterpUpdateSecs = time;
02041 }
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060 }
02061 }
02062 else if (isAttachment())
02063 {
02064 mLastInterpUpdateSecs = time;
02065 return TRUE;
02066 }
02067 else
02068 {
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079 LLVector3 accel = getAcceleration();
02080 LLVector3 vel = getVelocity();
02081
02082 if (!(accel.isExactlyZero() && vel.isExactlyZero()))
02083 {
02084 LLVector3 pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;
02085
02086
02087 setPositionRegion(pos + getPositionRegion());
02088 setVelocity(vel + accel*dt);
02089
02090
02091 setChanged(MOVED | SILHOUETTE);
02092 }
02093
02094 mLastInterpUpdateSecs = time;
02095 }
02096 }
02097
02098 if (gNoRender)
02099 {
02100
02101 return TRUE;
02102 }
02103
02104 updateDrawable(FALSE);
02105
02106 return TRUE;
02107 }
02108
02109
02110 BOOL LLViewerObject::setData(const U8 *datap, const U32 data_size)
02111 {
02112 LLMemType mt(LLMemType::MTYPE_OBJECT);
02113
02114 delete [] mData;
02115
02116 if (datap)
02117 {
02118 mData = new U8[data_size];
02119 if (!mData)
02120 {
02121 return FALSE;
02122 }
02123 memcpy(mData, datap, data_size);
02124 }
02125 return TRUE;
02126 }
02127
02128
02129
02130
02131 void LLViewerObject::deleteInventoryItem(const LLUUID& item_id)
02132 {
02133 if(mInventory)
02134 {
02135 InventoryObjectList::iterator it = mInventory->begin();
02136 InventoryObjectList::iterator end = mInventory->end();
02137 for( ; it != end; ++it )
02138 {
02139 if((*it)->getUUID() == item_id)
02140 {
02141
02142 mInventory->erase(it);
02143 return;
02144 }
02145 }
02146 doInventoryCallback();
02147 }
02148 }
02149
02150 void LLViewerObject::doUpdateInventory(
02151 LLViewerInventoryItem* item,
02152 U8 key,
02153 bool is_new)
02154 {
02155 LLMemType mt(LLMemType::MTYPE_OBJECT);
02156
02157 LLViewerInventoryItem* old_item = NULL;
02158 if(TASK_INVENTORY_ITEM_KEY == key)
02159 {
02160 old_item = (LLViewerInventoryItem*)getInventoryObject(item->getUUID());
02161 }
02162 else if(TASK_INVENTORY_ASSET_KEY == key)
02163 {
02164 old_item = getInventoryItemByAsset(item->getAssetUUID());
02165 }
02166 LLUUID item_id;
02167 LLUUID new_owner;
02168 LLUUID new_group;
02169 BOOL group_owned = FALSE;
02170 if(old_item)
02171 {
02172 item_id = old_item->getUUID();
02173 new_owner = old_item->getPermissions().getOwner();
02174 new_group = old_item->getPermissions().getGroup();
02175 group_owned = old_item->getPermissions().isGroupOwned();
02176 old_item = NULL;
02177 }
02178 else
02179 {
02180 item_id = item->getUUID();
02181 }
02182 if(!is_new && mInventory)
02183 {
02184
02185
02186
02187
02188 deleteInventoryItem(item_id);
02189 LLPermissions perm(item->getPermissions());
02190 LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this);
02191 bool is_atomic = ((S32)LLAssetType::AT_OBJECT == item->getType()) ? false : true;
02192 if(obj_perm)
02193 {
02194 perm.setOwnerAndGroup(LLUUID::null, obj_perm->getOwner(), obj_perm->getGroup(), is_atomic);
02195 }
02196 else
02197 {
02198 if(group_owned)
02199 {
02200 perm.setOwnerAndGroup(LLUUID::null, new_owner, new_group, is_atomic);
02201 }
02202 else if(!new_owner.isNull())
02203 {
02204
02205
02206
02207 perm.setOwnerAndGroup(LLUUID::null, new_owner, new_group, is_atomic);
02208 }
02209
02210 else if(permYouOwner())
02211 {
02212
02213 perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), item->getPermissions().getGroup(), is_atomic);
02214 --mInventorySerialNum;
02215 }
02216 else
02217 {
02218
02219 perm.setOwnerAndGroup(LLUUID::null, LLUUID::null, LLUUID::null, is_atomic);
02220 --mInventorySerialNum;
02221 }
02222 }
02223 LLViewerInventoryItem* new_item = new LLViewerInventoryItem(item);
02224 new_item->setPermissions(perm);
02225 mInventory->push_front(new_item);
02226 doInventoryCallback();
02227 ++mInventorySerialNum;
02228 }
02229 }
02230
02231
02232
02233
02234 void LLViewerObject::saveScript(
02235 const LLViewerInventoryItem* item,
02236 BOOL active,
02237 bool is_new)
02238 {
02239 LLMemType mt(LLMemType::MTYPE_OBJECT);
02240
02241
02242
02243
02244
02245 lldebugs << "LLViewerObject::saveScript() " << item->getUUID() << " " << item->getAssetUUID() << llendl;
02246 LLPointer<LLViewerInventoryItem> task_item =
02247 new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
02248 item->getAssetUUID(), item->getType(),
02249 item->getInventoryType(),
02250 item->getName(), item->getDescription(),
02251 item->getSaleInfo(), item->getFlags(),
02252 item->getCreationDate());
02253 task_item->setTransactionID(item->getTransactionID());
02254
02255 LLMessageSystem* msg = gMessageSystem;
02256 msg->newMessageFast(_PREHASH_RezScript);
02257 msg->nextBlockFast(_PREHASH_AgentData);
02258 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
02259 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02260 msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
02261 msg->nextBlockFast(_PREHASH_UpdateBlock);
02262 msg->addU32Fast(_PREHASH_ObjectLocalID, (mLocalID));
02263 U8 enabled = active;
02264 msg->addBOOLFast(_PREHASH_Enabled, enabled);
02265 msg->nextBlockFast(_PREHASH_InventoryBlock);
02266 task_item->packMessage(msg);
02267 msg->sendReliable(mRegionp->getHost());
02268
02269
02270 doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, is_new);
02271 }
02272
02273 void LLViewerObject::moveInventory(const LLUUID& folder_id,
02274 const LLUUID& item_id)
02275 {
02276 lldebugs << "LLViewerObject::moveInventory " << item_id << llendl;
02277 LLMessageSystem* msg = gMessageSystem;
02278 msg->newMessageFast(_PREHASH_MoveTaskInventory);
02279 msg->nextBlockFast(_PREHASH_AgentData);
02280 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
02281 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02282 msg->addUUIDFast(_PREHASH_FolderID, folder_id);
02283 msg->nextBlockFast(_PREHASH_InventoryData);
02284 msg->addU32Fast(_PREHASH_LocalID, mLocalID);
02285 msg->addUUIDFast(_PREHASH_ItemID, item_id);
02286 msg->sendReliable(mRegionp->getHost());
02287
02288 LLInventoryObject* inv_obj = getInventoryObject(item_id);
02289 if(inv_obj)
02290 {
02291 LLViewerInventoryItem* item = (LLViewerInventoryItem*)inv_obj;
02292 if(!item->getPermissions().allowCopyBy(gAgent.getID()))
02293 {
02294 deleteInventoryItem(item_id);
02295 ++mInventorySerialNum;
02296 }
02297 }
02298 }
02299
02300 void LLViewerObject::dirtyInventory()
02301 {
02302
02303
02304
02305 if(mInventory && !mInventoryCallbacks.empty())
02306 {
02307 mInventory->clear();
02308 delete mInventory;
02309 mInventory = NULL;
02310 mInventoryDirty = TRUE;
02311 }
02312 }
02313
02314 void LLViewerObject::registerInventoryListener(LLVOInventoryListener* listener, void* user_data)
02315 {
02316 LLMemType mt(LLMemType::MTYPE_OBJECT);
02317
02318 LLInventoryCallbackInfo* info = new LLInventoryCallbackInfo;
02319 info->mListener = listener;
02320 info->mInventoryData = user_data;
02321 mInventoryCallbacks.push_front(info);
02322 }
02323
02324 void LLViewerObject::removeInventoryListener(LLVOInventoryListener* listener)
02325 {
02326 if (listener == NULL)
02327 return;
02328 for (callback_list_t::iterator iter = mInventoryCallbacks.begin();
02329 iter != mInventoryCallbacks.end(); )
02330 {
02331 callback_list_t::iterator curiter = iter++;
02332 LLInventoryCallbackInfo* info = *curiter;
02333 if (info->mListener == listener)
02334 {
02335 delete info;
02336 mInventoryCallbacks.erase(curiter);
02337 break;
02338 }
02339 }
02340 }
02341
02342 void LLViewerObject::clearInventoryListeners()
02343 {
02344 for_each(mInventoryCallbacks.begin(), mInventoryCallbacks.end(), DeletePointer());
02345 mInventoryCallbacks.clear();
02346 }
02347
02348 void LLViewerObject::requestInventory()
02349 {
02350 mInventoryDirty = FALSE;
02351 if(mInventory)
02352 {
02353
02354
02355
02356 doInventoryCallback();
02357 }
02358
02359 else
02360 {
02361 fetchInventoryFromServer();
02362 }
02363 }
02364
02365 void LLViewerObject::fetchInventoryFromServer()
02366 {
02367 if (!mInventoryPending)
02368 {
02369 delete mInventory;
02370 mInventory = NULL;
02371 mInventoryDirty = FALSE;
02372 LLMessageSystem* msg = gMessageSystem;
02373 msg->newMessageFast(_PREHASH_RequestTaskInventory);
02374 msg->nextBlockFast(_PREHASH_AgentData);
02375 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
02376 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02377 msg->nextBlockFast(_PREHASH_InventoryData);
02378 msg->addU32Fast(_PREHASH_LocalID, mLocalID);
02379 msg->sendReliable(mRegionp->getHost());
02380
02381
02382 mInventoryPending = TRUE;
02383 }
02384 }
02385
02386 struct LLFilenameAndTask
02387 {
02388 LLUUID mTaskID;
02389 char mFilename[MAX_STRING];
02390 #ifdef _DEBUG
02391 static S32 sCount;
02392 LLFilenameAndTask()
02393 {
02394 ++sCount;
02395 lldebugs << "Constructing LLFilenameAndTask: " << sCount << llendl;
02396 }
02397 ~LLFilenameAndTask()
02398 {
02399 --sCount;
02400 lldebugs << "Destroying LLFilenameAndTask: " << sCount << llendl;
02401 }
02402 private:
02403 LLFilenameAndTask(const LLFilenameAndTask& rhs);
02404 const LLFilenameAndTask& operator=(const LLFilenameAndTask& rhs) const;
02405 #endif
02406 };
02407
02408 #ifdef _DEBUG
02409 S32 LLFilenameAndTask::sCount = 0;
02410 #endif
02411
02412
02413 void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
02414 {
02415 LLMemType mt(LLMemType::MTYPE_OBJECT);
02416
02417 LLUUID task_id;
02418 msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_TaskID, task_id);
02419 LLViewerObject* object = gObjectList.findObject(task_id);
02420 if(!object)
02421 {
02422 llwarns << "LLViewerObject::processTaskInv object "
02423 << task_id << " does not exist." << llendl;
02424 return;
02425 }
02426
02427 msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, object->mInventorySerialNum);
02428 LLFilenameAndTask* ft = new LLFilenameAndTask;
02429 ft->mTaskID = task_id;
02430 msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, MAX_STRING, ft->mFilename);
02431 if(!ft->mFilename[0])
02432 {
02433 lldebugs << "Task has no inventory" << llendl;
02434
02435 if(object->mInventory)
02436 {
02437 object->mInventory->clear();
02438 }
02439 else
02440 {
02441 object->mInventory = new InventoryObjectList();
02442 }
02443 LLPointer<LLInventoryObject> obj;
02444 obj = new LLInventoryObject(object->mID, LLUUID::null,
02445 LLAssetType::AT_CATEGORY,
02446 "Contents");
02447 object->mInventory->push_front(obj);
02448 object->doInventoryCallback();
02449 delete ft;
02450 return;
02451 }
02452 gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename).c_str(),
02453 ft->mFilename, LL_PATH_CACHE,
02454 object->mRegionp->getHost(),
02455 TRUE,
02456 &LLViewerObject::processTaskInvFile,
02457 (void**)ft,
02458 LLXferManager::HIGH_PRIORITY);
02459 }
02460
02461 void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status)
02462 {
02463 LLFilenameAndTask* ft = (LLFilenameAndTask*)user_data;
02464 LLViewerObject* object = NULL;
02465 if(ft && (0 == error_code) &&
02466 (object = gObjectList.findObject(ft->mTaskID)))
02467 {
02468 object->loadTaskInvFile(ft->mFilename);
02469 }
02470 else
02471 {
02472
02473
02474 lldebugs << "Problem loading task inventory. Return code: "
02475 << error_code << llendl;
02476 }
02477 delete ft;
02478 }
02479
02480 void LLViewerObject::loadTaskInvFile(const char* filename)
02481 {
02482 LLMemType mt(LLMemType::MTYPE_OBJECT);
02483
02484 std::string filename_and_local_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, filename);
02485 llifstream ifs(filename_and_local_path.c_str());
02486 if(ifs.good())
02487 {
02488 char buffer[MAX_STRING];
02489
02490 char keyword[MAX_STRING];
02491 if(mInventory)
02492 {
02493 mInventory->clear();
02494 }
02495 else
02496 {
02497 mInventory = new InventoryObjectList;
02498 }
02499 while(ifs.good())
02500 {
02501 ifs.getline(buffer, MAX_STRING);
02502 sscanf(buffer, " %254s", keyword);
02503 if(0 == strcmp("inv_item", keyword))
02504 {
02505 LLPointer<LLInventoryObject> inv = new LLViewerInventoryItem;
02506 inv->importLegacyStream(ifs);
02507 mInventory->push_front(inv);
02508 }
02509 else if(0 == strcmp("inv_object", keyword))
02510 {
02511 LLPointer<LLInventoryObject> inv = new LLInventoryObject;
02512 inv->importLegacyStream(ifs);
02513 mInventory->push_front(inv);
02514 }
02515 else
02516 {
02517 llwarns << "Unknown token in inventory file '"
02518 << keyword << "'" << llendl;
02519 }
02520 }
02521 ifs.close();
02522 LLFile::remove(filename_and_local_path.c_str());
02523 }
02524 else
02525 {
02526 llwarns << "unable to load task inventory: " << filename_and_local_path
02527 << llendl;
02528 }
02529 doInventoryCallback();
02530 }
02531
02532 void LLViewerObject::doInventoryCallback()
02533 {
02534 for (callback_list_t::iterator iter = mInventoryCallbacks.begin();
02535 iter != mInventoryCallbacks.end(); )
02536 {
02537 callback_list_t::iterator curiter = iter++;
02538 LLInventoryCallbackInfo* info = *curiter;
02539 if (info->mListener != NULL)
02540 {
02541 info->mListener->inventoryChanged(this,
02542 mInventory,
02543 mInventorySerialNum,
02544 info->mInventoryData);
02545 }
02546 else
02547 {
02548 llinfos << "LLViewerObject::doInventoryCallback() deleting bad listener entry." << llendl;
02549 delete info;
02550 mInventoryCallbacks.erase(curiter);
02551 }
02552 }
02553 mInventoryPending = FALSE;
02554 }
02555
02556 void LLViewerObject::removeInventory(const LLUUID& item_id)
02557 {
02558
02559 LLFloaterProperties::closeByID(item_id, mID);
02560
02561 LLMessageSystem* msg = gMessageSystem;
02562 msg->newMessageFast(_PREHASH_RemoveTaskInventory);
02563 msg->nextBlockFast(_PREHASH_AgentData);
02564 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
02565 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02566 msg->nextBlockFast(_PREHASH_InventoryData);
02567 msg->addU32Fast(_PREHASH_LocalID, mLocalID);
02568 msg->addUUIDFast(_PREHASH_ItemID, item_id);
02569 msg->sendReliable(mRegionp->getHost());
02570 deleteInventoryItem(item_id);
02571 ++mInventorySerialNum;
02572
02573
02574
02575
02576
02577 }
02578
02579 void LLViewerObject::updateInventory(
02580 LLViewerInventoryItem* item,
02581 U8 key,
02582 bool is_new)
02583 {
02584 LLMemType mt(LLMemType::MTYPE_OBJECT);
02585
02586
02587
02588
02589 LLPointer<LLViewerInventoryItem> task_item =
02590 new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
02591 item->getAssetUUID(), item->getType(),
02592 item->getInventoryType(),
02593 item->getName(), item->getDescription(),
02594 item->getSaleInfo(),
02595 item->getFlags(),
02596 item->getCreationDate());
02597 task_item->setTransactionID(item->getTransactionID());
02598 LLMessageSystem* msg = gMessageSystem;
02599 msg->newMessageFast(_PREHASH_UpdateTaskInventory);
02600 msg->nextBlockFast(_PREHASH_AgentData);
02601 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
02602 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02603 msg->nextBlockFast(_PREHASH_UpdateData);
02604 msg->addU32Fast(_PREHASH_LocalID, mLocalID);
02605 msg->addU8Fast(_PREHASH_Key, key);
02606 msg->nextBlockFast(_PREHASH_InventoryData);
02607 task_item->packMessage(msg);
02608 msg->sendReliable(mRegionp->getHost());
02609
02610
02611 doUpdateInventory(task_item, key, is_new);
02612 }
02613
02614 LLInventoryObject* LLViewerObject::getInventoryObject(const LLUUID& item_id)
02615 {
02616 LLInventoryObject* rv = NULL;
02617 if(mInventory)
02618 {
02619 InventoryObjectList::iterator it = mInventory->begin();
02620 InventoryObjectList::iterator end = mInventory->end();
02621 for ( ; it != end; ++it)
02622 {
02623 if((*it)->getUUID() == item_id)
02624 {
02625 rv = *it;
02626 break;
02627 }
02628 }
02629 }
02630 return rv;
02631 }
02632
02633 void LLViewerObject::getInventoryContents(InventoryObjectList& objects)
02634 {
02635 if(mInventory)
02636 {
02637 InventoryObjectList::iterator it = mInventory->begin();
02638 InventoryObjectList::iterator end = mInventory->end();
02639 for( ; it != end; ++it)
02640 {
02641 if ((*it)->getType() != LLAssetType::AT_CATEGORY)
02642 {
02643 objects.push_back(*it);
02644 }
02645 }
02646 }
02647 }
02648
02649 LLInventoryObject* LLViewerObject::getInventoryRoot()
02650 {
02651 if (!mInventory || !mInventory->size())
02652 {
02653 return NULL;
02654 }
02655 return mInventory->back();
02656 }
02657
02658 LLViewerInventoryItem* LLViewerObject::getInventoryItemByAsset(const LLUUID& asset_id)
02659 {
02660 if (mInventoryDirty)
02661 llwarns << "Peforming inventory lookup for object " << mID << " that has dirty inventory!" << llendl;
02662
02663 LLViewerInventoryItem* rv = NULL;
02664 if(mInventory)
02665 {
02666 LLViewerInventoryItem* item = NULL;
02667
02668 InventoryObjectList::iterator it = mInventory->begin();
02669 InventoryObjectList::iterator end = mInventory->end();
02670 for( ; it != end; ++it)
02671 {
02672 LLInventoryObject* obj = *it;
02673 if(obj->getType() != LLAssetType::AT_CATEGORY)
02674 {
02675
02676 item = (LLViewerInventoryItem*)obj;
02677 if(item->getAssetUUID() == asset_id)
02678 {
02679 rv = item;
02680 break;
02681 }
02682 }
02683 }
02684 }
02685 return rv;
02686 }
02687
02688 void LLViewerObject::updateViewerInventoryAsset(
02689 const LLViewerInventoryItem* item,
02690 const LLUUID& new_asset)
02691 {
02692 LLPointer<LLViewerInventoryItem> task_item =
02693 new LLViewerInventoryItem(item);
02694 task_item->setAssetUUID(new_asset);
02695
02696
02697 doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, false);
02698 }
02699
02700 void LLViewerObject::setPixelAreaAndAngle(LLAgent &agent)
02701 {
02702 if (getVolume())
02703 {
02704 return;
02705 }
02706
02707 LLVector3 viewer_pos_agent = agent.getCameraPositionAgent();
02708 LLVector3 pos_agent = getRenderPosition();
02709
02710 F32 dx = viewer_pos_agent.mV[VX] - pos_agent.mV[VX];
02711 F32 dy = viewer_pos_agent.mV[VY] - pos_agent.mV[VY];
02712 F32 dz = viewer_pos_agent.mV[VZ] - pos_agent.mV[VZ];
02713
02714 F32 max_scale = getMaxScale();
02715 F32 mid_scale = getMidScale();
02716 F32 min_scale = getMinScale();
02717
02718
02719
02720
02721
02722 F32 range = sqrt(dx*dx + dy*dy + dz*dz) - min_scale/2;
02723
02724 if (range < 0.001f || isHUDAttachment())
02725 {
02726 mAppAngle = 180.f;
02727 mPixelArea = (F32)LLViewerCamera::getInstance()->getScreenPixelArea();
02728 }
02729 else
02730 {
02731 mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG;
02732
02733 F32 pixels_per_meter = LLViewerCamera::getInstance()->getPixelMeterRatio() / range;
02734
02735 mPixelArea = (pixels_per_meter * max_scale) * (pixels_per_meter * mid_scale);
02736 if (mPixelArea > LLViewerCamera::getInstance()->getScreenPixelArea())
02737 {
02738 mAppAngle = 180.f;
02739 mPixelArea = (F32)LLViewerCamera::getInstance()->getScreenPixelArea();
02740 }
02741 }
02742 }
02743
02744 BOOL LLViewerObject::updateLOD()
02745 {
02746
02747 if (mAudioSourcep && mAudioSourcep->isLoop())
02748 {
02749 F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : (mAudioGain * gSavedSettings.getF32("AudioLevelSFX"));
02750 mAudioSourcep->setGain(volume);
02751 }
02752 return FALSE;
02753 }
02754
02755 BOOL LLViewerObject::updateGeometry(LLDrawable *drawable)
02756 {
02757 return TRUE;
02758 }
02759
02760 void LLViewerObject::updateFaceSize(S32 idx)
02761 {
02762
02763 }
02764
02765 LLDrawable* LLViewerObject::createDrawable(LLPipeline *pipeline)
02766 {
02767 return NULL;
02768 }
02769
02770 void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped)
02771 {
02772 LLPrimitive::setScale(scale);
02773 if (mDrawable.notNull())
02774 {
02775
02776
02777 mDrawable->setRadius(LLVector3(1,1,0.5f).scaleVec(scale).magVec());
02778 updateDrawable(damped);
02779 }
02780
02781 if( (LL_PCODE_VOLUME == getPCode()) && !isDead() )
02782 {
02783 if (permYouOwner() || (scale.magVecSquared() > (7.5f * 7.5f)) )
02784 {
02785 if (!mOnMap)
02786 {
02787 gObjectList.addToMap(this);
02788 mOnMap = TRUE;
02789 }
02790 }
02791 else
02792 {
02793 if (mOnMap)
02794 {
02795 gObjectList.removeFromMap(this);
02796 mOnMap = FALSE;
02797 }
02798 }
02799 }
02800 }
02801
02802 void LLViewerObject::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax)
02803 {
02804 LLVector3 center = getRenderPosition();
02805 LLVector3 size = getScale();
02806 newMin.setVec(center-size);
02807 newMax.setVec(center+size);
02808 mDrawable->setPositionGroup((newMin + newMax) * 0.5f);
02809 }
02810
02811 F32 LLViewerObject::getBinRadius()
02812 {
02813 if (mDrawable.notNull())
02814 {
02815 const LLVector3* ext = mDrawable->getSpatialExtents();
02816 return (ext[1]-ext[0]).magVec();
02817 }
02818
02819 return getScale().magVec();
02820 }
02821
02822 F32 LLViewerObject::getMaxScale() const
02823 {
02824 return llmax(getScale().mV[VX],getScale().mV[VY], getScale().mV[VZ]);
02825 }
02826
02827 F32 LLViewerObject::getMinScale() const
02828 {
02829 return llmin(getScale().mV[0],getScale().mV[1],getScale().mV[2]);
02830 }
02831
02832 F32 LLViewerObject::getMidScale() const
02833 {
02834 if (getScale().mV[VX] < getScale().mV[VY])
02835 {
02836 if (getScale().mV[VY] < getScale().mV[VZ])
02837 {
02838 return getScale().mV[VY];
02839 }
02840 else if (getScale().mV[VX] < getScale().mV[VZ])
02841 {
02842 return getScale().mV[VZ];
02843 }
02844 else
02845 {
02846 return getScale().mV[VX];
02847 }
02848 }
02849 else if (getScale().mV[VX] < getScale().mV[VZ])
02850 {
02851 return getScale().mV[VX];
02852 }
02853 else if (getScale().mV[VY] < getScale().mV[VZ])
02854 {
02855 return getScale().mV[VZ];
02856 }
02857 else
02858 {
02859 return getScale().mV[VY];
02860 }
02861 }
02862
02863
02864 void LLViewerObject::updateTextures(LLAgent &agent)
02865 {
02866 }
02867
02868 void LLViewerObject::boostTexturePriority(BOOL boost_children )
02869 {
02870 if (isDead())
02871 {
02872 return;
02873 }
02874
02875 S32 i;
02876 S32 tex_count = getNumTEs();
02877 for (i = 0; i < tex_count; i++)
02878 {
02879 getTEImage(i)->setBoostLevel(LLViewerImage::BOOST_SELECTED);
02880 }
02881
02882 if (boost_children)
02883 {
02884 S32 num_children = mChildList.size();
02885 for (i = 0; i < num_children; i++)
02886 {
02887 LLViewerObject *childp = mChildList[i];
02888 childp->boostTexturePriority();
02889 }
02890 }
02891 }
02892
02893
02894 void LLViewerObject::setLineWidthForWindowSize(S32 window_width)
02895 {
02896 if (window_width < 700)
02897 {
02898 LLUI::setLineWidth(2.0f);
02899 }
02900 else if (window_width < 1100)
02901 {
02902 LLUI::setLineWidth(3.0f);
02903 }
02904 else if (window_width < 2000)
02905 {
02906 LLUI::setLineWidth(4.0f);
02907 }
02908 else
02909 {
02910
02911 LLUI::setLineWidth(5.0f);
02912 }
02913 }
02914
02915 void LLViewerObject::increaseArrowLength()
02916 {
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927 }
02928
02929
02930 void LLViewerObject::decreaseArrowLength()
02931 {
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942 }
02943
02944
02945 void LLViewerObject::addNVPair(const std::string& data)
02946 {
02947
02948 LLNameValue *nv = new LLNameValue(data.c_str());
02949
02950
02951
02952
02953
02954 name_value_map_t::iterator iter = mNameValuePairs.find(nv->mName);
02955 if (iter != mNameValuePairs.end())
02956 {
02957 LLNameValue* foundnv = iter->second;
02958 if (foundnv->mClass != NVC_READ_ONLY)
02959 {
02960 delete foundnv;
02961 mNameValuePairs.erase(iter);
02962 }
02963 else
02964 {
02965 delete nv;
02966
02967 return;
02968 }
02969 }
02970 mNameValuePairs[nv->mName] = nv;
02971 }
02972
02973 BOOL LLViewerObject::removeNVPair(const char *name)
02974 {
02975 char* canonical_name = gNVNameTable.addString(name);
02976
02977 lldebugs << "LLViewerObject::removeNVPair(): " << name << llendl;
02978
02979 name_value_map_t::iterator iter = mNameValuePairs.find(canonical_name);
02980 if (iter != mNameValuePairs.end())
02981 {
02982 if( mRegionp )
02983 {
02984 LLNameValue* nv = iter->second;
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997 delete nv;
02998 mNameValuePairs.erase(iter);
02999 return TRUE;
03000 }
03001 else
03002 {
03003 lldebugs << "removeNVPair - No region for object" << llendl;
03004 }
03005 }
03006 return FALSE;
03007 }
03008
03009
03010 LLNameValue *LLViewerObject::getNVPair(const char *name) const
03011 {
03012 char *canonical_name;
03013
03014 canonical_name = gNVNameTable.addString(name);
03015
03016
03017
03018 name_value_map_t::const_iterator iter = mNameValuePairs.find(canonical_name);
03019 if (iter != mNameValuePairs.end())
03020 {
03021 return iter->second;
03022 }
03023 else
03024 {
03025 return NULL;
03026 }
03027 }
03028
03029 void LLViewerObject::updatePositionCaches() const
03030 {
03031 if (!isRoot())
03032 {
03033 mPositionRegion = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation();
03034 mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
03035 }
03036 else
03037 {
03038 mPositionRegion = getPosition();
03039 mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
03040 }
03041 }
03042
03043 const LLVector3d LLViewerObject::getPositionGlobal() const
03044 {
03045 LLVector3d position_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());;
03046
03047 if (isAttachment())
03048 {
03049 position_global = gAgent.getPosGlobalFromAgent(getRenderPosition());
03050 }
03051
03052 return position_global;
03053 }
03054
03055 const LLVector3 &LLViewerObject::getPositionAgent() const
03056 {
03057 if (mRegionp)
03058 {
03059 if (mDrawable.notNull() && (!mDrawable->isRoot() && getParent()))
03060 {
03061
03062 LLVector3 position_region;
03063 position_region = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation();
03064 mPositionAgent = mRegionp->getPosAgentFromRegion(position_region);
03065 }
03066 else
03067 {
03068 mPositionAgent = mRegionp->getPosAgentFromRegion(getPosition());
03069 }
03070 }
03071 return mPositionAgent;
03072 }
03073
03074 const LLVector3 &LLViewerObject::getPositionRegion() const
03075 {
03076 if (!isRoot())
03077 {
03078 LLViewerObject *parent = (LLViewerObject *)getParent();
03079 mPositionRegion = parent->getPositionRegion() + (getPosition() * parent->getRotation());
03080 }
03081 else
03082 {
03083 mPositionRegion = getPosition();
03084 }
03085
03086 return mPositionRegion;
03087 }
03088
03089 const LLVector3 LLViewerObject::getPositionEdit() const
03090 {
03091 if (isRootEdit())
03092 {
03093 return getPosition();
03094 }
03095 else
03096 {
03097 LLViewerObject *parent = (LLViewerObject *)getParent();
03098 LLVector3 position_edit = parent->getPositionEdit() + getPosition() * parent->getRotationEdit();
03099 return position_edit;
03100 }
03101 }
03102
03103 const LLVector3 LLViewerObject::getRenderPosition() const
03104 {
03105 if (mDrawable.isNull() || mDrawable->getGeneration() < 0)
03106 {
03107 return getPositionAgent();
03108 }
03109 else
03110 {
03111 return mDrawable->getPositionAgent();
03112 }
03113 }
03114
03115 const LLVector3 LLViewerObject::getPivotPositionAgent() const
03116 {
03117 return getRenderPosition();
03118 }
03119
03120 const LLQuaternion LLViewerObject::getRenderRotation() const
03121 {
03122 LLQuaternion ret;
03123 if (mDrawable.isNull() || mDrawable->isStatic())
03124 {
03125 ret = getRotationEdit();
03126 }
03127 else
03128 {
03129 if (!mDrawable->isRoot())
03130 {
03131 ret = getRotation() * LLQuaternion(mDrawable->getParent()->getWorldMatrix());
03132 }
03133 else
03134 {
03135 ret = LLQuaternion(mDrawable->getWorldMatrix());
03136 }
03137 }
03138
03139 return ret;
03140 }
03141
03142 const LLMatrix4 LLViewerObject::getRenderMatrix() const
03143 {
03144 return mDrawable->getWorldMatrix();
03145 }
03146
03147 const LLQuaternion LLViewerObject::getRotationRegion() const
03148 {
03149 LLQuaternion global_rotation = getRotation();
03150 if (!((LLXform *)this)->isRoot())
03151 {
03152 global_rotation = global_rotation * getParent()->getRotation();
03153 }
03154 return global_rotation;
03155 }
03156
03157 const LLQuaternion LLViewerObject::getRotationEdit() const
03158 {
03159 LLQuaternion global_rotation = getRotation();
03160 if (!((LLXform *)this)->isRootEdit())
03161 {
03162 global_rotation = global_rotation * getParent()->getRotation();
03163 }
03164 return global_rotation;
03165 }
03166
03167 void LLViewerObject::setPositionAbsoluteGlobal( const LLVector3d &pos_global, BOOL damped )
03168 {
03169 if (isAttachment())
03170 {
03171 LLVector3 new_pos = mRegionp->getPosRegionFromGlobal(pos_global);
03172 if (isRootEdit())
03173 {
03174 new_pos -= mDrawable->mXform.getParent()->getWorldPosition();
03175 LLQuaternion world_rotation = mDrawable->mXform.getParent()->getWorldRotation();
03176 new_pos = new_pos * ~world_rotation;
03177 }
03178 else
03179 {
03180 LLViewerObject* parentp = (LLViewerObject*)getParent();
03181 new_pos -= parentp->getPositionAgent();
03182 new_pos = new_pos * ~parentp->getRotationRegion();
03183 }
03184 LLViewerObject::setPosition(new_pos);
03185
03186 if (mParent && ((LLViewerObject*)mParent)->isAvatar())
03187 {
03188
03189 LLVOAvatar *avatar = (LLVOAvatar*)mParent;
03190
03191 avatar->clampAttachmentPositions();
03192 }
03193 }
03194 else
03195 {
03196 if( isRoot() )
03197 {
03198 setPositionRegion(mRegionp->getPosRegionFromGlobal(pos_global));
03199 }
03200 else
03201 {
03202
03203 LLViewerObject* parent = (LLViewerObject *)getParent();
03204
03205 gPipeline.updateMoveNormalAsync(parent->mDrawable);
03206
03207 LLVector3 pos_local = mRegionp->getPosRegionFromGlobal(pos_global) - parent->getPositionRegion();
03208 pos_local = pos_local * ~parent->getRotationRegion();
03209 LLViewerObject::setPosition( pos_local );
03210 }
03211 }
03212
03213 gPipeline.updateMoveNormalAsync(mDrawable);
03214 }
03215
03216 void LLViewerObject::setPosition(const LLVector3 &pos, BOOL damped)
03217 {
03218 if (getPosition() != pos)
03219 {
03220 setChanged(TRANSLATED | SILHOUETTE);
03221 }
03222
03223 LLXform::setPosition(pos);
03224 updateDrawable(damped);
03225 if (isRoot())
03226 {
03227
03228 updatePositionCaches();
03229 }
03230 }
03231
03232 void LLViewerObject::setPositionGlobal(const LLVector3d &pos_global, BOOL damped)
03233 {
03234 if (isAttachment())
03235 {
03236 if (isRootEdit())
03237 {
03238 LLVector3 newPos = mRegionp->getPosRegionFromGlobal(pos_global);
03239 newPos = newPos - mDrawable->mXform.getParent()->getWorldPosition();
03240
03241 LLQuaternion invWorldRotation = mDrawable->mXform.getParent()->getWorldRotation();
03242 invWorldRotation.transQuat();
03243
03244 newPos = newPos * invWorldRotation;
03245 LLViewerObject::setPosition(newPos);
03246 }
03247 else
03248 {
03249
03250 LLVector3 newPos = mRegionp->getPosRegionFromGlobal(pos_global);
03251 newPos = newPos - mDrawable->mXform.getParent()->getWorldPosition();
03252 LLVector3 delta_pos = newPos - getPosition();
03253
03254 LLQuaternion invRotation = mDrawable->getRotation();
03255 invRotation.transQuat();
03256
03257 delta_pos = delta_pos * invRotation;
03258
03259
03260
03261 LLVector3 old_pos = mDrawable->mXform.getParent()->getPosition();
03262 mDrawable->mXform.getParent()->setPosition(old_pos + delta_pos);
03263 setChanged(TRANSLATED | SILHOUETTE);
03264 }
03265 if (mParent && ((LLViewerObject*)mParent)->isAvatar())
03266 {
03267
03268 LLVOAvatar *avatar = (LLVOAvatar*)mParent;
03269
03270 avatar->clampAttachmentPositions();
03271 }
03272 }
03273 else
03274 {
03275 if (isRoot())
03276 {
03277 setPositionRegion(mRegionp->getPosRegionFromGlobal(pos_global));
03278 }
03279 else
03280 {
03281
03282 LLVector3d position_offset;
03283 position_offset.setVec(getPosition()*getParent()->getRotation());
03284 LLVector3d new_pos_global = pos_global - position_offset;
03285 ((LLViewerObject *)getParent())->setPositionGlobal(new_pos_global);
03286 }
03287 }
03288 updateDrawable(damped);
03289 }
03290
03291
03292 void LLViewerObject::setPositionParent(const LLVector3 &pos_parent, BOOL damped)
03293 {
03294
03295 if (!isRoot())
03296 {
03297 LLViewerObject::setPosition(pos_parent);
03298 updateDrawable(damped);
03299 }
03300 else
03301 {
03302 setPositionRegion(pos_parent, damped);
03303 }
03304 }
03305
03306 void LLViewerObject::setPositionRegion(const LLVector3 &pos_region, BOOL damped)
03307 {
03308 if (!isRootEdit())
03309 {
03310 LLViewerObject* parent = (LLViewerObject*) getParent();
03311 LLViewerObject::setPosition((pos_region-parent->getPositionRegion())*~parent->getRotationRegion());
03312 }
03313 else
03314 {
03315 LLViewerObject::setPosition(pos_region);
03316 mPositionRegion = pos_region;
03317 mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
03318 }
03319 }
03320
03321 void LLViewerObject::setPositionAgent(const LLVector3 &pos_agent, BOOL damped)
03322 {
03323 LLVector3 pos_region = getRegion()->getPosRegionFromAgent(pos_agent);
03324 setPositionRegion(pos_region, damped);
03325 }
03326
03327
03328
03329
03330
03331 void LLViewerObject::setPositionEdit(const LLVector3 &pos_edit, BOOL damped)
03332 {
03333 if (!isRootEdit())
03334 {
03335
03336 LLVector3 position_offset = getPosition() * getParent()->getRotation();
03337
03338 ((LLViewerObject *)getParent())->setPositionEdit(pos_edit - position_offset);
03339 }
03340 else if (isJointChild())
03341 {
03342
03343 LLViewerObject *parent = (LLViewerObject *) getParent();
03344 LLQuaternion inv_parent_rot = parent->getRotation();
03345 inv_parent_rot.transQuat();
03346 LLVector3 pos_parent = (pos_edit - parent->getPositionRegion()) * inv_parent_rot;
03347 LLViewerObject::setPosition(pos_parent);
03348 }
03349 else
03350 {
03351 LLViewerObject::setPosition(pos_edit);
03352 mPositionRegion = pos_edit;
03353 mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
03354 }
03355 updateDrawable(damped);
03356 }
03357
03358
03359 LLViewerObject* LLViewerObject::getRootEdit() const
03360 {
03361 const LLViewerObject* root = this;
03362 while (root->mParent
03363 && !(root->mJointInfo
03364 || ((LLViewerObject*)root->mParent)->isAvatar()) )
03365 {
03366 root = (LLViewerObject*)root->mParent;
03367 }
03368 return (LLViewerObject*)root;
03369 }
03370
03371 U8 LLViewerObject::getMediaType() const
03372 {
03373 if (mMedia)
03374 {
03375 return mMedia->mMediaType;
03376 }
03377 else
03378 {
03379 return LLViewerObject::MEDIA_TYPE_NONE;
03380 }
03381 }
03382
03383 void LLViewerObject::setMediaType(U8 media_type)
03384 {
03385 if (!mMedia)
03386 {
03387
03388 }
03389 else if (mMedia->mMediaType != media_type)
03390 {
03391 mMedia->mMediaType = media_type;
03392
03393
03394 }
03395 }
03396
03397 const LLString& LLViewerObject::getMediaURL() const
03398 {
03399 if (mMedia)
03400 {
03401 return mMedia->mMediaURL;
03402 }
03403 else
03404 {
03405 return LLString::null;
03406 }
03407 }
03408
03409 void LLViewerObject::setMediaURL(const LLString& media_url)
03410 {
03411 LLMemType mt(LLMemType::MTYPE_OBJECT);
03412
03413 if (!mMedia)
03414 {
03415 mMedia = new LLViewerObjectMedia;
03416 mMedia->mMediaURL = media_url;
03417 mMedia->mPassedWhitelist = FALSE;
03418
03419
03420 }
03421 else if (mMedia->mMediaURL != media_url)
03422 {
03423 mMedia->mMediaURL = media_url;
03424 mMedia->mPassedWhitelist = FALSE;
03425
03426
03427 }
03428 }
03429
03430 BOOL LLViewerObject::getMediaPassedWhitelist() const
03431 {
03432 if (mMedia)
03433 {
03434 return mMedia->mPassedWhitelist;
03435 }
03436 else
03437 {
03438 return FALSE;
03439 }
03440 }
03441
03442 void LLViewerObject::setMediaPassedWhitelist(BOOL passed)
03443 {
03444 if (mMedia)
03445 {
03446 mMedia->mPassedWhitelist = passed;
03447 }
03448 }
03449
03450 BOOL LLViewerObject::setMaterial(const U8 material)
03451 {
03452 BOOL res = LLPrimitive::setMaterial(material);
03453 if (res)
03454 {
03455 setChanged(TEXTURE);
03456 }
03457 return res;
03458 }
03459
03460 void LLViewerObject::setNumTEs(const U8 num_tes)
03461 {
03462 LLMemType mt(LLMemType::MTYPE_OBJECT);
03463
03464 U32 i;
03465 if (num_tes != getNumTEs())
03466 {
03467 if (num_tes)
03468 {
03469 LLPointer<LLViewerImage> *new_images;
03470 new_images = new LLPointer<LLViewerImage>[num_tes];
03471 for (i = 0; i < num_tes; i++)
03472 {
03473 if (i < getNumTEs())
03474 {
03475 new_images[i] = mTEImages[i];
03476 }
03477 else if (getNumTEs())
03478 {
03479 new_images[i] = mTEImages[getNumTEs()-1];
03480 }
03481 else
03482 {
03483 new_images[i] = NULL;
03484 }
03485 }
03486
03487 deleteTEImages();
03488
03489 mTEImages = new_images;
03490 }
03491 else
03492 {
03493 deleteTEImages();
03494 }
03495 LLPrimitive::setNumTEs(num_tes);
03496 setChanged(TEXTURE);
03497
03498 if (mDrawable.notNull())
03499 {
03500 gPipeline.markTextured(mDrawable);
03501 }
03502 }
03503 }
03504
03505 void LLViewerObject::sendMaterialUpdate() const
03506 {
03507 LLViewerRegion* regionp = getRegion();
03508 if(!regionp) return;
03509 gMessageSystem->newMessageFast(_PREHASH_ObjectMaterial);
03510 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03511 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
03512 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03513 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03514 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
03515 gMessageSystem->addU8Fast(_PREHASH_Material, getMaterial() );
03516 gMessageSystem->sendReliable( regionp->getHost() );
03517
03518 }
03519
03520
03521 void LLViewerObject::sendRotationUpdate() const
03522 {
03523 LLViewerRegion* regionp = getRegion();
03524 if(!regionp) return;
03525 gMessageSystem->newMessageFast(_PREHASH_ObjectRotation);
03526 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03527 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
03528 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03529 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03530 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID);
03531 gMessageSystem->addQuatFast(_PREHASH_Rotation, getRotationEdit());
03532
03533 gMessageSystem->sendReliable( regionp->getHost() );
03534 }
03535
03536
03538
03539
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553 void LLViewerObject::sendShapeUpdate()
03554 {
03555 gMessageSystem->newMessageFast(_PREHASH_ObjectShape);
03556 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
03557 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
03558 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03559 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
03560 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
03561
03562 LLVolumeMessage::packVolumeParams(&getVolume()->getParams(), gMessageSystem);
03563
03564 LLViewerRegion *regionp = getRegion();
03565 gMessageSystem->sendReliable( regionp->getHost() );
03566 }
03567
03568
03569 void LLViewerObject::sendTEUpdate() const
03570 {
03571 LLMessageSystem* msg = gMessageSystem;
03572 msg->newMessageFast(_PREHASH_ObjectImage);
03573
03574 msg->nextBlockFast(_PREHASH_AgentData);
03575 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
03576 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03577
03578 msg->nextBlockFast(_PREHASH_ObjectData);
03579 msg->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
03580 if (mMedia)
03581 {
03582 msg->addString("MediaURL", mMedia->mMediaURL);
03583 }
03584 else
03585 {
03586 msg->addString("MediaURL", NULL);
03587 }
03588
03589
03590
03591 packTEMessage(msg);
03592
03593 LLViewerRegion *regionp = getRegion();
03594 msg->sendReliable( regionp->getHost() );
03595 }
03596
03597 void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
03598 {
03599 LLPrimitive::setTE(te, texture_entry);
03600
03601
03602
03603 const LLUUID& image_id = getTE(te)->getID();
03604 mTEImages[te] = gImageList.getImage(image_id);
03605
03606 }
03607
03608 void LLViewerObject::setTEImage(const U8 te, LLViewerImage *imagep)
03609 {
03610 if (mTEImages[te] != imagep)
03611 {
03612 mTEImages[te] = imagep;
03613 LLPrimitive::setTETexture(te, imagep->getID());
03614 setChanged(TEXTURE);
03615 if (mDrawable.notNull())
03616 {
03617 gPipeline.markTextured(mDrawable);
03618 }
03619 }
03620 }
03621
03622
03623 S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host)
03624 {
03625 S32 retval = 0;
03626 if (uuid != getTE(te)->getID() ||
03627 uuid == LLUUID::null)
03628 {
03629 retval = LLPrimitive::setTETexture(te, uuid);
03630 mTEImages[te] = gImageList.getImageFromHost(uuid, host);
03631 setChanged(TEXTURE);
03632 if (mDrawable.notNull())
03633 {
03634 gPipeline.markTextured(mDrawable);
03635 }
03636 }
03637 return retval;
03638 }
03639
03640
03641 S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
03642 {
03643
03644 return setTETextureCore(te, uuid, LLHost::invalid);
03645 }
03646
03647
03648 S32 LLViewerObject::setTEColor(const U8 te, const LLColor3& color)
03649 {
03650 return setTEColor(te, LLColor4(color));
03651 }
03652
03653 S32 LLViewerObject::setTEColor(const U8 te, const LLColor4& color)
03654 {
03655 S32 retval = 0;
03656 const LLTextureEntry *tep = getTE(te);
03657 if (!tep)
03658 {
03659 llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
03660 }
03661 else if (color != tep->getColor())
03662 {
03663 retval = LLPrimitive::setTEColor(te, color);
03664 setChanged(TEXTURE);
03665 if (mDrawable.notNull() && retval)
03666 {
03667
03668 gPipeline.markTextured(mDrawable);
03669 }
03670 }
03671 return retval;
03672 }
03673
03674 S32 LLViewerObject::setTEBumpmap(const U8 te, const U8 bump)
03675 {
03676 S32 retval = 0;
03677 const LLTextureEntry *tep = getTE(te);
03678 if (!tep)
03679 {
03680 llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
03681 }
03682 else if (bump != tep->getBumpmap())
03683 {
03684 retval = LLPrimitive::setTEBumpmap(te, bump);
03685 setChanged(TEXTURE);
03686 if (mDrawable.notNull() && retval)
03687 {
03688 gPipeline.markTextured(mDrawable);
03689 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
03690 }
03691 }
03692 return retval;
03693 }
03694
03695 S32 LLViewerObject::setTETexGen(const U8 te, const U8 texgen)
03696 {
03697 S32 retval = 0;
03698 const LLTextureEntry *tep = getTE(te);
03699 if (!tep)
03700 {
03701 llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
03702 }
03703 else if (texgen != tep->getTexGen())
03704 {
03705 retval = LLPrimitive::setTETexGen(te, texgen);
03706 setChanged(TEXTURE);
03707 }
03708 return retval;
03709 }
03710
03711 S32 LLViewerObject::setTEShiny(const U8 te, const U8 shiny)
03712 {
03713 S32 retval = 0;
03714 const LLTextureEntry *tep = getTE(te);
03715 if (!tep)
03716 {
03717 llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
03718 }
03719 else if (shiny != tep->getShiny())
03720 {
03721 retval = LLPrimitive::setTEShiny(te, shiny);
03722 setChanged(TEXTURE);
03723 }
03724 return retval;
03725 }
03726
03727 S32 LLViewerObject::setTEFullbright(const U8 te, const U8 fullbright)
03728 {
03729 S32 retval = 0;
03730 const LLTextureEntry *tep = getTE(te);
03731 if (!tep)
03732 {
03733 llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
03734 }
03735 else if (fullbright != tep->getFullbright())
03736 {
03737 retval = LLPrimitive::setTEFullbright(te, fullbright);
03738 setChanged(TEXTURE);
03739 if (mDrawable.notNull() && retval)
03740 {
03741 gPipeline.markTextured(mDrawable);
03742 }
03743 }
03744 return retval;
03745 }
03746
03747
03748 S32 LLViewerObject::setTEMediaFlags(const U8 te, const U8 media_flags)
03749 {
03750
03751 S32 retval = 0;
03752 const LLTextureEntry *tep = getTE(te);
03753 if (!tep)
03754 {
03755 llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
03756 }
03757 else if (media_flags != tep->getMediaFlags())
03758 {
03759 retval = LLPrimitive::setTEMediaFlags(te, media_flags);
03760 setChanged(TEXTURE);
03761 if (mDrawable.notNull() && retval)
03762 {
03763 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD, TRUE);
03764 gPipeline.markTextured(mDrawable);
03765
03766
03767 }
03768 }
03769 return retval;
03770 }
03771
03772 S32 LLViewerObject::setTEGlow(const U8 te, const F32 glow)
03773 {
03774 S32 retval = 0;
03775 const LLTextureEntry *tep = getTE(te);
03776 if (!tep)
03777 {
03778 llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
03779 }
03780 else if (glow != tep->getGlow())
03781 {
03782 retval = LLPrimitive::setTEGlow(te, glow);
03783 setChanged(TEXTURE);
03784 if (mDrawable.notNull() && retval)
03785 {
03786 gPipeline.markTextured(mDrawable);
03787 }
03788 }
03789 return retval;
03790 }
03791
03792
03793 S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t)
03794 {
03795 S32 retval = 0;
03796 retval = LLPrimitive::setTEScale(te, s, t);
03797 setChanged(TEXTURE);
03798 if (mDrawable.notNull() && retval)
03799 {
03800 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
03801 }
03802 return retval;
03803 }
03804
03805 S32 LLViewerObject::setTEScaleS(const U8 te, const F32 s)
03806 {
03807 S32 retval = LLPrimitive::setTEScaleS(te, s);
03808 if (mDrawable.notNull() && retval)
03809 {
03810 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
03811 }
03812
03813 return retval;
03814 }
03815
03816 S32 LLViewerObject::setTEScaleT(const U8 te, const F32 t)
03817 {
03818 S32 retval = LLPrimitive::setTEScaleT(te, t);
03819 if (mDrawable.notNull() && retval)
03820 {
03821 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
03822 }
03823
03824 return retval;
03825 }
03826
03827 S32 LLViewerObject::setTEOffset(const U8 te, const F32 s, const F32 t)
03828 {
03829 S32 retval = LLPrimitive::setTEOffset(te, s, t);
03830 if (mDrawable.notNull() && retval)
03831 {
03832 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
03833 }
03834 return retval;
03835 }
03836
03837 S32 LLViewerObject::setTEOffsetS(const U8 te, const F32 s)
03838 {
03839 S32 retval = LLPrimitive::setTEOffsetS(te, s);
03840 if (mDrawable.notNull() && retval)
03841 {
03842 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
03843 }
03844
03845 return retval;
03846 }
03847
03848 S32 LLViewerObject::setTEOffsetT(const U8 te, const F32 t)
03849 {
03850 S32 retval = LLPrimitive::setTEOffsetT(te, t);
03851 if (mDrawable.notNull() && retval)
03852 {
03853 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
03854 }
03855
03856 return retval;
03857 }
03858
03859 S32 LLViewerObject::setTERotation(const U8 te, const F32 r)
03860 {
03861 S32 retval = LLPrimitive::setTERotation(te, r);
03862 if (mDrawable.notNull() && retval)
03863 {
03864 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
03865 }
03866 return retval;
03867 }
03868
03869
03870 LLViewerImage *LLViewerObject::getTEImage(const U8 face) const
03871 {
03872
03873
03874 if (face < getNumTEs())
03875 {
03876 LLViewerImage* image = mTEImages[face];
03877 if (image)
03878 {
03879 return image;
03880 }
03881 else
03882 {
03883 return (LLViewerImage*)((LLImageGL*)LLViewerImage::sDefaultImagep);
03884 }
03885 }
03886
03887 llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl;
03888
03889 return NULL;
03890 }
03891
03892
03893 void LLViewerObject::fitFaceTexture(const U8 face)
03894 {
03895 llinfos << "fitFaceTexture not implemented" << llendl;
03896 }
03897
03898
03899 LLBBox LLViewerObject::getBoundingBoxAgent() const
03900 {
03901 LLVector3 position_agent;
03902 LLQuaternion rot;
03903 LLViewerObject* root_edit = (LLViewerObject*)getRootEdit();
03904 LLViewerObject* avatar_parent = (LLViewerObject*)root_edit->getParent();
03905 if (avatar_parent && avatar_parent->isAvatar() && root_edit->mDrawable.notNull())
03906 {
03907 LLXform* parent_xform = root_edit->mDrawable->getXform()->getParent();
03908 position_agent = (getPositionEdit() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();
03909 rot = getRotationEdit() * parent_xform->getWorldRotation();
03910 }
03911 else
03912 {
03913 position_agent = getPositionAgent();
03914 rot = getRotationRegion();
03915 }
03916
03917 return LLBBox( position_agent, rot, getScale() * -0.5f, getScale() * 0.5f );
03918 }
03919
03920 U32 LLViewerObject::getNumVertices() const
03921 {
03922 U32 num_vertices = 0;
03923 if (mDrawable.notNull())
03924 {
03925 S32 i, num_faces;
03926 num_faces = mDrawable->getNumFaces();
03927 for (i = 0; i < num_faces; i++)
03928 {
03929 num_vertices += mDrawable->getFace(i)->getGeomCount();
03930 }
03931 }
03932 return num_vertices;
03933 }
03934
03935 U32 LLViewerObject::getNumIndices() const
03936 {
03937 U32 num_indices = 0;
03938 if (mDrawable.notNull())
03939 {
03940 S32 i, num_faces;
03941 num_faces = mDrawable->getNumFaces();
03942 for (i = 0; i < num_faces; i++)
03943 {
03944 num_indices += mDrawable->getFace(i)->getIndicesCount();
03945 }
03946 }
03947 return num_indices;
03948 }
03949
03950
03951 S32 LLViewerObject::countInventoryContents(LLAssetType::EType type)
03952 {
03953 S32 count = 0;
03954 if( mInventory )
03955 {
03956 InventoryObjectList::const_iterator it = mInventory->begin();
03957 InventoryObjectList::const_iterator end = mInventory->end();
03958 for( ; it != end ; ++it )
03959 {
03960 if( (*it)->getType() == type )
03961 {
03962 ++count;
03963 }
03964 }
03965 }
03966 return count;
03967 }
03968
03969
03970 void LLViewerObject::setCanSelect(BOOL canSelect)
03971 {
03972 mbCanSelect = canSelect;
03973 for (U32 i = 0; i < mChildList.size(); i++)
03974 {
03975 mChildList[i]->mbCanSelect = canSelect;
03976 }
03977 }
03978
03979 void LLViewerObject::setDebugText(const std::string &utf8text)
03980 {
03981 if (utf8text.empty() && !mText)
03982 {
03983 return;
03984 }
03985
03986 if (!mText)
03987 {
03988 mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
03989 mText->setFont(LLFontGL::sSansSerif);
03990 mText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
03991 mText->setMaxLines(-1);
03992 mText->setSourceObject(this);
03993 mText->setOnHUDAttachment(isHUDAttachment());
03994 }
03995 mText->setColor(LLColor4::white);
03996 mText->setStringUTF8(utf8text);
03997 mText->setZCompare(FALSE);
03998 mText->setDoFade(FALSE);
03999 updateText();
04000 }
04001
04002 void LLViewerObject::setIcon(LLViewerImage* icon_image)
04003 {
04004 if (!mIcon)
04005 {
04006 mIcon = (LLHUDIcon *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_ICON);
04007 mIcon->setSourceObject(this);
04008 mIcon->setImage(icon_image);
04009
04010 mIcon->setScale(0.03f);
04011 }
04012 else
04013 {
04014 mIcon->restartLifeTimer();
04015 }
04016 }
04017
04018 void LLViewerObject::clearIcon()
04019 {
04020 if (mIcon)
04021 {
04022 mIcon = NULL;
04023 }
04024 }
04025
04026 LLViewerObject* LLViewerObject::getSubParent()
04027 {
04028 if (isJointChild())
04029 {
04030 return this;
04031 }
04032 return (LLViewerObject*) getParent();
04033 }
04034
04035 const LLViewerObject* LLViewerObject::getSubParent() const
04036 {
04037 if (isJointChild())
04038 {
04039 return this;
04040 }
04041 return (const LLViewerObject*) getParent();
04042 }
04043
04044 BOOL LLViewerObject::isOnMap()
04045 {
04046 return mOnMap;
04047 }
04048
04049
04050 void LLViewerObject::updateText()
04051 {
04052 if (!isDead())
04053 {
04054 if (mText.notNull())
04055 {
04056 LLVector3 up_offset(0,0,0);
04057 up_offset.mV[2] = getScale().mV[VZ]*0.6f;
04058
04059 if (mDrawable.notNull())
04060 {
04061 mText->setPositionAgent(getRenderPosition() + up_offset);
04062 }
04063 else
04064 {
04065 mText->setPositionAgent(getPositionAgent() + up_offset);
04066 }
04067 }
04068 }
04069 }
04070
04071 BOOL LLViewerObject::isParticleSource() const
04072 {
04073 return !mPartSourcep.isNull() && !mPartSourcep->isDead();
04074 }
04075
04076 void LLViewerObject::setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id)
04077 {
04078 if (mPartSourcep)
04079 {
04080 deleteParticleSource();
04081 }
04082
04083 LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::createPSS(this, particle_parameters);
04084 mPartSourcep = pss;
04085
04086 if (mPartSourcep)
04087 {
04088 mPartSourcep->setOwnerUUID(owner_id);
04089
04090 if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
04091 {
04092 LLViewerImage* image;
04093 if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
04094 {
04095 image = gImageList.getImageFromFile("pixiesmall.tga");
04096 }
04097 else
04098 {
04099 image = gImageList.getImage(mPartSourcep->mPartSysData.mPartImageID);
04100 }
04101 mPartSourcep->setImage(image);
04102 }
04103 }
04104 LLViewerPartSim::getInstance()->addPartSource(pss);
04105 }
04106
04107 void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& owner_id)
04108 {
04109 if (!mPartSourcep.isNull() && mPartSourcep->isDead())
04110 {
04111 mPartSourcep = NULL;
04112 }
04113 if (mPartSourcep)
04114 {
04115
04116 if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, block_num))
04117 {
04118 mPartSourcep->setDead();
04119 mPartSourcep = NULL;
04120 }
04121 }
04122 else
04123 {
04124 LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, block_num);
04125
04126 if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return;
04127
04128
04129 if (pss)
04130 {
04131
04132 pss->setOwnerUUID(owner_id);
04133 mPartSourcep = pss;
04134 LLViewerPartSim::getInstance()->addPartSource(pss);
04135 }
04136 }
04137 if (mPartSourcep)
04138 {
04139 if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
04140 {
04141 LLViewerImage* image;
04142 if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
04143 {
04144 image = gImageList.getImageFromFile("pixiesmall.j2c");
04145 }
04146 else
04147 {
04148 image = gImageList.getImage(mPartSourcep->mPartSysData.mPartImageID);
04149 }
04150 mPartSourcep->setImage(image);
04151 }
04152 }
04153 }
04154
04155 void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id)
04156 {
04157 if (!mPartSourcep.isNull() && mPartSourcep->isDead())
04158 {
04159 mPartSourcep = NULL;
04160 }
04161 if (mPartSourcep)
04162 {
04163
04164 if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp))
04165 {
04166 mPartSourcep->setDead();
04167 mPartSourcep = NULL;
04168 }
04169 }
04170 else
04171 {
04172 LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp);
04173
04174 if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return;
04175
04176 if (pss)
04177 {
04178
04179 pss->setOwnerUUID(owner_id);
04180 mPartSourcep = pss;
04181 LLViewerPartSim::getInstance()->addPartSource(pss);
04182 }
04183 }
04184 if (mPartSourcep)
04185 {
04186 if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
04187 {
04188 LLViewerImage* image;
04189 if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
04190 {
04191 image = gImageList.getImageFromFile("pixiesmall.j2c");
04192 }
04193 else
04194 {
04195 image = gImageList.getImage(mPartSourcep->mPartSysData.mPartImageID);
04196 }
04197 mPartSourcep->setImage(image);
04198 }
04199 }
04200 }
04201
04202 void LLViewerObject::deleteParticleSource()
04203 {
04204 if (mPartSourcep.notNull())
04205 {
04206 mPartSourcep->setDead();
04207 mPartSourcep = NULL;
04208 }
04209 }
04210
04211
04212 void LLViewerObject::updateDrawable(BOOL force_damped)
04213 {
04214 if (mDrawable.notNull() &&
04215 !mDrawable->isState(LLDrawable::ON_MOVE_LIST) &&
04216 isChanged(MOVED))
04217 {
04218 BOOL damped_motion =
04219 !isChanged(SHIFTED) &&
04220 (force_damped ||
04221 (!isSelected() &&
04222 (mDrawable->isRoot() ||
04223 !((LLViewerObject*)getParent())->isSelected()) &&
04224 getPCode() == LL_PCODE_VOLUME &&
04225 getVelocity().isExactlyZero() &&
04226 mDrawable->getGeneration() != -1)
04227 );
04228 gPipeline.markMoved(mDrawable, damped_motion);
04229 }
04230 clearChanged(SHIFTED);
04231 }
04232
04233
04234 F32 LLViewerObject::getVObjRadius() const
04235 {
04236 return mDrawable.notNull() ? mDrawable->getRadius() : 0.f;
04237 }
04238
04239 void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const U8 flags)
04240 {
04241 if (!gAudiop)
04242 {
04243 return;
04244 }
04245
04246 if (audio_uuid.isNull())
04247 {
04248 if (!mAudioSourcep)
04249 {
04250 return;
04251 }
04252 if (mAudioSourcep->isLoop() && !mAudioSourcep->hasPendingPreloads())
04253 {
04254
04255
04256
04257
04258
04259 gAudiop->cleanupAudioSource(mAudioSourcep);
04260 mAudioSourcep = NULL;
04261 }
04262 else if (flags & LL_SOUND_FLAG_STOP)
04263 {
04264
04265 mAudioSourcep->play(LLUUID::null);
04266 }
04267 return;
04268 }
04269 if (flags & LL_SOUND_FLAG_LOOP
04270 && mAudioSourcep && mAudioSourcep->isLoop() && mAudioSourcep->getCurrentData()
04271 && mAudioSourcep->getCurrentData()->getID() == audio_uuid)
04272 {
04273
04274 return;
04275 }
04276
04277
04278 if ( mAudioSourcep && mAudioSourcep->isDone() )
04279 {
04280 gAudiop->cleanupAudioSource(mAudioSourcep);
04281 mAudioSourcep = NULL;
04282 }
04283
04284 getAudioSource(owner_id);
04285
04286 if (mAudioSourcep)
04287 {
04288 BOOL queue = flags & LL_SOUND_FLAG_QUEUE;
04289 mAudioGain = gain;
04290 F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : gain * gSavedSettings.getF32("AudioLevelSFX");
04291 mAudioSourcep->setGain(volume);
04292 mAudioSourcep->setLoop(flags & LL_SOUND_FLAG_LOOP);
04293 mAudioSourcep->setSyncMaster(flags & LL_SOUND_FLAG_SYNC_MASTER);
04294 mAudioSourcep->setSyncSlave(flags & LL_SOUND_FLAG_SYNC_SLAVE);
04295 mAudioSourcep->setQueueSounds(queue);
04296 if(!queue)
04297 {
04298 mAudioSourcep->play(LLUUID::null);
04299 }
04300
04301 mAudioSourcep->play(audio_uuid);
04302 }
04303 }
04304
04305 LLAudioSource *LLViewerObject::getAudioSource(const LLUUID& owner_id)
04306 {
04307 if (!mAudioSourcep)
04308 {
04309
04310
04311 LLAudioSourceVO *asvop = new LLAudioSourceVO(mID, owner_id, 0.01f, this);
04312
04313 mAudioSourcep = asvop;
04314 if(gAudiop) gAudiop->addAudioSource(asvop);
04315 }
04316
04317 return mAudioSourcep;
04318 }
04319
04320 void LLViewerObject::adjustAudioGain(const F32 gain)
04321 {
04322 if (!gAudiop)
04323 {
04324 return;
04325 }
04326 if (mAudioSourcep)
04327 {
04328 mAudioGain = gain;
04329 F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : mAudioGain * gSavedSettings.getF32("AudioLevelSFX");
04330 mAudioSourcep->setGain(volume);
04331 }
04332 }
04333
04334
04335
04336 bool LLViewerObject::unpackParameterEntry(U16 param_type, LLDataPacker *dp)
04337 {
04338 ExtraParameter* param = getExtraParameterEntryCreate(param_type);
04339 if (param)
04340 {
04341 param->data->unpack(*dp);
04342 param->in_use = TRUE;
04343 parameterChanged(param_type, param->data, TRUE, false);
04344 return true;
04345 }
04346 else
04347 {
04348 return false;
04349 }
04350 }
04351
04352 LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 param_type)
04353 {
04354 LLNetworkData* new_block = NULL;
04355 switch (param_type)
04356 {
04357 case LLNetworkData::PARAMS_FLEXIBLE:
04358 {
04359 new_block = new LLFlexibleObjectData();
04360 break;
04361 }
04362 case LLNetworkData::PARAMS_LIGHT:
04363 {
04364 new_block = new LLLightParams();
04365 break;
04366 }
04367 case LLNetworkData::PARAMS_SCULPT:
04368 {
04369 new_block = new LLSculptParams();
04370 break;
04371 }
04372
04373 default:
04374 {
04375 llinfos << "Unknown param type." << llendl;
04376 break;
04377 }
04378 };
04379
04380 if (new_block)
04381 {
04382 ExtraParameter* new_entry = new ExtraParameter;
04383 new_entry->data = new_block;
04384 new_entry->in_use = false;
04385 mExtraParameterList[param_type] = new_entry;
04386 return new_entry;
04387 }
04388 return NULL;
04389 }
04390
04391 LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntry(U16 param_type) const
04392 {
04393 std::map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type);
04394 if (itor != mExtraParameterList.end())
04395 {
04396 return itor->second;
04397 }
04398 return NULL;
04399 }
04400
04401 LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntryCreate(U16 param_type)
04402 {
04403 ExtraParameter* param = getExtraParameterEntry(param_type);
04404 if (!param)
04405 {
04406 param = createNewParameterEntry(param_type);
04407 }
04408 return param;
04409 }
04410
04411 LLNetworkData* LLViewerObject::getParameterEntry(U16 param_type) const
04412 {
04413 ExtraParameter* param = getExtraParameterEntry(param_type);
04414 if (param)
04415 {
04416 return param->data;
04417 }
04418 else
04419 {
04420 return NULL;
04421 }
04422 }
04423
04424 BOOL LLViewerObject::getParameterEntryInUse(U16 param_type) const
04425 {
04426 ExtraParameter* param = getExtraParameterEntry(param_type);
04427 if (param)
04428 {
04429 return param->in_use;
04430 }
04431 else
04432 {
04433 return FALSE;
04434 }
04435 }
04436
04437 bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin)
04438 {
04439 ExtraParameter* param = getExtraParameterEntryCreate(param_type);
04440 if (param)
04441 {
04442 if (param->in_use && new_value == *(param->data))
04443 {
04444 return false;
04445 }
04446 param->in_use = true;
04447 param->data->copy(new_value);
04448 parameterChanged(param_type, param->data, TRUE, local_origin);
04449 return true;
04450 }
04451 else
04452 {
04453 return false;
04454 }
04455 }
04456
04457
04458
04459
04460 bool LLViewerObject::setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin)
04461 {
04462 ExtraParameter* param = getExtraParameterEntryCreate(param_type);
04463 if (param->in_use != in_use)
04464 {
04465 param->in_use = in_use;
04466 parameterChanged(param_type, param->data, in_use, local_origin);
04467 return true;
04468 }
04469 return false;
04470 }
04471
04472 void LLViewerObject::parameterChanged(U16 param_type, bool local_origin)
04473 {
04474 ExtraParameter* param = getExtraParameterEntry(param_type);
04475 if (param)
04476 {
04477 parameterChanged(param_type, param->data, param->in_use, local_origin);
04478 }
04479 }
04480
04481 void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin)
04482 {
04483 if (local_origin)
04484 {
04485 LLViewerRegion* regionp = getRegion();
04486 if(!regionp) return;
04487
04488
04489 U8 tmp[MAX_OBJECT_PARAMS_SIZE];
04490 LLDataPackerBinaryBuffer dpb(tmp, MAX_OBJECT_PARAMS_SIZE);
04491 if (data->pack(dpb))
04492 {
04493 U32 datasize = (U32)dpb.getCurrentSize();
04494
04495 LLMessageSystem* msg = gMessageSystem;
04496 msg->newMessageFast(_PREHASH_ObjectExtraParams);
04497 msg->nextBlockFast(_PREHASH_AgentData);
04498 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
04499 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
04500 msg->nextBlockFast(_PREHASH_ObjectData);
04501 msg->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
04502
04503 msg->addU16Fast(_PREHASH_ParamType, param_type);
04504 msg->addBOOLFast(_PREHASH_ParamInUse, in_use);
04505
04506 msg->addU32Fast(_PREHASH_ParamSize, datasize);
04507 msg->addBinaryDataFast(_PREHASH_ParamData, tmp, datasize);
04508
04509 msg->sendReliable( regionp->getHost() );
04510 }
04511 else
04512 {
04513 llwarns << "Failed to send object extra parameters: " << param_type << llendl;
04514 }
04515 }
04516 }
04517
04518 void LLViewerObject::setDrawableState(U32 state, BOOL recursive)
04519 {
04520 if (mDrawable)
04521 {
04522 mDrawable->setState(state);
04523 }
04524 if (recursive)
04525 {
04526 for (U32 i = 0; i < mChildList.size(); i++)
04527 {
04528 mChildList[i]->setDrawableState(state, recursive);
04529 }
04530 }
04531 }
04532
04533 void LLViewerObject::clearDrawableState(U32 state, BOOL recursive)
04534 {
04535 if (mDrawable)
04536 {
04537 mDrawable->clearState(state);
04538 }
04539 if (recursive)
04540 {
04541 for (U32 i = 0; i < mChildList.size(); i++)
04542 {
04543 mChildList[i]->clearDrawableState(state, recursive);
04544 }
04545 }
04546 }
04547
04549
04551
04552
04553 BOOL LLViewerObject::permAnyOwner() const
04554 {
04555 if (isRootEdit())
04556 {
04557 return ((mFlags & FLAGS_OBJECT_ANY_OWNER) != 0);
04558 }
04559 else
04560 {
04561 return ((LLViewerObject*)getParent())->permAnyOwner();
04562 }
04563 }
04564
04565 BOOL LLViewerObject::permYouOwner() const
04566 {
04567 if (isRootEdit())
04568 {
04569 #ifdef HACKED_GODLIKE_VIEWER
04570 return TRUE;
04571 #else
04572 # ifdef TOGGLE_HACKED_GODLIKE_VIEWER
04573 if (!LLAppViewer::instance()->isInProductionGrid()
04574 && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
04575 {
04576 return TRUE;
04577 }
04578 # endif
04579 return ((mFlags & FLAGS_OBJECT_YOU_OWNER) != 0);
04580 #endif
04581 }
04582 else
04583 {
04584 return ((LLViewerObject*)getParent())->permYouOwner();
04585 }
04586 }
04587
04588
04589 BOOL LLViewerObject::permGroupOwner() const
04590 {
04591 if (isRootEdit())
04592 {
04593 return ((mFlags & FLAGS_OBJECT_GROUP_OWNED) != 0);
04594 }
04595 else
04596 {
04597 return ((LLViewerObject*)getParent())->permGroupOwner();
04598 }
04599 }
04600
04601
04602 BOOL LLViewerObject::permOwnerModify() const
04603 {
04604 if (isRootEdit())
04605 {
04606 #ifdef HACKED_GODLIKE_VIEWER
04607 return TRUE;
04608 #else
04609 # ifdef TOGGLE_HACKED_GODLIKE_VIEWER
04610 if (!LLAppViewer::instance()->isInProductionGrid()
04611 && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
04612 {
04613 return TRUE;
04614 }
04615 # endif
04616 return ((mFlags & FLAGS_OBJECT_OWNER_MODIFY) != 0);
04617 #endif
04618 }
04619 else
04620 {
04621 return ((LLViewerObject*)getParent())->permOwnerModify();
04622 }
04623 }
04624
04625
04626 BOOL LLViewerObject::permModify() const
04627 {
04628 if (isRootEdit())
04629 {
04630 #ifdef HACKED_GODLIKE_VIEWER
04631 return TRUE;
04632 #else
04633 # ifdef TOGGLE_HACKED_GODLIKE_VIEWER
04634 if (!LLAppViewer::instance()->isInProductionGrid()
04635 && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
04636 {
04637 return TRUE;
04638 }
04639 # endif
04640 return ((mFlags & FLAGS_OBJECT_MODIFY) != 0);
04641 #endif
04642 }
04643 else
04644 {
04645 return ((LLViewerObject*)getParent())->permModify();
04646 }
04647 }
04648
04649
04650 BOOL LLViewerObject::permCopy() const
04651 {
04652 if (isRootEdit())
04653 {
04654 #ifdef HACKED_GODLIKE_VIEWER
04655 return TRUE;
04656 #else
04657 # ifdef TOGGLE_HACKED_GODLIKE_VIEWER
04658 if (!LLAppViewer::instance()->isInProductionGrid()
04659 && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
04660 {
04661 return TRUE;
04662 }
04663 # endif
04664 return ((mFlags & FLAGS_OBJECT_COPY) != 0);
04665 #endif
04666 }
04667 else
04668 {
04669 return ((LLViewerObject*)getParent())->permCopy();
04670 }
04671 }
04672
04673
04674 BOOL LLViewerObject::permMove() const
04675 {
04676 if (isRootEdit())
04677 {
04678 #ifdef HACKED_GODLIKE_VIEWER
04679 return TRUE;
04680 #else
04681 # ifdef TOGGLE_HACKED_GODLIKE_VIEWER
04682 if (!LLAppViewer::instance()->isInProductionGrid()
04683 && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
04684 {
04685 return TRUE;
04686 }
04687 # endif
04688 return ((mFlags & FLAGS_OBJECT_MOVE) != 0);
04689 #endif
04690 }
04691 else
04692 {
04693 return ((LLViewerObject*)getParent())->permMove();
04694 }
04695 }
04696
04697
04698 BOOL LLViewerObject::permTransfer() const
04699 {
04700 if (isRootEdit())
04701 {
04702 #ifdef HACKED_GODLIKE_VIEWER
04703 return TRUE;
04704 #else
04705 # ifdef TOGGLE_HACKED_GODLIKE_VIEWER
04706 if (!LLAppViewer::instance()->isInProductionGrid()
04707 && (gAgent.getGodLevel() >= GOD_MAINTENANCE))
04708 {
04709 return TRUE;
04710 }
04711 # endif
04712 return ((mFlags & FLAGS_OBJECT_TRANSFER) != 0);
04713 #endif
04714 }
04715 else
04716 {
04717 return ((LLViewerObject*)getParent())->permTransfer();
04718 }
04719 }
04720
04721
04722
04723 BOOL LLViewerObject::allowOpen() const
04724 {
04725 return !flagInventoryEmpty() && (permYouOwner() || permModify());
04726 }
04727
04728 LLViewerObject::LLInventoryCallbackInfo::~LLInventoryCallbackInfo()
04729 {
04730 if (mListener)
04731 {
04732 mListener->clearVOInventoryListener();
04733 }
04734 }
04735
04736 void LLViewerObject::updateVolume(const LLVolumeParams& volume_params)
04737 {
04738 if (setVolume(volume_params, 1))
04739 {
04740
04741 sendShapeUpdate();
04742 markForUpdate(TRUE);
04743 }
04744 }
04745
04746 void LLViewerObject::markForUpdate(BOOL priority)
04747 {
04748 if (mDrawable.notNull())
04749 {
04750 gPipeline.markTextured(mDrawable);
04751 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, priority);
04752 }
04753 }
04754
04755 bool LLViewerObject::getIncludeInSearch() const
04756 {
04757 return ((mFlags & FLAGS_INCLUDE_IN_SEARCH) != 0);
04758 }
04759
04760 void LLViewerObject::setIncludeInSearch(bool include_in_search)
04761 {
04762 if (include_in_search)
04763 {
04764 mFlags |= FLAGS_INCLUDE_IN_SEARCH;
04765 }
04766 else
04767 {
04768 mFlags &= ~FLAGS_INCLUDE_IN_SEARCH;
04769 }
04770 }
04771
04772 void LLViewerObject::setRegion(LLViewerRegion *regionp)
04773 {
04774 llassert(regionp);
04775 mLatestRecvPacketID = 0;
04776 mRegionp = regionp;
04777
04778 for (child_list_t::iterator i = getChildren().begin(); i != getChildren().end(); ++i)
04779 {
04780 LLViewerObject* child = *i;
04781 child->setRegion(regionp);
04782 }
04783
04784 setChanged(MOVED | SILHOUETTE);
04785 updateDrawable(FALSE);
04786 }
04787
04788 bool LLViewerObject::specialHoverCursor() const
04789 {
04790 return (mFlags & FLAGS_USE_PHYSICS)
04791 || (mFlags & FLAGS_HANDLE_TOUCH)
04792 || (mClickAction != 0);
04793 }
04794
04795 void LLViewerObject::updateFlags()
04796 {
04797 LLViewerRegion* regionp = getRegion();
04798 if(!regionp) return;
04799 gMessageSystem->newMessage("ObjectFlagUpdate");
04800 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
04801 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
04802 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
04803 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, getLocalID() );
04804 gMessageSystem->addBOOLFast(_PREHASH_UsePhysics, usePhysics() );
04805 gMessageSystem->addBOOL("IsTemporary", flagTemporaryOnRez() );
04806 gMessageSystem->addBOOL("IsPhantom", flagPhantom() );
04807 gMessageSystem->addBOOL("CastsShadows", flagCastShadows() );
04808 gMessageSystem->sendReliable( regionp->getHost() );
04809 }
04810
04811 BOOL LLViewerObject::setFlags(U32 flags, BOOL state)
04812 {
04813 BOOL setit = FALSE;
04814 if (state)
04815 {
04816 if ((mFlags & flags) != flags)
04817 {
04818 mFlags |= flags;
04819 setit = TRUE;
04820 }
04821 }
04822 else
04823 {
04824 if ((mFlags & flags) != 0)
04825 {
04826 mFlags &= ~flags;
04827 setit = TRUE;
04828 }
04829 }
04830
04831
04832
04833
04834 {
04835 updateFlags();
04836 }
04837 return setit;
04838 }
04839
04840 BOOL LLViewerObject::lineSegmentIntersect(const LLVector3& start, LLVector3& end) const
04841 {
04842 return FALSE;
04843 }
04844
04845 void LLViewerObject::applyAngularVelocity(F32 dt)
04846 {
04847
04848 mRotTime += dt;
04849 LLVector3 ang_vel = getAngularVelocity();
04850 F32 omega = ang_vel.magVecSquared();
04851 F32 angle = 0.0f;
04852 LLQuaternion dQ;
04853 if (omega > 0.00001f)
04854 {
04855 omega = sqrt(omega);
04856 angle = omega * dt;
04857
04858 ang_vel *= 1.f/omega;
04859
04860 dQ.setQuat(angle, ang_vel);
04861
04862 setRotation(getRotation()*dQ);
04863 setChanged(MOVED | SILHOUETTE);
04864 }
04865 }
04866
04867 void LLViewerObject::resetRot()
04868 {
04869 mRotTime = 0.0f;
04870 }
04871
04872 U32 LLViewerObject::getPartitionType() const
04873 {
04874 return LLViewerRegion::PARTITION_NONE;
04875 }
04876
04877 void LLViewerObject::dirtySpatialGroup() const
04878 {
04879 if (mDrawable)
04880 {
04881 LLSpatialGroup* group = mDrawable->getSpatialGroup();
04882 if (group)
04883 {
04884 group->dirtyGeom();
04885 }
04886 }
04887 }
04888
04889 void LLViewerObject::dirtyMesh()
04890 {
04891 if (mDrawable)
04892 {
04893 LLSpatialGroup* group = mDrawable->getSpatialGroup();
04894 if (group)
04895 {
04896 group->dirtyMesh();
04897 }
04898 }
04899 }
04900
04901 F32 LLAlphaObject::getPartSize(S32 idx)
04902 {
04903 return 0.f;
04904 }
04905
04906
04907 void LLStaticViewerObject::updateDrawable(BOOL force_damped)
04908 {
04909
04910 if (mDrawable.notNull())
04911 {
04912 mDrawable->updateXform(TRUE);
04913 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
04914 }
04915 clearChanged(SHIFTED);
04916 }