diff options
author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2017-06-07 14:23:49 +0100 |
---|---|---|
committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2017-06-07 14:23:49 +0100 |
commit | c9baf4c66157c601cc4d4e325c7843b3bf9a0cad (patch) | |
tree | 20c09129ce8e72b8731c6c109c9e2a600783df44 /indra | |
parent | 74957676fc0b05825abc3af907241479f06fa8c3 (diff) |
SL-691,SL-694 - viewer can animate objects based on server messaging. First end-to-end demo for animated objects.
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/newview/llcontrolavatar.cpp | 119 | ||||
-rw-r--r-- | indra/newview/llcontrolavatar.h | 50 | ||||
-rw-r--r-- | indra/newview/lldrawpoolavatar.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llviewermenu.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llviewermessage.cpp | 15 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 35 | ||||
-rw-r--r-- | indra/newview/llviewerobject.h | 11 | ||||
-rw-r--r-- | indra/newview/llviewerobjectlist.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llviewerobjectlist.h | 2 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 52 | ||||
-rw-r--r-- | indra/newview/llvoavatar.h | 8 | ||||
-rw-r--r-- | indra/newview/llvoavatarself.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llvograss.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 32 |
15 files changed, 305 insertions, 35 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b4e930d062..3787a25a9b 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -149,6 +149,7 @@ set(viewer_SOURCE_FILES llcommunicationchannel.cpp llcompilequeue.cpp llconfirmationmanager.cpp + llcontrolavatar.cpp llconversationlog.cpp llconversationloglist.cpp llconversationloglistitem.cpp @@ -769,6 +770,7 @@ set(viewer_HEADER_FILES llcommunicationchannel.h llcompilequeue.h llconfirmationmanager.h + llcontrolavatar.h llconversationlog.h llconversationloglist.h llconversationloglistitem.h diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp new file mode 100644 index 0000000000..1ecd3305ed --- /dev/null +++ b/indra/newview/llcontrolavatar.cpp @@ -0,0 +1,119 @@ +/** + * @file llcontrolavatar.cpp + * @brief Implementation for special dummy avatar used to drive rigged meshes. + * + * $LicenseInfo:firstyear=2017&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2017, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llcontrolavatar.h" +#include "llagent.h" // Get state values from here +#include "llviewerobjectlist.h" +#include "pipeline.h" +#include "llanimationstates.h" + +LLControlAvatar::LLControlAvatar(const LLUUID& id, const LLPCode pcode, LLViewerRegion* regionp) : + LLVOAvatar(id, pcode, regionp), + mPlaying(false) +{ + mIsControlAvatar = true; +} + +// virtual +LLControlAvatar::~LLControlAvatar() +{ +} + +void LLControlAvatar::matchTransform(LLVOVolume *obj) +{ + setPositionAgent(obj->getRenderPosition()); + //slamPosition(); + + LLQuaternion fix_axes_rot(-F_PI_BY_TWO, LLVector3(0,0,1)); + LLQuaternion obj_rot = obj->getRotation(); + LLQuaternion result_rot = fix_axes_rot * obj_rot; + setRotation(result_rot); + mRoot->setWorldRotation(result_rot); + mRoot->setPosition(obj->getRenderPosition()); +} + +// Based on LLViewerJointAttachment::setupDrawable(), without the attaching part. +void LLControlAvatar::updateGeom(LLVOVolume *obj) +{ + if (!obj->mDrawable) + return; + if (obj->mDrawable->isActive()) + { + obj->mDrawable->makeStatic(FALSE); + } + obj->mDrawable->makeActive(); + gPipeline.markMoved(obj->mDrawable); + gPipeline.markTextured(obj->mDrawable); // face may need to change draw pool to/from POOL_HUD + obj->mDrawable->setState(LLDrawable::USE_BACKLIGHT); + + LLViewerObject::const_child_list_t& child_list = obj->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* childp = *iter; + if (childp && childp->mDrawable.notNull()) + { + childp->mDrawable->setState(LLDrawable::USE_BACKLIGHT); + gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD + gPipeline.markMoved(childp->mDrawable); + } + } + + gPipeline.markRebuild(obj->mDrawable, LLDrawable::REBUILD_ALL, TRUE); + obj->markForUpdate(TRUE); + + matchTransform(obj); + //addAttachmentOverridesForObject(obj); +} + +LLControlAvatar *LLControlAvatar::createControlAvatar(LLVOVolume *obj) +{ + // TRIF Lifted from LLPreviewAnimation + LLControlAvatar *cav = (LLControlAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), CO_FLAG_CONTROL_AVATAR); + cav->createDrawable(&gPipeline); + cav->mIsDummy = TRUE; + cav->mSpecialRenderMode = 1; + //cav->setPositionAgent(obj->getRenderPosition()); + //cav->slamPosition(); + //cav->setRotation(obj->getRotation()); + cav->updateJointLODs(); + cav->updateGeometry(cav->mDrawable); + cav->startMotion(ANIM_AGENT_STAND, 5.0f); + cav->hideSkirt(); + + // stop extraneous animations + cav->stopMotion( ANIM_AGENT_HEAD_ROT, TRUE ); + cav->stopMotion( ANIM_AGENT_EYE, TRUE ); + cav->stopMotion( ANIM_AGENT_BODY_NOISE, TRUE ); + cav->stopMotion( ANIM_AGENT_BREATHE_ROT, TRUE ); + + // Sync up position/rotation with object + cav->matchTransform(obj); + + return cav; +} + diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h new file mode 100644 index 0000000000..c8b1039363 --- /dev/null +++ b/indra/newview/llcontrolavatar.h @@ -0,0 +1,50 @@ +/** + * @file llcontrolavatar.h + * @brief Special dummy avatar used to drive rigged meshes. + * + * $LicenseInfo:firstyear=2017&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2017, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_CONTROLAVATAR_H +#define LL_CONTROLAVATAR_H + +#include "llvoavatar.h" +#include "llvovolume.h" + +class LLControlAvatar: + public LLVOAvatar +{ + LOG_CLASS(LLControlAvatar); + +public: + LLControlAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); + virtual ~LLControlAvatar(); + + void matchTransform(LLVOVolume *obj); + void updateGeom(LLVOVolume *obj); + + static LLControlAvatar *createControlAvatar(LLVOVolume *obj); + + bool mPlaying; +}; + +#endif //LL_CONTROLAVATAR_H diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index b221221f16..fa4fd7c533 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -467,7 +467,8 @@ void LLDrawPoolAvatar::renderShadow(S32 pass) } LLVOAvatar *avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); - if (avatarp->isDead() || avatarp->mIsDummy || avatarp->mDrawable.isNull()) +// AXON fix + if (avatarp->isDead() || /*avatarp->mIsDummy ||*/ avatarp->mDrawable.isNull()) { return; } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index c68f6b8a15..eddbe16482 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -6907,7 +6907,7 @@ class LLAttachmentEnableDrop : public view_listener_t // Do not enable drop if all faces of object are not enabled if (object && LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES )) { - S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getState()); + S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getAttachmentState()); attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL); if (attachment) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 2b62ccd62f..7fd87f99d3 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -55,6 +55,7 @@ #include "llagentcamera.h" #include "llcallingcard.h" #include "llbuycurrencyhtml.h" +#include "llcontrolavatar.h" #include "llfirstuse.h" #include "llfloaterbump.h" #include "llfloaterbuyland.h" @@ -5099,22 +5100,28 @@ void process_object_animation(LLMessageSystem *mesgsys, void **user_data) S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationList); LL_WARNS() << "AXON handle object animation here, num_blocks " << num_blocks << LL_ENDL; - //avatarp->mSignaledAnimations.clear(); + LLControlAvatar *avatarp = volp->mControlAvatar; + if (!avatarp->mPlaying) + { + avatarp->mPlaying = true; + avatarp->updateGeom(volp); + } + avatarp->mSignaledAnimations.clear(); volp->setDebugText(llformat("Animations %d", num_blocks)); for( S32 i = 0; i < num_blocks; i++ ) { mesgsys->getUUIDFast(_PREHASH_AnimationList, _PREHASH_AnimID, animation_id, i); mesgsys->getS32Fast(_PREHASH_AnimationList, _PREHASH_AnimSequenceID, anim_sequence_id, i); - //avatarp->mSignaledAnimations[animation_id] = anim_sequence_id; + avatarp->mSignaledAnimations[animation_id] = anim_sequence_id; LL_INFOS() << "AXON got object animation request for object " << uuid << " animation id " << animation_id << LL_ENDL; } - if (num_blocks) + if (num_blocks >= 0) { LL_INFOS() << "AXON process animation state changes here" << LL_ENDL; - //avatarp->processAnimationStateChanges(); + avatarp->processAnimationStateChanges(); } } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 030c0ca9f6..ff808ba079 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -60,6 +60,7 @@ #include "llbbox.h" #include "llbox.h" #include "llcylinder.h" +#include "llcontrolavatar.h" #include "lldrawable.h" #include "llface.h" #include "llfloaterproperties.h" @@ -138,7 +139,7 @@ const F32 PHYSICS_TIMESTEP = 1.f / 45.f; static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object"); // static -LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) +LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, S32 flags) { LLViewerObject *res = NULL; LL_RECORD_BLOCK_TIME(FTM_CREATE_OBJECT); @@ -166,6 +167,12 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco } res = gAgentAvatarp; } + else if (flags & CO_FLAG_CONTROL_AVATAR) + { + LLControlAvatar *avatar = new LLControlAvatar(id, pcode, regionp); + avatar->initInstance(); + res = avatar; + } else { LLVOAvatar *avatar = new LLVOAvatar(id, pcode, regionp); @@ -235,6 +242,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mText(), mHudText(""), mHudTextColor(LLColor4::white), + mControlAvatar(NULL), mLastInterpUpdateSecs(0.f), mLastMessageUpdateSecs(0.f), mLatestRecvPacketID(0), @@ -259,7 +267,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mRotTime(0.f), mAngularVelocityRot(), mPreviousRotation(), - mState(0), + mAttachmentState(0), mMedia(NULL), mClickAction(0), mObjectCost(0), @@ -369,11 +377,18 @@ void LLViewerObject::markDead() ((LLViewerObject *)getParent())->removeChild(this); } LLUUID mesh_id; + // FIXME AXON - need to do this for control avatars too if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id)) { // This case is needed for indirectly attached mesh objects. av->resetJointsOnDetach(mesh_id); } + if (mControlAvatar) + { + LLControlAvatar *av = mControlAvatar; + mControlAvatar = NULL; + av->markDead(); + } // Mark itself as dead mDead = TRUE; @@ -1378,7 +1393,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, U8 state; mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num ); - mState = state; + mAttachmentState = state; // ...new objects that should come in selected need to be added to the selected list mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0); @@ -1648,7 +1663,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, U8 state; mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num ); - mState = state; + mAttachmentState = state; break; } @@ -1671,7 +1686,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, U8 state; dp->unpackU8(state, "State"); - mState = state; + mAttachmentState = state; switch(update_type) { @@ -3857,7 +3872,7 @@ const LLVector3 LLViewerObject::getRenderPosition() const if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED)) { LLVOAvatar* avatar = getAvatar(); - if (avatar) + if (avatar && !mControlAvatar) { return avatar->getPositionAgent(); } @@ -3993,6 +4008,10 @@ void LLViewerObject::setPosition(const LLVector3 &pos, BOOL damped) // position caches need to be up to date on root objects updatePositionCaches(); } + if (mControlAvatar) + { + mControlAvatar->matchTransform(dynamic_cast<LLVOVolume*>(this)); + } } void LLViewerObject::setPositionGlobal(const LLVector3d &pos_global, BOOL damped) @@ -6358,6 +6377,10 @@ const std::string& LLViewerObject::getAttachmentItemName() const //virtual LLVOAvatar* LLViewerObject::getAvatar() const { + if (mControlAvatar) + { + return mControlAvatar; + } if (isAttachment()) { LLViewerObject* vobj = (LLViewerObject*) getParent(); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 24fcf0517e..e727567957 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -47,6 +47,7 @@ class LLAgent; // TODO: Get rid of this. class LLAudioSource; class LLAudioSourceVO; class LLColor4; +class LLControlAvatar; class LLDataPacker; class LLDataPackerBinaryBuffer; class LLDrawable; @@ -374,7 +375,7 @@ public: void sendShapeUpdate(); - U8 getState() { return mState; } + U8 getAttachmentState() { return mAttachmentState; } F32 getAppAngle() const { return mAppAngle; } F32 getPixelArea() const { return mPixelArea; } @@ -683,6 +684,8 @@ public: static BOOL sUseSharedDrawables; + LLPointer<LLControlAvatar> mControlAvatar; + protected: // delete an item in the inventory, but don't tell the // server. This is used internally by remove, update, and @@ -693,8 +696,10 @@ protected: // updateInventory. void doUpdateInventory(LLPointer<LLViewerInventoryItem>& item, U8 key, bool is_new); + // Flags for createObject + static const S32 CO_FLAG_CONTROL_AVATAR = 1 << 1; - static LLViewerObject *createObject(const LLUUID &id, LLPCode pcode, LLViewerRegion *regionp); + static LLViewerObject *createObject(const LLUUID &id, LLPCode pcode, LLViewerRegion *regionp, S32 flags = 0); BOOL setData(const U8 *datap, const U32 data_size); @@ -782,7 +787,7 @@ protected: LLQuaternion mAngularVelocityRot; // accumulated rotation from the angular velocity computations LLQuaternion mPreviousRotation; - U8 mState; // legacy + U8 mAttachmentState; // this encodes the attachment id in a somewhat complex way. 0 if not an attachment. LLViewerObjectMedia* mMedia; // NULL if no media associated U8 mClickAction; F32 mObjectCost; //resource cost of this object or -1 if unknown diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 8f98d66c0c..1f99119d82 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1942,12 +1942,12 @@ void LLViewerObjectList::resetObjectBeacons() mDebugBeacons.clear(); } -LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp) +LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp, S32 flags) { LLUUID fullid; fullid.generate(); - LLViewerObject *objectp = LLViewerObject::createObject(fullid, pcode, regionp); + LLViewerObject *objectp = LLViewerObject::createObject(fullid, pcode, regionp, flags); if (!objectp) { // LL_WARNS() << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << LL_ENDL; diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 94c751acc6..72b2b99004 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -67,7 +67,7 @@ public: inline LLViewerObject *getObject(const S32 index); inline LLViewerObject *findObject(const LLUUID &id); - LLViewerObject *createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp); // Create a viewer-side object + LLViewerObject *createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp, S32 flags = 0); // Create a viewer-side object LLViewerObject *createObjectFromCache(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id); LLViewerObject *createObject(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id, const LLHost &sender); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 3968266c27..7ba264f35a 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -44,6 +44,7 @@ #include "llavatarnamecache.h" #include "llavatarpropertiesprocessor.h" #include "llavatarrendernotifier.h" +#include "llcontrolavatar.h" #include "llexperiencecache.h" #include "llphysicsmotion.h" #include "llviewercontrol.h" @@ -663,7 +664,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mLastUpdateRequestCOFVersion(-1), mLastUpdateReceivedCOFVersion(-1), mCachedMuteListUpdateTime(0), - mCachedInMuteList(false) + mCachedInMuteList(false), + mIsControlAvatar(false) { LL_DEBUGS("AvatarRender") << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << LL_ENDL; @@ -1942,7 +1944,7 @@ void LLVOAvatar::resetSkeleton(bool reset_animations) //----------------------------------------------------------------------------- void LLVOAvatar::releaseMeshData() { - if (sInstances.size() < AVATAR_RELEASE_THRESHOLD || mIsDummy) + if (sInstances.size() < AVATAR_RELEASE_THRESHOLD)// || mIsDummy) { return; } @@ -2738,7 +2740,8 @@ void LLVOAvatar::idleUpdateLoadingEffect() LLPartData::LL_PART_EMISSIVE_MASK | // LLPartData::LL_PART_FOLLOW_SRC_MASK | LLPartData::LL_PART_TARGET_POS_MASK ); - if (!isTooComplex()) // do not generate particles for overly-complex avatars + // TRIF skip cloud effects for dummy avs as well + if (!mIsDummy && !isTooComplex()) // do not generate particles for overly-complex avatars { setParticleSource(particle_parameters, getID()); } @@ -3530,7 +3533,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) } // change animation time quanta based on avatar render load - if (!isSelf() && !mIsDummy) + if (!isSelf())// && !mIsDummy) { F32 time_quantum = clamp_rescale((F32)sInstances.size(), 10.f, 35.f, 0.f, 0.25f); F32 pixel_area_scale = clamp_rescale(mPixelArea, 100, 5000, 1.f, 0.f); @@ -3652,7 +3655,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) //-------------------------------------------------------------------- // Propagate viewer object rotation to root of avatar //-------------------------------------------------------------------- - if (!isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS)) + // FIXME TRIF - just skipping this for now for all dummy avs + if (!mIsDummy && !isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS)) { LLQuaternion iQ; LLVector3 upDir( 0.0f, 0.0f, 1.0f ); @@ -4041,7 +4045,7 @@ void LLVOAvatar::updateVisibility() if (mIsDummy) { - visible = TRUE; + visible = FALSE; } else if (mDrawable.isNull()) { @@ -4356,7 +4360,7 @@ U32 LLVOAvatar::renderSkinned() { if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) { - if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy) + if (isTextureVisible(TEX_HEAD_BAKED))// || mIsDummy) { LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); if (head_mesh) @@ -4366,7 +4370,7 @@ U32 LLVOAvatar::renderSkinned() first_pass = FALSE; } } - if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy) + if (isTextureVisible(TEX_UPPER_BAKED))// || mIsDummy) { LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); if (upper_mesh) @@ -4376,7 +4380,7 @@ U32 LLVOAvatar::renderSkinned() first_pass = FALSE; } - if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy) + if (isTextureVisible(TEX_LOWER_BAKED))// || mIsDummy) { LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); if (lower_mesh) @@ -4435,6 +4439,8 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) } // Can't test for baked hair being defined, since that won't always be the case (not all viewers send baked hair) // TODO: 1.25 will be able to switch this logic back to calling isTextureVisible(); + if (!mIsDummy) + { if ( (getImage(TEX_HAIR_BAKED, 0) && getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE) || LLDrawPoolAlpha::sShowDebugAlpha) { @@ -4445,6 +4451,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) } first_pass = FALSE; } + } if (LLPipeline::sImpostorRender) { gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); @@ -5521,12 +5528,26 @@ void LLVOAvatar::rebuildAttachmentOverrides() //----------------------------------------------------------------------------- void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo) { - LLVOAvatar *av = vo->getAvatarAncestor(); + bool non_attached_case = false; + // FIXME TRIF - will this work if vo has child objects? + if (vo->mControlAvatar) + { + non_attached_case = true; + } + LLVOAvatar *av; + if (non_attached_case) + { + av = vo->mControlAvatar; + } + else + { + av = vo->getAvatarAncestor(); if (!av || (av != this)) { LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL; return; } + } LLScopedContextString str("addAttachmentOverridesForObject " + av->getFullname()); @@ -5554,7 +5575,7 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo) LLUUID currentId = vobj->getVolume()->getParams().getSculptID(); const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj ); - if ( vobj && vobj->isAttachment() && vobj->isMesh() && pSkinData ) + if ( vobj && (vobj->isAttachment()||non_attached_case) && vobj->isMesh() && pSkinData ) { const int bindCnt = pSkinData->mAlternateBindMatrix.size(); const int jointCnt = pSkinData->mJointNames.size(); @@ -5738,6 +5759,7 @@ void LLVOAvatar::showAttachmentOverrides(bool verbose) const //----------------------------------------------------------------------------- // resetJointsOnDetach //----------------------------------------------------------------------------- +// TRIF handle NPC case void LLVOAvatar::resetJointsOnDetach(LLViewerObject *vo) { LLVOAvatar *av = vo->getAvatarAncestor(); @@ -5766,6 +5788,7 @@ void LLVOAvatar::resetJointsOnDetach(LLViewerObject *vo) //----------------------------------------------------------------------------- // resetJointsOnDetach //----------------------------------------------------------------------------- +// TRIF handle NPC case void LLVOAvatar::resetJointsOnDetach(const LLUUID& mesh_id) { //Subsequent joints are relative to pelvis @@ -6288,7 +6311,7 @@ void LLVOAvatar::removeChild(LLViewerObject *childp) LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* viewer_object) { - S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getState()); + S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getAttachmentState()); // This should never happen unless the server didn't process the attachment point // correctly, but putting this check in here to be safe. @@ -6812,6 +6835,11 @@ BOOL LLVOAvatar::isVisible() const // Determine if we have enough avatar data to render bool LLVOAvatar::getIsCloud() const { + if (mIsDummy) + { + return false; + } + return ( ((const_cast<LLVOAvatar*>(this))->visualParamWeightsAreDefault())// Do we have a shape? || ( !isTextureDefined(TEX_LOWER_BAKED) || !isTextureDefined(TEX_UPPER_BAKED) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index bd89d4ef23..2832f940f4 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -233,6 +233,8 @@ public: public: virtual bool isSelf() const { return false; } // True if this avatar is for this viewer's agent + virtual bool isControlAvatar() const { return mIsControlAvatar; } // True if this avatar is a control av (no associated user) + private: //aligned members LL_ALIGN_16(LLVector4a mImpostorExtents[2]); @@ -441,6 +443,12 @@ public: VisualMuteSettings mVisuallyMuteSetting; // Always or never visually mute this AV //-------------------------------------------------------------------- + // NPC status + //-------------------------------------------------------------------- +public: + bool mIsControlAvatar; + + //-------------------------------------------------------------------- // Morph masks //-------------------------------------------------------------------- public: diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index aa5d82a096..2137bf4eb3 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -2789,7 +2789,7 @@ BOOL LLVOAvatarSelf::needsRenderBeam() // don't render selection beam on hud objects is_touching_or_grabbing = FALSE; } - return is_touching_or_grabbing || (mState & AGENT_STATE_EDITING && LLSelectMgr::getInstance()->shouldShowSelection()); + return is_touching_or_grabbing || (getAttachmentState() & AGENT_STATE_EDITING && LLSelectMgr::getInstance()->shouldShowSelection()); } // static diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index de63a3963c..e7e4e6f228 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -92,7 +92,8 @@ LLVOGrass::~LLVOGrass() void LLVOGrass::updateSpecies() { - mSpecies = mState; + // TRIF is grass still even supported? This use of state seems odd. + mSpecies = getAttachmentState(); if (!sSpeciesTable.count(mSpecies)) { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index ed0205704f..a2f417a5cc 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -76,8 +76,13 @@ #include "lldatapacker.h" #include "llviewershadermgr.h" #include "llvoavatar.h" +#include "llcontrolavatar.h" +#include "llvoavatarself.h" #include "llvocache.h" #include "llmaterialmgr.h" +#include "llanimationstates.h" +#include "llinventorytype.h" +#include "llviewerinventory.h" const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; @@ -3383,7 +3388,7 @@ void LLVOVolume::updateRadius() BOOL LLVOVolume::isAttachment() const { - return mState != 0 ; + return mAttachmentState != 0 ; } BOOL LLVOVolume::isHUDAttachment() const @@ -3391,7 +3396,7 @@ BOOL LLVOVolume::isHUDAttachment() const // *NOTE: we assume hud attachment points are in defined range // since this range is constant for backwards compatibility // reasons this is probably a reasonable assumption to make - S32 attachment_id = ATTACHMENT_ID_FROM_STATE(mState); + S32 attachment_id = ATTACHMENT_ID_FROM_STATE(mAttachmentState); return ( attachment_id >= 31 && attachment_id <= 38 ); } @@ -4825,10 +4830,31 @@ 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->mControlAvatar) + { + vobj->mControlAvatar = LLControlAvatar::createControlAvatar(vobj); + vobj->mControlAvatar->addAttachmentOverridesForObject(vobj); + vobj->requestInventory(); + } + if (vobj->mControlAvatar) + { + pAvatarVO = vobj->mControlAvatar; + } + } + bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); + // TRIF why this variable? Only different from rigged if + // there are no LLFaces associated with the drawable. bool is_rigged = false; + // TRIF handle NPC case if (rigged && pAvatarVO) { pAvatarVO->addAttachmentOverridesForObject(vobj); @@ -4855,7 +4881,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //sum up face verts and indices drawablep->updateFaceSize(i); - if (rigged) + if (rigged || (vobj->mControlAvatar && vobj->mControlAvatar->mPlaying)) { if (!facep->isState(LLFace::RIGGED)) { //completely reset vertex buffer |