diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index 61055f6f586aeed00444e7720c6b228f88bdfac2..26c4865e4c713db352951a8dff75bcdaa8e7c34f 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -48,15 +48,15 @@ LLControlAvatar::~LLControlAvatar() void LLControlAvatar::matchVolumeTransform() { - setPositionAgent(mVolp->getRenderPosition()); + setPositionAgent(mRootVolp->getRenderPosition()); //slamPosition(); LLQuaternion fix_axes_rot(-F_PI_BY_TWO, LLVector3(0,0,1)); - LLQuaternion obj_rot = mVolp->getRotation(); + LLQuaternion obj_rot = mRootVolp->getRotation(); LLQuaternion result_rot = fix_axes_rot * obj_rot; setRotation(result_rot); mRoot->setWorldRotation(result_rot); - mRoot->setPosition(mVolp->getRenderPosition()); + mRoot->setPosition(mRootVolp->getRenderPosition()); } void LLControlAvatar::setGlobalScale(F32 scale) @@ -91,18 +91,18 @@ void LLControlAvatar::recursiveScaleJoint(LLJoint* joint, F32 factor) // Based on LLViewerJointAttachment::setupDrawable(), without the attaching part. void LLControlAvatar::updateVolumeGeom() { - if (!mVolp->mDrawable) + if (!mRootVolp->mDrawable) return; - if (mVolp->mDrawable->isActive()) + if (mRootVolp->mDrawable->isActive()) { - mVolp->mDrawable->makeStatic(FALSE); + mRootVolp->mDrawable->makeStatic(FALSE); } - mVolp->mDrawable->makeActive(); - gPipeline.markMoved(mVolp->mDrawable); - gPipeline.markTextured(mVolp->mDrawable); // face may need to change draw pool to/from POOL_HUD - mVolp->mDrawable->setState(LLDrawable::USE_BACKLIGHT); + mRootVolp->mDrawable->makeActive(); + gPipeline.markMoved(mRootVolp->mDrawable); + gPipeline.markTextured(mRootVolp->mDrawable); // face may need to change draw pool to/from POOL_HUD + mRootVolp->mDrawable->setState(LLDrawable::USE_BACKLIGHT); - LLViewerObject::const_child_list_t& child_list = mVolp->getChildren(); + LLViewerObject::const_child_list_t& child_list = mRootVolp->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); ++iter) { @@ -115,8 +115,8 @@ void LLControlAvatar::updateVolumeGeom() } } - gPipeline.markRebuild(mVolp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); - mVolp->markForUpdate(TRUE); + gPipeline.markRebuild(mRootVolp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); + mRootVolp->markForUpdate(TRUE); // Note that attachment overrides aren't needed here, have already // been applied at the time the mControlAvatar was created, in @@ -148,7 +148,7 @@ LLControlAvatar *LLControlAvatar::createControlAvatar(LLVOVolume *obj) // AXON Lifted from LLPreviewAnimation LLControlAvatar *cav = (LLControlAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), CO_FLAG_CONTROL_AVATAR); - cav->mVolp = obj; + cav->mRootVolp = obj; cav->createDrawable(&gPipeline); cav->mIsDummy = TRUE; diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h index f29388e035d5f5dec4efa11509d667559c6f5fd4..bb54cc5b2d573c72f5e7ca3f6b8b0a3c70137a49 100644 --- a/indra/newview/llcontrolavatar.h +++ b/indra/newview/llcontrolavatar.h @@ -50,7 +50,7 @@ class LLControlAvatar: F32 mGlobalScale; - LLVOVolume *mVolp; + LLVOVolume *mRootVolp; }; #endif //LL_CONTROLAVATAR_H diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index ff33fe79fac86d761d65ca7364446e78ed599c95..f8cdb5bf928fc77e0025cdb236dc9095691aa6ef 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -5097,7 +5097,7 @@ void process_object_animation(LLMessageSystem *mesgsys, void **user_data) return; } - LLControlAvatar *avatarp = volp->mControlAvatar; + LLControlAvatar *avatarp = volp->getControlAvatar(); if (!avatarp) { LL_WARNS() << "AXON no control avatar, ignoring" << LL_ENDL; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index f1c7cfae0d922a703825b82d6e9ef21330aea2a3..bd0e864f80c15654b2ad911395f0f4f174936849 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -383,11 +383,9 @@ void LLViewerObject::markDead() // This case is needed for indirectly attached mesh objects. av->resetJointsOnDetach(mesh_id); } - if (mControlAvatar) + if (getControlAvatar()) { - LLControlAvatar *av = mControlAvatar; - mControlAvatar = NULL; - av->markDead(); + unlinkControlAvatar(); } // Mark itself as dead @@ -2917,6 +2915,55 @@ void LLViewerObject::fetchInventoryFromServer() } } +LLControlAvatar *LLViewerObject::getControlAvatar() +{ + return getRootEdit()->mControlAvatar.get(); +} + +LLControlAvatar *LLViewerObject::getControlAvatar() const +{ + return getRootEdit()->mControlAvatar.get(); +} + +void LLViewerObject::linkControlAvatar() +{ + if (!getControlAvatar() && isRootEdit()) + { + LLVOVolume *volp = dynamic_cast<LLVOVolume*>(this); + if (!volp) + { + LL_WARNS() << "called with null or non-volume object" << LL_ENDL; + return; + } + mControlAvatar = LLControlAvatar::createControlAvatar(volp); + } + if (getControlAvatar()) + { + getControlAvatar()->addAttachmentOverridesForObject(this); + } + else + { + LL_WARNS() << "no control avatar found!" << LL_ENDL; + } +} + +void LLViewerObject::unlinkControlAvatar() +{ + if (getControlAvatar()) + { + getControlAvatar()->resetJointsOnDetach(this); + } + if (isRootEdit()) + { + // This will remove the entire linkset from the control avatar + LLControlAvatar *av = mControlAvatar; + mControlAvatar = NULL; + av->markDead(); + } + // For non-root prims, removing from the linkset will + // automatically remove the control avatar connection. +} + struct LLFilenameAndTask { LLUUID mTaskID; @@ -3872,7 +3919,7 @@ const LLVector3 LLViewerObject::getRenderPosition() const if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED)) { LLVOAvatar* avatar = getAvatar(); - if (avatar && !mControlAvatar) + if (avatar && !getControlAvatar()) { return avatar->getPositionAgent(); } @@ -4008,9 +4055,9 @@ void LLViewerObject::setPosition(const LLVector3 &pos, BOOL damped) // position caches need to be up to date on root objects updatePositionCaches(); } - if (mControlAvatar) + if (getControlAvatar() && isRootEdit()) { - mControlAvatar->matchVolumeTransform(); + getControlAvatar()->matchVolumeTransform(); } } @@ -6377,9 +6424,9 @@ const std::string& LLViewerObject::getAttachmentItemName() const //virtual LLVOAvatar* LLViewerObject::getAvatar() const { - if (mControlAvatar) + if (getControlAvatar()) { - return mControlAvatar; + return getControlAvatar(); } if (isAttachment()) { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index e727567957a31c4be5f7d387630c0f0ed9dfa393..bef00e2bab8e70c4aaa0889aac1c163bd0f365b4 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -684,6 +684,17 @@ class LLViewerObject static BOOL sUseSharedDrawables; +public: + // Returns mControlAvatar for the edit root prim of this linkset + LLControlAvatar *getControlAvatar(); + LLControlAvatar *getControlAvatar() const; + + // Create or connect to an existing control av as applicable + void linkControlAvatar(); + // Remove any reference to control av for this prim + void unlinkControlAvatar(); + +private: LLPointer<LLControlAvatar> mControlAvatar; protected: diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index beb6f08899f06eaaeec0b8271a0fda928bc0bf73..c268ab5f3c6bd9454691a074a9fbfea5d4c811b6 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -3433,7 +3433,7 @@ void LLVOAvatar::updateDebugText() { LLControlAvatar *control_av = dynamic_cast<LLControlAvatar*>(this); // Try to get name from inventory of associated object - LLVOVolume *volp = control_av->mVolp; + LLVOVolume *volp = control_av->mRootVolp; if (volp) { volp->requestInventory(); // AXON should be a no-op if already requested or fetched? @@ -5565,14 +5565,14 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo) { bool non_attached_case = false; // FIXME AXON - will this work if vo has child objects? - if (vo->mControlAvatar) + if (vo->getControlAvatar()) { non_attached_case = true; } LLVOAvatar *av; if (non_attached_case) { - av = vo->mControlAvatar; + av = vo->getControlAvatar(); } else { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 150769845b3e16067fa6c7edbfe4c2cbc097035c..da24d9f9c27fa846dfe91110d82607fe533e5348 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3311,6 +3311,10 @@ void LLVOVolume::setExtendedMeshFlags(U32 flags) bool LLVOVolume::canBeAnimatedObject() const { if (!isMesh()) + { + return false; + } + if (isAttachment()) { return false; } @@ -4830,20 +4834,24 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) vobj->isMesh() && gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); - bool rigged_non_attachment = !vobj->isAttachment() && - vobj->isMesh() && - gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); - - if (rigged_non_attachment) + if (vobj->isAnimatedObject()) { - if (!vobj->mControlAvatar) + if (!vobj->getControlAvatar()) { - vobj->mControlAvatar = LLControlAvatar::createControlAvatar(vobj); - vobj->mControlAvatar->addAttachmentOverridesForObject(vobj); + vobj->linkControlAvatar(); } - if (vobj->mControlAvatar) + if (vobj->getControlAvatar()) + { + pAvatarVO = vobj->getControlAvatar(); + } + } + else + { + // Not animated but has a control avatar - probably + // the checkbox has changed since the last rebuild. + if (vobj->getControlAvatar()) { - pAvatarVO = vobj->mControlAvatar; + vobj->unlinkControlAvatar(); } } @@ -4880,7 +4888,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //sum up face verts and indices drawablep->updateFaceSize(i); - if (rigged || (vobj->mControlAvatar && vobj->mControlAvatar->mPlaying)) + if (rigged || (vobj->getControlAvatar() && vobj->getControlAvatar()->mPlaying)) { if (!facep->isState(LLFace::RIGGED)) { //completely reset vertex buffer