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