summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2017-06-07 14:23:49 +0100
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2017-06-07 14:23:49 +0100
commitc9baf4c66157c601cc4d4e325c7843b3bf9a0cad (patch)
tree20c09129ce8e72b8731c6c109c9e2a600783df44 /indra
parent74957676fc0b05825abc3af907241479f06fa8c3 (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.txt2
-rw-r--r--indra/newview/llcontrolavatar.cpp119
-rw-r--r--indra/newview/llcontrolavatar.h50
-rw-r--r--indra/newview/lldrawpoolavatar.cpp3
-rw-r--r--indra/newview/llviewermenu.cpp2
-rw-r--r--indra/newview/llviewermessage.cpp15
-rw-r--r--indra/newview/llviewerobject.cpp35
-rw-r--r--indra/newview/llviewerobject.h11
-rw-r--r--indra/newview/llviewerobjectlist.cpp4
-rw-r--r--indra/newview/llviewerobjectlist.h2
-rw-r--r--indra/newview/llvoavatar.cpp52
-rw-r--r--indra/newview/llvoavatar.h8
-rw-r--r--indra/newview/llvoavatarself.cpp2
-rw-r--r--indra/newview/llvograss.cpp3
-rw-r--r--indra/newview/llvovolume.cpp32
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