Merge axon

master
Ansariel 2017-09-20 01:09:14 +02:00
commit 01d8e7e347
64 changed files with 2636 additions and 784 deletions

View File

@ -236,6 +236,14 @@
<boolean>false</boolean> <boolean>false</boolean>
</map> </map>
<key>ObjectAnimation</key>
<map>
<key>flavor</key>
<string>template</string>
<key>trusted-sender</key>
<boolean>false</boolean>
</map>
<key>AvatarAppearance</key> <key>AvatarAppearance</key>
<map> <map>
<key>flavor</key> <key>flavor</key>

View File

@ -150,10 +150,13 @@ public:
BOOL isPaused() const { return mPaused; } BOOL isPaused() const { return mPaused; }
void setTimeStep(F32 step); void setTimeStep(F32 step);
F32 getTimeStep() const { return mTimeStep; }
void setTimeFactor(F32 time_factor); void setTimeFactor(F32 time_factor);
F32 getTimeFactor() const { return mTimeFactor; } F32 getTimeFactor() const { return mTimeFactor; }
F32 getAnimTime() const { return mAnimTime; }
// <FS:Ansariel> Fix impostered animation speed based on a fix by Henri Beauchamp // <FS:Ansariel> Fix impostered animation speed based on a fix by Henri Beauchamp
void setUpdateFactor(F32 update_factor) { mUpdateFactor = update_factor; } void setUpdateFactor(F32 update_factor) { mUpdateFactor = update_factor; }

View File

@ -157,6 +157,7 @@ const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT;
// attachment constants // attachment constants
const S32 MAX_AGENT_ATTACHMENTS = 38; const S32 MAX_AGENT_ATTACHMENTS = 38;
const S32 MAX_AGENT_ANIMATED_OBJECT_ATTACHMENTS = 1;
const U8 ATTACHMENT_ADD = 0x80; const U8 ATTACHMENT_ADD = 0x80;
// god levels // god levels

View File

@ -1,5 +1,4 @@
/** /**
* @file llvolume.cpp * @file llvolume.cpp
* *
* $LicenseInfo:firstyear=2002&license=viewerlgpl$ * $LicenseInfo:firstyear=2002&license=viewerlgpl$

View File

@ -818,6 +818,7 @@ char const* const _PREHASH_StateSave = LLMessageStringTable::getInstance()->getS
char const* const _PREHASH_RoleData = LLMessageStringTable::getInstance()->getString("RoleData"); char const* const _PREHASH_RoleData = LLMessageStringTable::getInstance()->getString("RoleData");
char const* const _PREHASH_AgentAnimation = LLMessageStringTable::getInstance()->getString("AgentAnimation"); char const* const _PREHASH_AgentAnimation = LLMessageStringTable::getInstance()->getString("AgentAnimation");
char const* const _PREHASH_AvatarAnimation = LLMessageStringTable::getInstance()->getString("AvatarAnimation"); char const* const _PREHASH_AvatarAnimation = LLMessageStringTable::getInstance()->getString("AvatarAnimation");
char const* const _PREHASH_ObjectAnimation = LLMessageStringTable::getInstance()->getString("ObjectAnimation");
char const* const _PREHASH_LogDwellTime = LLMessageStringTable::getInstance()->getString("LogDwellTime"); char const* const _PREHASH_LogDwellTime = LLMessageStringTable::getInstance()->getString("LogDwellTime");
char const* const _PREHASH_ParcelGodMarkAsContent = LLMessageStringTable::getInstance()->getString("ParcelGodMarkAsContent"); char const* const _PREHASH_ParcelGodMarkAsContent = LLMessageStringTable::getInstance()->getString("ParcelGodMarkAsContent");
char const* const _PREHASH_UsePhysics = LLMessageStringTable::getInstance()->getString("UsePhysics"); char const* const _PREHASH_UsePhysics = LLMessageStringTable::getInstance()->getString("UsePhysics");

View File

@ -818,6 +818,7 @@ extern char const* const _PREHASH_StateSave;
extern char const* const _PREHASH_RoleData; extern char const* const _PREHASH_RoleData;
extern char const* const _PREHASH_AgentAnimation; extern char const* const _PREHASH_AgentAnimation;
extern char const* const _PREHASH_AvatarAnimation; extern char const* const _PREHASH_AvatarAnimation;
extern char const* const _PREHASH_ObjectAnimation;
extern char const* const _PREHASH_LogDwellTime; extern char const* const _PREHASH_LogDwellTime;
extern char const* const _PREHASH_ParcelGodMarkAsContent; extern char const* const _PREHASH_ParcelGodMarkAsContent;
extern char const* const _PREHASH_UsePhysics; extern char const* const _PREHASH_UsePhysics;

View File

@ -1607,6 +1607,8 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size)
return (size == 17); return (size == 17);
case PARAMS_LIGHT_IMAGE: case PARAMS_LIGHT_IMAGE:
return (size == 28); return (size == 28);
case PARAMS_EXTENDED_MESH:
return (size == 4);
} }
return FALSE; return FALSE;
@ -2034,3 +2036,67 @@ bool LLLightImageParams::fromLLSD(LLSD& sd)
return false; return false;
} }
//============================================================================
LLExtendedMeshParams::LLExtendedMeshParams()
{
mType = PARAMS_EXTENDED_MESH;
mFlags = 0;
}
BOOL LLExtendedMeshParams::pack(LLDataPacker &dp) const
{
dp.packU32(mFlags, "flags");
return TRUE;
}
BOOL LLExtendedMeshParams::unpack(LLDataPacker &dp)
{
dp.unpackU32(mFlags, "flags");
return TRUE;
}
bool LLExtendedMeshParams::operator==(const LLNetworkData& data) const
{
if (data.mType != PARAMS_EXTENDED_MESH)
{
return false;
}
const LLExtendedMeshParams *param = (const LLExtendedMeshParams*)&data;
if ( (param->mFlags != mFlags) )
{
return false;
}
return true;
}
void LLExtendedMeshParams::copy(const LLNetworkData& data)
{
const LLExtendedMeshParams *param = (LLExtendedMeshParams*)&data;
mFlags = param->mFlags;
}
LLSD LLExtendedMeshParams::asLLSD() const
{
LLSD sd;
sd["flags"] = LLSD::Integer(mFlags);
return sd;
}
bool LLExtendedMeshParams::fromLLSD(LLSD& sd)
{
if (sd.has("flags"))
{
setFlags( sd["flags"].asInteger());
return true;
}
return false;
}

View File

@ -114,6 +114,7 @@ public:
PARAMS_LIGHT_IMAGE = 0x40, PARAMS_LIGHT_IMAGE = 0x40,
PARAMS_RESERVED = 0x50, // Used on server-side PARAMS_RESERVED = 0x50, // Used on server-side
PARAMS_MESH = 0x60, PARAMS_MESH = 0x60,
PARAMS_EXTENDED_MESH = 0x70,
}; };
public: public:
@ -296,6 +297,27 @@ public:
}; };
class LLExtendedMeshParams : public LLNetworkData
{
protected:
U32 mFlags;
public:
static const U32 ANIMATED_MESH_ENABLED_FLAG = 0x1 << 0;
LLExtendedMeshParams();
/*virtual*/ BOOL pack(LLDataPacker &dp) const;
/*virtual*/ BOOL unpack(LLDataPacker &dp);
/*virtual*/ bool operator==(const LLNetworkData& data) const;
/*virtual*/ void copy(const LLNetworkData& data);
LLSD asLLSD() const;
operator LLSD() const { return asLLSD(); }
bool fromLLSD(LLSD& sd);
void setFlags(const U32& flags) { mFlags = flags; }
U32 getFlags() const { return mFlags; }
};
// This code is not naming-standards compliant. Leaving it like this for // This code is not naming-standards compliant. Leaving it like this for
// now to make the connection to code in // now to make the connection to code in

View File

@ -256,6 +256,7 @@ set(viewer_SOURCE_FILES
llcommunicationchannel.cpp llcommunicationchannel.cpp
llcompilequeue.cpp llcompilequeue.cpp
llconfirmationmanager.cpp llconfirmationmanager.cpp
llcontrolavatar.cpp
llconversationlog.cpp llconversationlog.cpp
llconversationloglist.cpp llconversationloglist.cpp
llconversationloglistitem.cpp llconversationloglistitem.cpp
@ -1007,6 +1008,7 @@ set(viewer_HEADER_FILES
llcommunicationchannel.h llcommunicationchannel.h
llcompilequeue.h llcompilequeue.h
llconfirmationmanager.h llconfirmationmanager.h
llcontrolavatar.h
llconversationlog.h llconversationlog.h
llconversationloglist.h llconversationloglist.h
llconversationloglistitem.h llconversationloglistitem.h

View File

@ -50,7 +50,7 @@
</array> </array>
<key>tags</key> <key>tags</key>
<array> <array>
<string>AXON</string>
<!-- sample entry for debugging specific items <!-- sample entry for debugging specific items
<string>Avatar</string> <string>Avatar</string>
<string>Inventory</string> <string>Inventory</string>

View File

@ -3748,6 +3748,17 @@
<key>Backup</key> <key>Backup</key>
<integer>0</integer> <integer>0</integer>
</map> </map>
<key>DebugAnimatedObjects</key>
<map>
<key>Comment</key>
<string>Show info related to animated objects</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>DebugAvatarAppearanceMessage</key> <key>DebugAvatarAppearanceMessage</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
@ -13007,6 +13018,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<integer>0</integer> <integer>0</integer>
<key>Backup</key> <key>Backup</key>
<integer>0</integer> <integer>0</integer>
</map>
<key>RenderForceVolumeLOD</key>
<map>
<key>Comment</key>
<string>Override for all volume LODs</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>-1</integer>
</map> </map>
<key>RenderVolumeLODFactor</key> <key>RenderVolumeLODFactor</key>
<map> <map>

View File

@ -379,7 +379,7 @@ void FSFloaterObjectExport::addPrim(LLViewerObject* object, bool root)
{ {
if (object->isAttachment()) if (object->isAttachment())
{ {
prim["attachment_point"] = ATTACHMENT_ID_FROM_STATE(object->getState()); prim["attachment_point"] = ATTACHMENT_ID_FROM_STATE(object->getAttachmentState());
} }
} }
else else

View File

@ -893,10 +893,10 @@ void LLWearableHoldingPattern::onAllComplete()
// ++it) // ++it)
// { // {
// LLViewerObject *objectp = *it; // LLViewerObject *objectp = *it;
// if (!objectp->isAnimatedObject())
// {
// gAgentAvatarp->addAttachmentOverridesForObject(objectp); // gAgentAvatarp->addAttachmentOverridesForObject(objectp);
// } // }
//
// // Add new attachments to match those requested.
// LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL; // LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL;
// LLAgentWearables::userAttachMultipleAttachments(items_to_add); // LLAgentWearables::userAttachMultipleAttachments(items_to_add);
} }
@ -2752,8 +2752,11 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin(); it != objects_to_retain.end(); ++it) for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin(); it != objects_to_retain.end(); ++it)
{ {
LLViewerObject *objectp = *it; LLViewerObject *objectp = *it;
if (!objectp->isAnimatedObject())
{
gAgentAvatarp->addAttachmentOverridesForObject(objectp); gAgentAvatarp->addAttachmentOverridesForObject(objectp);
} }
}
// Add new attachments to match those requested. // Add new attachments to match those requested.
LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL; LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL;

View File

@ -670,6 +670,7 @@ static void settings_to_globals()
// </FS:Ansariel> // </FS:Ansariel>
LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures"); LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures");
LLVOVolume::sForceLOD = gSavedSettings.getS32("RenderForceVolumeLOD");
LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor"); LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor");
LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f; LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor"); LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
@ -823,7 +824,7 @@ LLAppViewer::LLAppViewer()
// //
LLLoginInstance::instance().setUpdaterService(mUpdater.get()); LLLoginInstance::instance().setUpdaterService(mUpdater.get());
LLLoginInstance::instance().setPlatformInfo(gPlatform, getOSInfo().getOSVersionString()); LLLoginInstance::instance().setPlatformInfo(gPlatform, getOSInfo().getOSVersionString(), getOSInfo().getOSStringSimple());
} }
LLAppViewer::~LLAppViewer() LLAppViewer::~LLAppViewer()

View File

@ -0,0 +1,406 @@
/**
* @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"
#include "llviewercontrol.h"
#include "llmeshrepository.h"
LLControlAvatar::LLControlAvatar(const LLUUID& id, const LLPCode pcode, LLViewerRegion* regionp) :
LLVOAvatar(id, pcode, regionp),
mPlaying(false),
mGlobalScale(1.0f),
mMarkedForDeath(false)
{
mIsControlAvatar = true;
mEnableDefaultMotions = false;
}
// virtual
LLControlAvatar::~LLControlAvatar()
{
}
void LLControlAvatar::matchVolumeTransform()
{
#if 0
// AXON - should we be using bind_shape?
{
LLVolume *volume = mRootVolp->getVolume();
if (volume)
{
LLUUID mesh_id = volume->getParams().getSculptID();
const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(mesh_id, mRootVolp);
if (skin)
{
LLMatrix4 bind_shape = skin->mBindShapeMatrix;
LL_INFOS("AXON") << "bind_shape is " << bind_shape << LL_ENDL;
}
}
}
#endif
if (mRootVolp)
{
if (mRootVolp->isAttachment())
{
LLVOAvatar *attached_av = mRootVolp->getAvatarAncestor();
if (attached_av)
{
LLViewerJointAttachment *attach = attached_av->getTargetAttachmentPoint(mRootVolp);
setPositionAgent(mRootVolp->getRenderPosition());
// AXON why doesn't attach joint have a valid world
// position? Using the parent as a kludge but not
// right.
//LLQuaternion fix_axes_rot(-F_PI_BY_TWO, LLVector3(0,0,1));
LLVector3 joint_pos = attach->getParent()->getWorldPosition();
LLQuaternion joint_rot = attach->getParent()->getWorldRotation();
//LLVector3 attach_pos = mRootVolp->mDrawable->getPosition();
//attach_pos.rotVec(joint_rot);
//LLQuaternion attach_rot = mRootVolp->mDrawable->getRotation();
//mRoot->setWorldPosition(joint_pos + attach_pos);
//mRoot->setWorldRotation(joint_rot * (attach_rot * ~fix_axes_rot));
mRoot->setWorldPosition(joint_pos);
mRoot->setWorldRotation(joint_rot);
}
else
{
LL_WARNS_ONCE() << "can't find attached av!" << LL_ENDL;
}
}
else
{
setPositionAgent(mRootVolp->getRenderPosition());
//slamPosition();
LLQuaternion fix_axes_rot(-F_PI_BY_TWO, LLVector3(0,0,1));
LLQuaternion obj_rot = mRootVolp->getRotation();
LLQuaternion result_rot = fix_axes_rot * obj_rot;
setRotation(result_rot);
mRoot->setWorldRotation(result_rot);
mRoot->setPosition(mRootVolp->getRenderPosition());
}
}
}
void LLControlAvatar::setGlobalScale(F32 scale)
{
if (scale <= 0.0)
{
LL_WARNS() << "invalid global scale " << scale << LL_ENDL;
return;
}
if (scale != mGlobalScale)
{
F32 adjust_scale = scale/mGlobalScale;
LL_INFOS() << "scale " << scale << " adjustment " << adjust_scale << LL_ENDL;
// AXON - should we be scaling from the pelvis or the root?
recursiveScaleJoint(mPelvisp,adjust_scale);
mGlobalScale = scale;
}
}
void LLControlAvatar::recursiveScaleJoint(LLJoint* joint, F32 factor)
{
joint->setScale(factor * joint->getScale());
for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
iter != joint->mChildren.end(); ++iter)
{
LLJoint* child = *iter;
recursiveScaleJoint(child, factor);
}
}
// Based on LLViewerJointAttachment::setupDrawable(), without the attaching part.
void LLControlAvatar::updateVolumeGeom()
{
if (!mRootVolp->mDrawable)
return;
if (mRootVolp->mDrawable->isActive())
{
mRootVolp->mDrawable->makeStatic(FALSE);
}
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 = mRootVolp->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(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
// llvovolume.cpp.
matchVolumeTransform();
// AXON testing scale
// What should the scale be? What we really want is the ratio
// between the scale at which the object was originally designed
// and rigged, and the scale to which it has been subsequently
// modified - for example, if the object has been scaled down by a
// factor of 2 then we should use 0.5 as the global scale. But we
// don't have the original scale stored anywhere, just the current
// scale. Possibilities - 1) remember the original scale
// somewhere, 2) add another field to let the user specify the
// global scale, 3) approximate the original scale by looking at
// the proportions of the skeleton after joint positions have
// been applied
//LLVector3 obj_scale = obj->getScale();
//F32 obj_scale_z = llmax(obj_scale[2],0.1f);
//setGlobalScale(obj_scale_z/2.0f); // roughly fit avatar height range (2m) into object height
}
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->mRootVolp = obj;
cav->createDrawable(&gPipeline);
cav->mIsDummy = TRUE;
cav->mSpecialRenderMode = 1;
cav->updateJointLODs();
cav->updateGeometry(cav->mDrawable);
cav->hideSkirt();
// Sync up position/rotation with object
cav->matchVolumeTransform();
return cav;
}
void LLControlAvatar::markForDeath()
{
mMarkedForDeath = true;
}
void LLControlAvatar::idleUpdate(LLAgent &agent, const F64 &time)
{
if (mMarkedForDeath)
{
markDead();
mMarkedForDeath = false;
}
else
{
LLVOAvatar::idleUpdate(agent,time);
}
}
BOOL LLControlAvatar::updateCharacter(LLAgent &agent)
{
return LLVOAvatar::updateCharacter(agent);
}
//virtual
void LLControlAvatar::updateDebugText()
{
if (gSavedSettings.getBOOL("DebugAnimatedObjects"))
{
S32 total_linkset_count = 0;
if (mRootVolp)
{
total_linkset_count = 1 + mRootVolp->getChildren().size();
}
std::vector<LLVOVolume*> volumes;
getAnimatedVolumes(volumes);
S32 animated_volume_count = volumes.size();
std::string active_string;
std::string lod_string;
S32 total_tris = 0;
S32 total_verts = 0;
for (std::vector<LLVOVolume*>::iterator it = volumes.begin();
it != volumes.end(); ++it)
{
LLVOVolume *volp = *it;
S32 verts = 0;
total_tris += volp->getTriangleCount(&verts);
total_verts += verts;
lod_string += llformat("%d",volp->getLOD());
if (volp && volp->mDrawable)
{
if (volp->mDrawable->isActive())
{
active_string += "A";
}
else
{
active_string += "S";
}
}
else
{
active_string += "-";
}
}
addDebugText(llformat("CAV obj %d anim %d active %s",
total_linkset_count, animated_volume_count, active_string.c_str()));
#if 0
// AXON - detailed rigged mesh info
for (std::vector<LLVOVolume*>::iterator it = volumes.begin();
it != volumes.end(); ++it)
{
LLRiggedVolume *rig_vol = (*it)->getRiggedVolume();
if (rig_vol)
{
addDebugText(rig_vol->mExtraDebugText);
}
}
#endif
addDebugText(llformat("lod %s",lod_string.c_str()));
addDebugText(llformat("tris %d verts %d", total_tris, total_verts));
//addDebugText(llformat("anim time %.1f (step %f factor %f)",
// mMotionController.getAnimTime(),
// mMotionController.getTimeStep(),
// mMotionController.getTimeFactor()));
}
LLVOAvatar::updateDebugText();
}
void LLControlAvatar::getAnimatedVolumes(std::vector<LLVOVolume*>& volumes)
{
if (!mRootVolp)
{
return;
}
volumes.push_back(mRootVolp);
LLViewerObject::const_child_list_t& child_list = mRootVolp->getChildren();
for (LLViewerObject::const_child_list_t::const_iterator iter = child_list.begin();
iter != child_list.end(); ++iter)
{
LLViewerObject* childp = *iter;
LLVOVolume *child_volp = dynamic_cast<LLVOVolume*>(childp);
if (child_volp && child_volp->isAnimatedObject())
{
volumes.push_back(child_volp);
}
}
}
// This is called after an associated object receives an animation
// message. Combine the signaled animations for all associated objects
// and process any resulting state changes.
void LLControlAvatar::updateAnimations()
{
if (!mRootVolp)
{
LL_WARNS("AXON") << "No root vol" << LL_ENDL;
return;
}
std::vector<LLVOVolume*> volumes;
getAnimatedVolumes(volumes);
// Rebuild mSignaledAnimations from the associated volumes.
std::map<LLUUID, S32> anims;
for (std::vector<LLVOVolume*>::iterator vol_it = volumes.begin(); vol_it != volumes.end(); ++vol_it)
{
LLVOVolume *volp = *vol_it;
for (std::map<LLUUID,S32>::iterator anim_it = volp->mObjectSignaledAnimations.begin();
anim_it != volp->mObjectSignaledAnimations.end();
++anim_it)
{
std::map<LLUUID,S32>::iterator found_anim_it = anims.find(anim_it->first);
if (found_anim_it != anims.end())
{
// Animation already present, use the larger sequence id
anims[anim_it->first] = llmax(found_anim_it->second, anim_it->second);
}
else
{
// Animation not already present, use this sequence id.
anims[anim_it->first] = anim_it->second;
}
}
}
mSignaledAnimations = anims;
LL_DEBUGS("AXON") << "process animation state changes here" << LL_ENDL;
processAnimationStateChanges();
}
// virtual
LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
LLVector4a* normal,
LLVector4a* tangent)
{
LLViewerObject* hit = NULL;
if (lineSegmentBoundingBox(start, end))
{
LLVector4a local_end = end;
LLVector4a local_intersection;
if (mRootVolp &&
mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
{
*intersection = local_intersection;
}
hit = mRootVolp;
}
}
return hit;
}

View File

@ -0,0 +1,82 @@
/**
* @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 matchVolumeTransform();
void updateVolumeGeom();
void setGlobalScale(F32 scale);
void recursiveScaleJoint(LLJoint *joint, F32 factor);
static LLControlAvatar *createControlAvatar(LLVOVolume *obj);
// Delayed kill so we don't make graphics pipeline unhappy calling
// markDead() inside other graphics pipeline operations.
void markForDeath();
virtual void idleUpdate(LLAgent &agent, const F64 &time);
virtual BOOL updateCharacter(LLAgent &agent);
void getAnimatedVolumes(std::vector<LLVOVolume*>& volumes);
void updateAnimations();
virtual LLViewerObject* lineSegmentIntersectRiggedAttachments(
const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
LLVector4a* normal = NULL, // return the surface normal at the intersection point
LLVector4a* tangent = NULL); // return the surface tangent at the intersection point
virtual void updateDebugText();
bool mPlaying;
F32 mGlobalScale;
LLVOVolume *mRootVolp;
bool mMarkedForDeath;
};
#endif //LL_CONTROLAVATAR_H

View File

@ -50,6 +50,7 @@
#include "llviewerobjectlist.h" #include "llviewerobjectlist.h"
#include "llviewerwindow.h" #include "llviewerwindow.h"
#include "llvocache.h" #include "llvocache.h"
#include "llcontrolavatar.h"
const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f; const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f;
const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f; const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f;
@ -550,7 +551,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
if (isState(ACTIVE) && if (isState(ACTIVE) &&
!isState(ACTIVE_CHILD) && !isState(ACTIVE_CHILD) &&
!mVObjp->isAttachment() && !mVObjp->isAttachment() &&
!mVObjp->isFlexible()) !mVObjp->isFlexible() &&
!mVObjp->isAnimatedObject())
{ {
clearState(ACTIVE | ANIMATED_CHILD); clearState(ACTIVE | ANIMATED_CHILD);

View File

@ -482,6 +482,7 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
} }
LLVOAvatar *avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); LLVOAvatar *avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get();
// AXON fix
if (avatarp->isDead() || avatarp->mIsDummy || avatarp->mDrawable.isNull()) if (avatarp->isDead() || avatarp->mIsDummy || avatarp->mDrawable.isNull())
{ {
return; return;

View File

@ -1842,9 +1842,17 @@ void LLModelPreview::getJointAliases( JointMap& joint_map)
//Joint names and aliases come from avatar_skeleton.xml //Joint names and aliases come from avatar_skeleton.xml
joint_map = av->getJointAliases(); joint_map = av->getJointAliases();
for (S32 i = 0; i < av->mNumCollisionVolumes; i++)
std::vector<std::string> cv_names, attach_names;
av->getSortedJointNames(1, cv_names);
av->getSortedJointNames(2, attach_names);
for (std::vector<std::string>::iterator it = cv_names.begin(); it != cv_names.end(); ++it)
{ {
joint_map[av->mCollisionVolumes[i].getName()] = av->mCollisionVolumes[i].getName(); joint_map[*it] = *it;
}
for (std::vector<std::string>::iterator it = attach_names.begin(); it != attach_names.end(); ++it)
{
joint_map[*it] = *it;
} }
} }

View File

@ -59,12 +59,22 @@
#include "llupdaterservice.h" #include "llupdaterservice.h"
#include "llevents.h" #include "llevents.h"
#include "llappviewer.h" #include "llappviewer.h"
#include "llsdserialize.h"
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <sstream> #include <sstream>
const S32 LOGIN_MAX_RETRIES = 3; const S32 LOGIN_MAX_RETRIES = 3;
// this can be removed once it is defined by the build for all forks
#ifndef ADDRESS_SIZE
#ifdef ND_BUILD64BIT_ARCH
# define ADDRESS_SIZE 64
#else
# define ADDRESS_SIZE 32
#endif
#endif
class LLLoginInstance::Disposable { class LLLoginInstance::Disposable {
public: public:
virtual ~Disposable() {} virtual ~Disposable() {}
@ -495,10 +505,12 @@ LLLoginInstance::LLLoginInstance() :
} }
void LLLoginInstance::setPlatformInfo(const std::string platform, void LLLoginInstance::setPlatformInfo(const std::string platform,
const std::string platform_version) const std::string platform_version,
const std::string platform_name)
{ {
mPlatform = platform; mPlatform = platform;
mPlatformVersion = platform_version; mPlatformVersion = platform_version;
mPlatformVersionName = platform_name;
} }
LLLoginInstance::~LLLoginInstance() LLLoginInstance::~LLLoginInstance()
@ -567,7 +579,6 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
requested_options.append("event_notifications"); requested_options.append("event_notifications");
requested_options.append("classified_categories"); requested_options.append("classified_categories");
requested_options.append("adult_compliant"); requested_options.append("adult_compliant");
//requested_options.append("inventory-targets");
requested_options.append("buddy-list"); requested_options.append("buddy-list");
requested_options.append("newuser-config"); requested_options.append("newuser-config");
requested_options.append("ui-config"); requested_options.append("ui-config");
@ -604,8 +615,7 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
#endif // OPENSIM // <FS:AW optional opensim support> #endif // OPENSIM // <FS:AW optional opensim support>
// </FS:AW various patches> // </FS:AW various patches>
// (re)initialize the request params with creds. LLSD request_params;
LLSD request_params = user_credential->getLoginParams();
unsigned char hashed_unique_id_string[MD5HEX_STR_SIZE]; unsigned char hashed_unique_id_string[MD5HEX_STR_SIZE];
if ( ! llHashedUniqueID(hashed_unique_id_string) ) if ( ! llHashedUniqueID(hashed_unique_id_string) )
@ -622,11 +632,26 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
request_params["version"] = LLVersionInfo::getVersion(); request_params["version"] = LLVersionInfo::getVersion();
request_params["channel"] = LLVersionInfo::getChannel(); request_params["channel"] = LLVersionInfo::getChannel();
request_params["platform"] = mPlatform; request_params["platform"] = mPlatform;
request_params["address_size"] = ADDRESS_SIZE;
request_params["platform_version"] = mPlatformVersion; request_params["platform_version"] = mPlatformVersion;
request_params["platform_string"] = mPlatformVersionName;
request_params["id0"] = mSerialNumber; request_params["id0"] = mSerialNumber;
request_params["host_id"] = gSavedSettings.getString("HostID"); request_params["host_id"] = gSavedSettings.getString("HostID");
request_params["extended_errors"] = true; // request message_id and message_args request_params["extended_errors"] = true; // request message_id and message_args
// log request_params _before_ adding the credentials
LL_DEBUGS("LLLogin") << "Login parameters: " << LLSDOStreamer<LLSDNotationFormatter>(request_params) << LL_ENDL;
// Copy the credentials into the request after logging the rest
LLSD credentials(user_credential->getLoginParams());
for (LLSD::map_const_iterator it = credentials.beginMap();
it != credentials.endMap();
it++
)
{
request_params[it->first] = it->second;
}
// Specify desired timeout/retry options // Specify desired timeout/retry options
LLSD http_params; LLSD http_params;
http_params["timeout"] = gSavedSettings.getF32("LoginSRVTimeout"); http_params["timeout"] = gSavedSettings.getF32("LoginSRVTimeout");

View File

@ -70,7 +70,7 @@ public:
void setSerialNumber(const std::string& sn) { mSerialNumber = sn; } void setSerialNumber(const std::string& sn) { mSerialNumber = sn; }
void setLastExecEvent(int lee) { mLastExecEvent = lee; } void setLastExecEvent(int lee) { mLastExecEvent = lee; }
void setLastExecDuration(S32 duration) { mLastExecDuration = duration; } void setLastExecDuration(S32 duration) { mLastExecDuration = duration; }
void setPlatformInfo(const std::string platform, const std::string platform_version); void setPlatformInfo(const std::string platform, const std::string platform_version, const std::string platform_name);
void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; } void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; }
LLNotificationsInterface& getNotificationsInterface() const { return *mNotifications; } LLNotificationsInterface& getNotificationsInterface() const { return *mNotifications; }
@ -108,6 +108,7 @@ private:
S32 mLastExecDuration; S32 mLastExecDuration;
std::string mPlatform; std::string mPlatform;
std::string mPlatformVersion; std::string mPlatformVersion;
std::string mPlatformVersionName;
UpdaterLauncherCallback mUpdaterLauncher; UpdaterLauncherCallback mUpdaterLauncher;
LLEventDispatcher mDispatcher; LLEventDispatcher mDispatcher;
LLUpdaterService * mUpdaterService; LLUpdaterService * mUpdaterService;

View File

@ -78,6 +78,8 @@
#include "llviewercontrol.h" #include "llviewercontrol.h"
#include "llmeshrepository.h" #include "llmeshrepository.h"
#include "llvoavatarself.h"
#include <boost/bind.hpp> #include <boost/bind.hpp>
// "Features" Tab // "Features" Tab
@ -86,6 +88,7 @@ BOOL LLPanelVolume::postBuild()
{ {
// Flexible Objects Parameters // Flexible Objects Parameters
{ {
childSetCommitCallback("Animated Mesh Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitAnimatedMeshCheckbox, this, _1, _2), NULL);
childSetCommitCallback("Flexible1D Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitIsFlexible, this, _1, _2), NULL); childSetCommitCallback("Flexible1D Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitIsFlexible, this, _1, _2), NULL);
childSetCommitCallback("FlexNumSections",onCommitFlexible,this); childSetCommitCallback("FlexNumSections",onCommitFlexible,this);
getChild<LLUICtrl>("FlexNumSections")->setValidateBeforeCommit(precommitValidate); getChild<LLUICtrl>("FlexNumSections")->setValidateBeforeCommit(precommitValidate);
@ -237,6 +240,11 @@ void LLPanelVolume::getState( )
{ {
volobjp = (LLVOVolume *)objectp; volobjp = (LLVOVolume *)objectp;
} }
LLVOVolume *root_volobjp = NULL;
if (root_objectp && (root_objectp->getPCode() == LL_PCODE_VOLUME))
{
root_volobjp = (LLVOVolume *)root_objectp;
}
if( !objectp ) if( !objectp )
{ {
@ -260,6 +268,8 @@ void LLPanelVolume::getState( )
BOOL editable = root_objectp->permModify() && !root_objectp->isPermanentEnforced(); BOOL editable = root_objectp->permModify() && !root_objectp->isPermanentEnforced();
BOOL single_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) BOOL single_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME )
&& LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1; && LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1;
BOOL single_root_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) &&
LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1;
// Select Single Message // Select Single Message
if (single_volume) if (single_volume)
@ -352,6 +362,25 @@ void LLPanelVolume::getState( )
getChildView("Light Ambiance")->setEnabled(false); getChildView("Light Ambiance")->setEnabled(false);
} }
// Animated Mesh
BOOL is_animated_mesh = single_root_volume && root_volobjp && root_volobjp->isAnimatedObject();
getChild<LLUICtrl>("Animated Mesh Checkbox Ctrl")->setValue(is_animated_mesh);
// AXON FIXME CHECK FOR SKIN INFO ALSO
// WHAT ABOUT isPermanentEnforced?
// What about linksets with some skinned objects?
BOOL enabled_animated_object_box = FALSE;
if (root_volobjp && root_volobjp == volobjp)
{
enabled_animated_object_box = single_root_volume && root_volobjp && root_volobjp->canBeAnimatedObject() && editable;
if (enabled_animated_object_box && !is_animated_mesh &&
root_volobjp->isAttachment() && !gAgentAvatarp->canAttachMoreAnimatedObjects())
{
// Turning this attachment animated would cause us to exceed the limit.
enabled_animated_object_box = false;
}
}
getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(enabled_animated_object_box);
// Flexible properties // Flexible properties
BOOL is_flexible = volobjp && volobjp->isFlexible(); BOOL is_flexible = volobjp && volobjp->isFlexible();
getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(is_flexible); getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(is_flexible);
@ -593,6 +622,7 @@ void LLPanelVolume::clearCtrls()
getChildView("Light Radius")->setEnabled(false); getChildView("Light Radius")->setEnabled(false);
getChildView("Light Falloff")->setEnabled(false); getChildView("Light Falloff")->setEnabled(false);
getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(false);
getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false); getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false);
getChildView("FlexNumSections")->setEnabled(false); getChildView("FlexNumSections")->setEnabled(false);
getChildView("FlexGravity")->setEnabled(false); getChildView("FlexGravity")->setEnabled(false);
@ -908,6 +938,31 @@ void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata )
self->refresh(); self->refresh();
} }
void LLPanelVolume::onCommitAnimatedMeshCheckbox(LLUICtrl *, void*)
{
LLViewerObject* objectp = mObject;
if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
{
return;
}
LLVOVolume *volobjp = (LLVOVolume *)objectp;
BOOL animated_mesh = getChild<LLUICtrl>("Animated Mesh Checkbox Ctrl")->getValue();
U32 flags = volobjp->getExtendedMeshFlags();
U32 new_flags = flags;
if (animated_mesh)
{
new_flags |= LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG;
}
else
{
new_flags &= ~LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG;
}
if (new_flags != flags)
{
volobjp->setExtendedMeshFlags(new_flags);
}
}
void LLPanelVolume::onCommitIsFlexible(LLUICtrl *, void*) void LLPanelVolume::onCommitIsFlexible(LLUICtrl *, void*)
{ {
if (mObject->flagObjectPermanent()) if (mObject->flagObjectPermanent())

View File

@ -63,6 +63,7 @@ public:
static void onCommitLight( LLUICtrl* ctrl, void* userdata); static void onCommitLight( LLUICtrl* ctrl, void* userdata);
void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata); void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata);
static void onCommitFlexible( LLUICtrl* ctrl, void* userdata); static void onCommitFlexible( LLUICtrl* ctrl, void* userdata);
void onCommitAnimatedMeshCheckbox(LLUICtrl* ctrl, void* userdata);
static void onCommitPhysicsParam( LLUICtrl* ctrl, void* userdata); static void onCommitPhysicsParam( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterial( LLUICtrl* ctrl, void* userdata); static void onCommitMaterial( LLUICtrl* ctrl, void* userdata);

View File

@ -46,6 +46,7 @@
#include "llundo.h" #include "llundo.h"
#include "lluuid.h" #include "lluuid.h"
#include "llvolume.h" #include "llvolume.h"
#include "llcontrolavatar.h"
#include "message.h" #include "message.h"
#include "object_flags.h" #include "object_flags.h"
#include "llquaternion.h" #include "llquaternion.h"
@ -6834,6 +6835,9 @@ S32 get_family_count(LLViewerObject *parent)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// updateSelectionCenter // updateSelectionCenter
//
// FIXME this is a grab bag of functionality only some of which has to do
// with the selection center
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void LLSelectMgr::updateSelectionCenter() void LLSelectMgr::updateSelectionCenter()
{ {
@ -6852,48 +6856,12 @@ void LLSelectMgr::updateSelectionCenter()
mSelectionCenterGlobal.clearVec(); mSelectionCenterGlobal.clearVec();
mShowSelection = FALSE; mShowSelection = FALSE;
mSelectionBBox = LLBBox(); mSelectionBBox = LLBBox();
mPauseRequest = NULL;
resetAgentHUDZoom(); resetAgentHUDZoom();
} }
else else
{ {
mSelectedObjects->mSelectType = getSelectTypeForObject(object); mSelectedObjects->mSelectType = getSelectTypeForObject(object);
// <FS:Ansariel> Chalice Yao's pause agent on attachment selection
//if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid() && object->getParent() != NULL)
//{
// mPauseRequest = gAgentAvatarp->requestPause();
//}
if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT)
{
if (isAgentAvatarValid() && object->permYouOwner())
{
mPauseRequest = gAgentAvatarp->requestPause();
}
else
{
LLViewerObject* objectp = mSelectedObjects->getPrimaryObject();
if (objectp && objectp->isAttachment())
{
while (objectp && !objectp->isAvatar())
{
objectp = (LLViewerObject*)objectp->getParent();
}
if (objectp && objectp->isAvatar())
{
mPauseRequest = objectp->asAvatar()->requestPause();
}
}
}
}
// </FS:Ansariel>
else
{
mPauseRequest = NULL;
}
if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && isAgentAvatarValid()) if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && isAgentAvatarValid())
{ {
// reset hud ZOOM // reset hud ZOOM
@ -6970,6 +6938,59 @@ void LLSelectMgr::updateSelectionCenter()
{ {
gEditMenuHandler = NULL; gEditMenuHandler = NULL;
} }
pauseAssociatedAvatars();
}
//-----------------------------------------------------------------------------
// pauseAssociatedAvatars
//
// If the selection includes an attachment or an animated object, the
// associated avatars should pause their animations until they are no
// longer selected.
//-----------------------------------------------------------------------------
void LLSelectMgr::pauseAssociatedAvatars()
{
mPauseRequests.clear();
for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
iter != mSelectedObjects->end(); iter++)
{
LLSelectNode* node = *iter;
LLViewerObject* object = node->getObject();
if (!object)
continue;
mSelectedObjects->mSelectType = getSelectTypeForObject(object);
if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT &&
isAgentAvatarValid() && object->getParent() != NULL)
{
if (object->isAnimatedObject())
{
// Is an animated object attachment.
// Pause both the control avatar and the avatar it's attached to.
if (object->getControlAvatar())
{
mPauseRequests.push_back(object->getControlAvatar()->requestPause());
}
mPauseRequests.push_back(gAgentAvatarp->requestPause());
}
else
{
// Is a regular attachment. Pause the avatar it's attached to.
mPauseRequests.push_back(gAgentAvatarp->requestPause());
}
}
else
{
if (object && object->isAnimatedObject() && object->getControlAvatar())
{
// Is a non-attached animated object. Pause the control avatar.
mPauseRequests.push_back(object->getControlAvatar()->requestPause());
}
}
}
} }
void LLSelectMgr::updatePointAt() void LLSelectMgr::updatePointAt()

View File

@ -821,6 +821,8 @@ public:
LLVector3d getSelectionCenterGlobal() const { return mSelectionCenterGlobal; } LLVector3d getSelectionCenterGlobal() const { return mSelectionCenterGlobal; }
void updateSelectionCenter(); void updateSelectionCenter();
void pauseAssociatedAvatars();
void resetAgentHUDZoom(); void resetAgentHUDZoom();
void setAgentHUDZoom(F32 target_zoom, F32 current_zoom); void setAgentHUDZoom(F32 target_zoom, F32 current_zoom);
void getAgentHUDZoom(F32 &target_zoom, F32 &current_zoom) const; void getAgentHUDZoom(F32 &target_zoom, F32 &current_zoom) const;
@ -924,7 +926,7 @@ private:
LLFrameTimer mEffectsTimer; LLFrameTimer mEffectsTimer;
BOOL mForceSelection; BOOL mForceSelection;
LLAnimPauseRequest mPauseRequest; std::vector<LLAnimPauseRequest> mPauseRequests;
// <FS:KC> show/hide build highlight // <FS:KC> show/hide build highlight
EFSShowHideHighlight mFSShowHideHighlight; EFSShowHideHighlight mFSShowHideHighlight;

View File

@ -3191,6 +3191,7 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFuncFast(_PREHASH_NameValuePair, process_name_value); msg->setHandlerFuncFast(_PREHASH_NameValuePair, process_name_value);
msg->setHandlerFuncFast(_PREHASH_RemoveNameValuePair, process_remove_name_value); msg->setHandlerFuncFast(_PREHASH_RemoveNameValuePair, process_remove_name_value);
msg->setHandlerFuncFast(_PREHASH_AvatarAnimation, process_avatar_animation); msg->setHandlerFuncFast(_PREHASH_AvatarAnimation, process_avatar_animation);
msg->setHandlerFuncFast(_PREHASH_ObjectAnimation, process_object_animation);
msg->setHandlerFuncFast(_PREHASH_AvatarAppearance, process_avatar_appearance); msg->setHandlerFuncFast(_PREHASH_AvatarAppearance, process_avatar_appearance);
// <FS:Ansariel> [Legacy Bake] // <FS:Ansariel> [Legacy Bake]
msg->setHandlerFunc("AgentCachedTextureResponse", LLAgent::processAgentCachedTextureResponse); msg->setHandlerFunc("AgentCachedTextureResponse", LLAgent::processAgentCachedTextureResponse);

View File

@ -2096,8 +2096,7 @@ BOOL LLToolPie::handleRightClickPick()
gMenuHolder->setObjectSelection(LLSelectMgr::getInstance()->getSelection()); gMenuHolder->setObjectSelection(LLSelectMgr::getInstance()->getSelection());
bool is_other_attachment = (object->isAttachment() && !object->isHUDAttachment() && !object->permYouOwner()); bool is_other_attachment = (object->isAttachment() && !object->isHUDAttachment() && !object->permYouOwner());
if (object->isAvatar() if (object->isAvatar() || is_other_attachment)
|| is_other_attachment)
{ {
// Find the attachment's avatar // Find the attachment's avatar
while( object && object->isAttachment()) while( object && object->isAttachment())

View File

@ -280,6 +280,12 @@ static bool handleAnisotropicChanged(const LLSD& newvalue)
return true; return true;
} }
static bool handleForceLODChanged(const LLSD& newvalue)
{
LLVOVolume::sForceLOD = (F32) newvalue.asReal();
return true;
}
static bool handleVolumeLODChanged(const LLSD& newvalue) static bool handleVolumeLODChanged(const LLSD& newvalue)
{ {
LLVOVolume::sLODFactor = (F32) newvalue.asReal(); LLVOVolume::sLODFactor = (F32) newvalue.asReal();
@ -978,6 +984,7 @@ void settings_setup_listeners()
gSavedSettings.getControl("RenderAvatarCloth")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderAvatarCloth")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderForceVolumeLOD")->getSignal()->connect(boost::bind(&handleForceLODChanged, _2));
gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2)); gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2));
gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2)); gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2));
gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2)); gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2));

View File

@ -395,6 +395,25 @@ void LLViewerJointAttachment::setOriginalPosition(LLVector3& position)
setPosition(position); setPosition(position);
} }
//-----------------------------------------------------------------------------
// getNumAnimatedObjects()
//-----------------------------------------------------------------------------
S32 LLViewerJointAttachment::getNumAnimatedObjects() const
{
S32 count = 0;
for (attachedobjs_vec_t::const_iterator iter = mAttachedObjects.begin();
iter != mAttachedObjects.end();
++iter)
{
const LLViewerObject *attached_object = *iter;
if (attached_object->isAnimatedObject())
{
count++;
}
}
return count;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// clampObjectPosition() // clampObjectPosition()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -80,6 +80,7 @@ public:
S32 getGroup() const { return mGroup; } S32 getGroup() const { return mGroup; }
S32 getPieSlice() const { return mPieSlice; } S32 getPieSlice() const { return mPieSlice; }
S32 getNumObjects() const { return mAttachedObjects.size(); } S32 getNumObjects() const { return mAttachedObjects.size(); }
S32 getNumAnimatedObjects() const;
void clampObjectPosition(); void clampObjectPosition();

View File

@ -1113,7 +1113,10 @@ class LLAdvancedSetDisplayTextureDensity : public view_listener_t
////////////////// //////////////////
// INFO DISPLAY // // INFO DISPLAY //
////////////////// //////////////////
U32 info_display_from_string(std::string info_display) // <FS:Ansariel> Need an unsigned long here
//U32 info_display_from_string(std::string info_display)
U64 info_display_from_string(std::string info_display)
// </FS:Ansariel>
{ {
if ("verify" == info_display) if ("verify" == info_display)
{ {
@ -1227,6 +1230,10 @@ U32 info_display_from_string(std::string info_display)
{ {
return LLPipeline::RENDER_DEBUG_TEXEL_DENSITY; return LLPipeline::RENDER_DEBUG_TEXEL_DENSITY;
} }
else if ("triangle count" == info_display)
{
return LLPipeline::RENDER_DEBUG_TRIANGLE_COUNT;
}
else if ("texture size" == info_display) else if ("texture size" == info_display)
{ {
return LLPipeline::RENDER_DEBUG_TEXTURE_SIZE; return LLPipeline::RENDER_DEBUG_TEXTURE_SIZE;
@ -1242,13 +1249,19 @@ class LLAdvancedToggleInfoDisplay : public view_listener_t
{ {
bool handleEvent(const LLSD& userdata) bool handleEvent(const LLSD& userdata)
{ {
U32 info_display = info_display_from_string( userdata.asString() ); // <FS:Ansariel> Need an unsigned long here
//U32 info_display = info_display_from_string( userdata.asString() );
U64 info_display = info_display_from_string( userdata.asString() );
// </FS:Ansariel>
LL_INFOS("ViewerMenu") << "toggle " << userdata.asString() << LL_ENDL; LL_INFOS("ViewerMenu") << "toggle " << userdata.asString() << LL_ENDL;
if ( info_display != 0 ) if ( info_display != 0 )
{ {
LLPipeline::toggleRenderDebug( (void*)(ptrdiff_t)info_display ); // <FS:Ansariel> Need an unsigned long here
//LLPipeline::toggleRenderDebug( (void*)(ptrdiff_t)info_display );
LLPipeline::toggleRenderDebug( (void*)&info_display );
// </FS:Ansariel>
} }
return true; return true;
@ -1260,12 +1273,18 @@ class LLAdvancedCheckInfoDisplay : public view_listener_t
{ {
bool handleEvent(const LLSD& userdata) bool handleEvent(const LLSD& userdata)
{ {
U32 info_display = info_display_from_string( userdata.asString() ); // <FS:Ansariel> Need an unsigned long here
//U32 info_display = info_display_from_string( userdata.asString() );
U64 info_display = info_display_from_string( userdata.asString() );
// </FS:Ansariel>
bool new_value = false; bool new_value = false;
if ( info_display != 0 ) if ( info_display != 0 )
{ {
new_value = LLPipeline::toggleRenderDebugControl( (void*)(ptrdiff_t)info_display ); // <FS:Ansariel> Need an unsigned long here
//new_value = LLPipeline::toggleRenderDebugControl( (void*)(ptrdiff_t)info_display );
new_value = LLPipeline::toggleRenderDebugControl( (void*)&info_display );
// </FS:Ansariel>
} }
return new_value; return new_value;
@ -8529,7 +8548,7 @@ class LLAttachmentEnableDrop : public view_listener_t
// Do not enable drop if all faces of object are not enabled // Do not enable drop if all faces of object are not enabled
if (object && LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES )) 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); attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL);
if (attachment) if (attachment)

View File

@ -164,7 +164,10 @@ void handle_export_selected( void * );
// Convert strings to internal types // Convert strings to internal types
U32 render_type_from_string(std::string render_type); U32 render_type_from_string(std::string render_type);
U32 feature_from_string(std::string feature); U32 feature_from_string(std::string feature);
U32 info_display_from_string(std::string info_display); // <FS:Ansariel> Need an unsigned long here
//U32 info_display_from_string(std::string info_display);
U64 info_display_from_string(std::string info_display);
// </FS:Ansariel>
// <FS:Techwolf Lupindo> export // <FS:Techwolf Lupindo> export
bool enable_object_export(); bool enable_object_export();
// </FS:Techwolf Lupindo> // </FS:Techwolf Lupindo>

View File

@ -55,6 +55,7 @@
#include "llagentcamera.h" #include "llagentcamera.h"
#include "llcallingcard.h" #include "llcallingcard.h"
#include "llbuycurrencyhtml.h" #include "llbuycurrencyhtml.h"
#include "llcontrolavatar.h"
#include "llfirstuse.h" #include "llfirstuse.h"
#include "llfloaterbump.h" #include "llfloaterbump.h"
#include "llfloaterbuyland.h" #include "llfloaterbuyland.h"
@ -107,6 +108,7 @@
#include "llviewerwindow.h" #include "llviewerwindow.h"
#include "llvlmanager.h" #include "llvlmanager.h"
#include "llvoavatarself.h" #include "llvoavatarself.h"
#include "llvovolume.h"
#include "llworld.h" #include "llworld.h"
#include "llworldmap.h" #include "llworldmap.h"
#include "pipeline.h" #include "pipeline.h"
@ -6510,12 +6512,15 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
LLUUID animation_id; LLUUID animation_id;
LLUUID uuid; LLUUID uuid;
S32 anim_sequence_id; S32 anim_sequence_id;
LLVOAvatar *avatarp; LLVOAvatar *avatarp = NULL;
mesgsys->getUUIDFast(_PREHASH_Sender, _PREHASH_ID, uuid); mesgsys->getUUIDFast(_PREHASH_Sender, _PREHASH_ID, uuid);
//clear animation flags LLViewerObject *objp = gObjectList.findObject(uuid);
avatarp = (LLVOAvatar *)gObjectList.findObject(uuid); if (objp)
{
avatarp = objp->asAvatar();
}
if (!avatarp) if (!avatarp)
{ {
@ -6527,6 +6532,7 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationList); S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationList);
S32 num_source_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationSourceList); S32 num_source_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationSourceList);
//clear animation flags
avatarp->mSignaledAnimations.clear(); avatarp->mSignaledAnimations.clear();
if (avatarp->isSelf()) if (avatarp->isSelf())
@ -6603,6 +6609,65 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
} }
} }
void process_object_animation(LLMessageSystem *mesgsys, void **user_data)
{
LLUUID animation_id;
LLUUID uuid;
S32 anim_sequence_id;
mesgsys->getUUIDFast(_PREHASH_Sender, _PREHASH_ID, uuid);
LLViewerObject *objp = gObjectList.findObject(uuid);
if (!objp)
{
LL_WARNS("Messaging") << "AXON Received animation state for unknown object" << uuid << LL_ENDL;
return;
}
LLVOVolume *volp = dynamic_cast<LLVOVolume*>(objp);
if (!volp)
{
LL_WARNS("Messaging") << "AXON Received animation state for non-volume object" << uuid << LL_ENDL;
return;
}
if (!volp->isAnimatedObject())
{
LL_WARNS("Messaging") << "AXON Received animation state for non-animated object" << uuid << LL_ENDL;
return;
}
LLControlAvatar *avatarp = volp->getControlAvatar();
if (!avatarp)
{
LL_WARNS() << "AXON no control avatar, ignoring" << LL_ENDL;
return;
}
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationList);
LL_DEBUGS("AXON") << "handle object animation here, num_blocks " << num_blocks << LL_ENDL;
if (!avatarp->mPlaying)
{
avatarp->mPlaying = true;
avatarp->updateVolumeGeom();
}
volp->mObjectSignaledAnimations.clear();
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);
volp->mObjectSignaledAnimations[animation_id] = anim_sequence_id;
LL_DEBUGS("AXON") << "got object animation request for object "
<< uuid << " animation id " << animation_id << LL_ENDL;
}
avatarp->updateAnimations();
}
void process_avatar_appearance(LLMessageSystem *mesgsys, void **user_data) void process_avatar_appearance(LLMessageSystem *mesgsys, void **user_data)
{ {
LLUUID uuid; LLUUID uuid;

View File

@ -107,6 +107,7 @@ void process_health_message(LLMessageSystem *mesgsys, void **user_data);
void process_sim_stats(LLMessageSystem *mesgsys, void **user_data); void process_sim_stats(LLMessageSystem *mesgsys, void **user_data);
void process_shooter_agent_hit(LLMessageSystem* msg, void** user_data); void process_shooter_agent_hit(LLMessageSystem* msg, void** user_data);
void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data); void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data);
void process_object_animation(LLMessageSystem *mesgsys, void **user_data);
void process_avatar_appearance(LLMessageSystem *mesgsys, void **user_data); void process_avatar_appearance(LLMessageSystem *mesgsys, void **user_data);
void process_camera_constraint(LLMessageSystem *mesgsys, void **user_data); void process_camera_constraint(LLMessageSystem *mesgsys, void **user_data);
void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data); void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data);

View File

@ -60,6 +60,7 @@
#include "llbbox.h" #include "llbbox.h"
#include "llbox.h" #include "llbox.h"
#include "llcylinder.h" #include "llcylinder.h"
#include "llcontrolavatar.h"
#include "lldrawable.h" #include "lldrawable.h"
#include "llface.h" #include "llface.h"
#include "llfloaterproperties.h" #include "llfloaterproperties.h"
@ -150,7 +151,7 @@ const F32 PHYSICS_TIMESTEP = 1.f / 45.f;
static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object"); static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object");
// static // 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; LLViewerObject *res = NULL;
LL_RECORD_BLOCK_TIME(FTM_CREATE_OBJECT); LL_RECORD_BLOCK_TIME(FTM_CREATE_OBJECT);
@ -184,6 +185,12 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
} }
res = gAgentAvatarp; res = gAgentAvatarp;
} }
else if (flags & CO_FLAG_CONTROL_AVATAR)
{
LLControlAvatar *avatar = new LLControlAvatar(id, pcode, regionp);
avatar->initInstance();
res = avatar;
}
else else
{ {
LLVOAvatar *avatar = new LLVOAvatar(id, pcode, regionp); LLVOAvatar *avatar = new LLVOAvatar(id, pcode, regionp);
@ -253,6 +260,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mText(), mText(),
mHudText(""), mHudText(""),
mHudTextColor(LLColor4::white), mHudTextColor(LLColor4::white),
mControlAvatar(NULL),
mLastInterpUpdateSecs(0.f), mLastInterpUpdateSecs(0.f),
mLastMessageUpdateSecs(0.f), mLastMessageUpdateSecs(0.f),
mLatestRecvPacketID(0), mLatestRecvPacketID(0),
@ -277,7 +285,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mRotTime(0.f), mRotTime(0.f),
mAngularVelocityRot(), mAngularVelocityRot(),
mPreviousRotation(), mPreviousRotation(),
mState(0), mAttachmentState(0),
mMedia(NULL), mMedia(NULL),
mClickAction(0), mClickAction(0),
mObjectCost(0), mObjectCost(0),
@ -381,16 +389,22 @@ void LLViewerObject::markDead()
//LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL; //LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL;
// Root object of this hierarchy unlinks itself. // Root object of this hierarchy unlinks itself.
LLVOAvatar *av = getAvatarAncestor();
if (getParent()) if (getParent())
{ {
((LLViewerObject *)getParent())->removeChild(this); ((LLViewerObject *)getParent())->removeChild(this);
} }
LLUUID mesh_id; LLUUID mesh_id;
{
LLVOAvatar *av = getAvatar();
if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id)) if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id))
{ {
// This case is needed for indirectly attached mesh objects. // This case is needed for indirectly attached mesh objects.
av->resetJointsOnDetach(mesh_id); av->removeAttachmentOverridesForObject(mesh_id);
}
}
if (getControlAvatar())
{
unlinkControlAvatar();
} }
// Mark itself as dead // Mark itself as dead
@ -1408,7 +1422,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
U8 state; U8 state;
mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num ); 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 // ...new objects that should come in selected need to be added to the selected list
mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0); mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
@ -1684,7 +1698,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
U8 state; U8 state;
mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num ); mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
mState = state; mAttachmentState = state;
break; break;
} }
@ -1707,7 +1721,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
U8 state; U8 state;
dp->unpackU8(state, "State"); dp->unpackU8(state, "State");
mState = state; mAttachmentState = state;
switch(update_type) switch(update_type)
{ {
@ -2050,7 +2064,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
if ( (RlvActions::isRlvEnabled()) && (sent_parentp->isAvatar()) && (sent_parentp->getID() == gAgent.getID()) ) if ( (RlvActions::isRlvEnabled()) && (sent_parentp->isAvatar()) && (sent_parentp->getID() == gAgent.getID()) )
{ {
// Rezzed object that's being worn as an attachment (we're assuming this will be due to llAttachToAvatar()) // Rezzed object that's being worn as an attachment (we're assuming this will be due to llAttachToAvatar())
S32 idxAttachPt = ATTACHMENT_ID_FROM_STATE(getState()); S32 idxAttachPt = ATTACHMENT_ID_FROM_STATE(getAttachmentState());
if (gRlvAttachmentLocks.isLockedAttachmentPoint(idxAttachPt, RLV_LOCK_ADD)) if (gRlvAttachmentLocks.isLockedAttachmentPoint(idxAttachPt, RLV_LOCK_ADD))
{ {
// If this will end up on an "add locked" attachment point then treat the attach as a user action // If this will end up on an "add locked" attachment point then treat the attach as a user action
@ -2970,6 +2984,61 @@ 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()->removeAttachmentOverridesForObject(this);
}
if (isRootEdit())
{
// This will remove the entire linkset from the control avatar
LLControlAvatar *av = mControlAvatar;
mControlAvatar = NULL;
av->markForDeath();
}
// For non-root prims, removing from the linkset will
// automatically remove the control avatar connection.
}
// virtual
bool LLViewerObject::isAnimatedObject() const
{
return false;
}
struct LLFilenameAndTask struct LLFilenameAndTask
{ {
LLUUID mTaskID; LLUUID mTaskID;
@ -3950,7 +4019,7 @@ const LLVector3 LLViewerObject::getRenderPosition() const
if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED)) if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED))
{ {
LLVOAvatar* avatar = getAvatar(); LLVOAvatar* avatar = getAvatar();
if (avatar) if (avatar && !getControlAvatar())
{ {
return avatar->getPositionAgent(); return avatar->getPositionAgent();
} }
@ -5213,7 +5282,13 @@ LLVOAvatar* LLViewerObject::asAvatar()
return NULL; return NULL;
} }
// If this object is directly or indirectly parented by an avatar, return it. // If this object is directly or indirectly parented by an avatar,
// return it. Normally getAvatar() is the correct function to call;
// it will give the avatar used for skinning. The exception is with
// animated objects that are also attachments; in that case,
// getAvatar() will return the control avatar, used for skinning, and
// getAvatarAncestor will return the avatar to which the object is
// attached.
LLVOAvatar* LLViewerObject::getAvatarAncestor() LLVOAvatar* LLViewerObject::getAvatarAncestor()
{ {
LLViewerObject *pobj = (LLViewerObject*) getParent(); LLViewerObject *pobj = (LLViewerObject*) getParent();
@ -5560,6 +5635,11 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para
new_block = new LLLightImageParams(); new_block = new LLLightImageParams();
break; break;
} }
case LLNetworkData::PARAMS_EXTENDED_MESH:
{
new_block = new LLExtendedMeshParams();
break;
}
default: default:
{ {
LL_INFOS() << "Unknown param type." << LL_ENDL; LL_INFOS() << "Unknown param type." << LL_ENDL;
@ -6461,6 +6541,10 @@ const std::string& LLViewerObject::getAttachmentItemName() const
//virtual //virtual
LLVOAvatar* LLViewerObject::getAvatar() const LLVOAvatar* LLViewerObject::getAvatar() const
{ {
if (getControlAvatar())
{
return getControlAvatar();
}
if (isAttachment()) if (isAttachment())
{ {
LLViewerObject* vobj = (LLViewerObject*) getParent(); LLViewerObject* vobj = (LLViewerObject*) getParent();

View File

@ -47,6 +47,7 @@ class LLAgent; // TODO: Get rid of this.
class LLAudioSource; class LLAudioSource;
class LLAudioSourceVO; class LLAudioSourceVO;
class LLColor4; class LLColor4;
class LLControlAvatar;
class LLDataPacker; class LLDataPacker;
class LLDataPackerBinaryBuffer; class LLDataPackerBinaryBuffer;
class LLDrawable; class LLDrawable;
@ -378,9 +379,9 @@ public:
void sendShapeUpdate(); void sendShapeUpdate();
// U8 getState() { return mState; } // U8 getAttachmentState() { return mAttachmentState; }
// [RLVa:KB] - Checked: 2010-02-27 (RLVa-1.2.0a) | Added: RLVa-1.2.0a // [RLVa:KB] - Checked: 2010-02-27 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
U8 getState() const { return mState; } U8 getAttachmentState() const { return mAttachmentState; }
// [/RLVa:KB] // [/RLVa:KB]
F32 getAppAngle() const { return mAppAngle; } F32 getAppAngle() const { return mAppAngle; }
@ -700,6 +701,21 @@ public:
static BOOL sUseSharedDrawables; 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();
virtual bool isAnimatedObject() const;
protected:
LLPointer<LLControlAvatar> mControlAvatar;
protected: protected:
// delete an item in the inventory, but don't tell the // delete an item in the inventory, but don't tell the
// server. This is used internally by remove, update, and // server. This is used internally by remove, update, and
@ -710,8 +726,10 @@ protected:
// updateInventory. // updateInventory.
void doUpdateInventory(LLPointer<LLViewerInventoryItem>& item, U8 key, bool is_new); 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); BOOL setData(const U8 *datap, const U32 data_size);
@ -799,7 +817,7 @@ protected:
LLQuaternion mAngularVelocityRot; // accumulated rotation from the angular velocity computations LLQuaternion mAngularVelocityRot; // accumulated rotation from the angular velocity computations
LLQuaternion mPreviousRotation; 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 LLViewerObjectMedia* mMedia; // NULL if no media associated
U8 mClickAction; U8 mClickAction;
F32 mObjectCost; //resource cost of this object or -1 if unknown F32 mObjectCost; //resource cost of this object or -1 if unknown

View File

@ -2127,12 +2127,12 @@ void LLViewerObjectList::resetObjectBeacons()
mDebugBeacons.clear(); mDebugBeacons.clear();
} }
LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp) LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp, S32 flags)
{ {
LLUUID fullid; LLUUID fullid;
fullid.generate(); fullid.generate();
LLViewerObject *objectp = LLViewerObject::createObject(fullid, pcode, regionp); LLViewerObject *objectp = LLViewerObject::createObject(fullid, pcode, regionp, flags);
if (!objectp) if (!objectp)
{ {
// LL_WARNS() << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << LL_ENDL; // LL_WARNS() << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << LL_ENDL;

View File

@ -67,7 +67,7 @@ public:
inline LLViewerObject *getObject(const S32 index); inline LLViewerObject *getObject(const S32 index);
inline LLViewerObject *findObject(const LLUUID &id); 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 *createObjectFromCache(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id);
LLViewerObject *createObject(const LLPCode pcode, LLViewerRegion *regionp, LLViewerObject *createObject(const LLPCode pcode, LLViewerRegion *regionp,
const LLUUID &uuid, const U32 local_id, const LLHost &sender); const LLUUID &uuid, const U32 local_id, const LLHost &sender);

View File

@ -3056,6 +3056,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("MeshUploadFlag"); capabilityNames.append("MeshUploadFlag");
capabilityNames.append("NavMeshGenerationStatus"); capabilityNames.append("NavMeshGenerationStatus");
capabilityNames.append("NewFileAgentInventory"); capabilityNames.append("NewFileAgentInventory");
capabilityNames.append("ObjectAnimation");
capabilityNames.append("ObjectMedia"); capabilityNames.append("ObjectMedia");
capabilityNames.append("ObjectMediaNavigate"); capabilityNames.append("ObjectMediaNavigate");
capabilityNames.append("ObjectNavMeshProperties"); capabilityNames.append("ObjectNavMeshProperties");

File diff suppressed because it is too large Load Diff

View File

@ -170,7 +170,8 @@ public:
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
LLVector4a* normal = NULL, // return the surface normal at the intersection point LLVector4a* normal = NULL, // return the surface normal at the intersection point
LLVector4a* tangent = NULL); // return the surface tangent at the intersection point LLVector4a* tangent = NULL); // return the surface tangent at the intersection point
LLViewerObject* lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end, virtual LLViewerObject* lineSegmentIntersectRiggedAttachments(
const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE, BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE, BOOL pick_rigged = FALSE,
@ -207,8 +208,8 @@ public:
LLJoint* getJoint(S32 num); LLJoint* getJoint(S32 num);
void addAttachmentOverridesForObject(LLViewerObject *vo); void addAttachmentOverridesForObject(LLViewerObject *vo);
void resetJointsOnDetach(const LLUUID& mesh_id); void removeAttachmentOverridesForObject(const LLUUID& mesh_id);
void resetJointsOnDetach(LLViewerObject *vo); void removeAttachmentOverridesForObject(LLViewerObject *vo);
bool jointIsRiggedTo(const std::string& joint_name); bool jointIsRiggedTo(const std::string& joint_name);
bool jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo); bool jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo);
void clearAttachmentOverrides(); void clearAttachmentOverrides();
@ -238,6 +239,8 @@ public:
public: public:
virtual bool isSelf() const { return false; } // True if this avatar is for this viewer's agent 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 private: //aligned members
LL_ALIGN_16(LLVector4a mImpostorExtents[2]); LL_ALIGN_16(LLVector4a mImpostorExtents[2]);
@ -245,8 +248,14 @@ private: //aligned members
// Updates // Updates
//-------------------------------------------------------------------- //--------------------------------------------------------------------
public: public:
void updateDebugText(); virtual void updateDebugText();
virtual BOOL updateCharacter(LLAgent &agent); virtual BOOL updateCharacter(LLAgent &agent);
void updateFootstepSounds();
void computeUpdatePeriod();
void updateOrientation(LLAgent &agent, F32 speed, F32 delta_time);
void updateTimeStep();
void updateRootPositionAndRotation(LLAgent &agent, F32 speed, bool was_sit_ground_constrained);
void idleUpdateVoiceVisualizer(bool voice_enabled); void idleUpdateVoiceVisualizer(bool voice_enabled);
void idleUpdateMisc(bool detailed_update); void idleUpdateMisc(bool detailed_update);
virtual void idleUpdateAppearanceAnimation(); virtual void idleUpdateAppearanceAnimation();
@ -452,6 +461,13 @@ public:
VisualMuteSettings mVisuallyMuteSetting; // Always or never visually mute this AV VisualMuteSettings mVisuallyMuteSetting; // Always or never visually mute this AV
//--------------------------------------------------------------------
// animated object status
//--------------------------------------------------------------------
public:
bool mIsControlAvatar;
bool mEnableDefaultMotions;
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Morph masks // Morph masks
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -769,9 +785,9 @@ public:
static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj); static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
/*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const; /*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const;
LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const; LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const;
LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
//-TT Patch: ReplaceWornItemsOnly //-TT Patch: ReplaceWornItemsOnly
LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
//-TT //-TT
protected: protected:
//LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object); //LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
@ -794,10 +810,11 @@ public:
BOOL hasHUDAttachment() const; BOOL hasHUDAttachment() const;
LLBBox getHUDBBox() const; LLBBox getHUDBBox() const;
void resetHUDAttachments(); void resetHUDAttachments();
BOOL canAttachMoreObjects() const; BOOL canAttachMoreObjects(U32 n=1) const;
BOOL canAttachMoreObjects(U32 n) const; BOOL canAttachMoreAnimatedObjects(U32 n=1) const;
protected: protected:
U32 getNumAttachments() const; // O(N), not O(1) U32 getNumAttachments() const; // O(N), not O(1)
U32 getNumAnimatedObjectAttachments() const; // O(N), not O(1)
/** Wearables /** Wearables
** ** ** **

View File

@ -3370,7 +3370,7 @@ BOOL LLVOAvatarSelf::needsRenderBeam()
// don't render selection beam on hud objects // don't render selection beam on hud objects
is_touching_or_grabbing = FALSE; 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 // static

View File

@ -92,7 +92,8 @@ LLVOGrass::~LLVOGrass()
void LLVOGrass::updateSpecies() void LLVOGrass::updateSpecies()
{ {
mSpecies = mState; // AXON is grass still even supported? This use of state seems odd.
mSpecies = getAttachmentState();
if (!sSpeciesTable.count(mSpecies)) if (!sSpeciesTable.count(mSpecies))
{ {

View File

@ -76,8 +76,13 @@
#include "lldatapacker.h" #include "lldatapacker.h"
#include "llviewershadermgr.h" #include "llviewershadermgr.h"
#include "llvoavatar.h" #include "llvoavatar.h"
#include "llcontrolavatar.h"
#include "llvoavatarself.h"
#include "llvocache.h" #include "llvocache.h"
#include "llmaterialmgr.h" #include "llmaterialmgr.h"
#include "llanimationstates.h"
#include "llinventorytype.h"
#include "llviewerinventory.h"
// [RLVa:KB] - Checked: RLVa-2.0.0 // [RLVa:KB] - Checked: RLVa-2.0.0
#include "rlvactions.h" #include "rlvactions.h"
#include "rlvlocks.h" #include "rlvlocks.h"
@ -90,6 +95,8 @@ U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 1;
BOOL gAnimateTextures = TRUE; BOOL gAnimateTextures = TRUE;
//extern BOOL gHideSelectedObjects; //extern BOOL gHideSelectedObjects;
// AXON TEMP
S32 LLVOVolume::sForceLOD = -1;
F32 LLVOVolume::sLODFactor = 1.f; F32 LLVOVolume::sLODFactor = 1.f;
F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop
F32 LLVOVolume::sDistanceFactor = 1.0f; F32 LLVOVolume::sDistanceFactor = 1.0f;
@ -1361,6 +1368,13 @@ void LLVOVolume::sculpt()
S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius) S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius)
{ {
S32 cur_detail; S32 cur_detail;
// AXON TEMP
if (LLVOVolume::sForceLOD>=0 && LLVOVolume::sForceLOD<=3)
{
cur_detail = LLVOVolume::sForceLOD;
}
else
{
if (LLPipeline::sDynamicLOD) if (LLPipeline::sDynamicLOD)
{ {
// We've got LOD in the profile, and in the twist. Use radius. // We've got LOD in the profile, and in the twist. Use radius.
@ -1371,6 +1385,7 @@ S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius)
{ {
cur_detail = llclamp((S32) (sqrtf(radius)*LLVOVolume::sLODFactor*4.f), 0, 3); cur_detail = llclamp((S32) (sqrtf(radius)*LLVOVolume::sLODFactor*4.f), 0, 3);
} }
}
return cur_detail; return cur_detail;
} }
@ -1427,13 +1442,36 @@ BOOL LLVOVolume::calcLOD()
ll_round(radius, 0.01f)); ll_round(radius, 0.01f));
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TRIANGLE_COUNT) && mDrawable->getFace(0))
{
if (isRootEdit() && getChildren().size()>0)
{
S32 total_tris = getTriangleCount();
LLViewerObject::const_child_list_t& child_list = getChildren();
for (LLViewerObject::const_child_list_t::const_iterator iter = child_list.begin();
iter != child_list.end(); ++iter)
{
LLViewerObject* childp = *iter;
LLVOVolume *child_volp = dynamic_cast<LLVOVolume*>(childp);
if (child_volp)
{
total_tris += child_volp->getTriangleCount();
}
}
setDebugText(llformat("TRIS %d TOTAL %d", getTriangleCount(), total_tris));
}
else
{
setDebugText(llformat("TRIS %d", getTriangleCount()));
}
}
// <FS> FIRE-20191 / STORM-2139 Render Metadata->LOD Info is broken on all "recent" viewer versions // <FS> FIRE-20191 / STORM-2139 Render Metadata->LOD Info is broken on all "recent" viewer versions
//if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) && //if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) &&
// mDrawable->getFace(0)) // mDrawable->getFace(0))
//{ //{
// //setDebugText(llformat("%.2f:%.2f, %d", mDrawable->mDistanceWRTCamera, radius, cur_detail)); //// This is a debug display for LODs. Please don't put the texture index here.
//setDebugText(llformat("%d", cur_detail));
// setDebugText(llformat("%d", mDrawable->getFace(0)->getTextureIndex()));
//} //}
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO)) if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO))
{ {
@ -1542,7 +1580,8 @@ void LLVOVolume::updateFaceFlags()
BOOL LLVOVolume::setParent(LLViewerObject* parent) BOOL LLVOVolume::setParent(LLViewerObject* parent)
{ {
BOOL ret = FALSE ; BOOL ret = FALSE ;
if (parent != getParent()) LLViewerObject *old_parent = (LLViewerObject*) getParent();
if (parent != old_parent)
{ {
ret = LLViewerObject::setParent(parent); ret = LLViewerObject::setParent(parent);
if (ret && mDrawable) if (ret && mDrawable)
@ -1550,6 +1589,7 @@ BOOL LLVOVolume::setParent(LLViewerObject* parent)
gPipeline.markMoved(mDrawable); gPipeline.markMoved(mDrawable);
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
} }
updateAnimatedObjectState(old_parent, parent);
} }
return ret ; return ret ;
@ -3441,6 +3481,176 @@ BOOL LLVOVolume::setIsFlexible(BOOL is_flexible)
return res; return res;
} }
//----------------------------------------------------------------------------
// AXON - methods related to extended mesh flags
U32 LLVOVolume::getExtendedMeshFlags() const
{
const LLExtendedMeshParams *param_block =
(const LLExtendedMeshParams *)getParameterEntry(LLNetworkData::PARAMS_EXTENDED_MESH);
if (param_block)
{
return param_block->getFlags();
}
else
{
return 0;
}
}
void LLVOVolume::setExtendedMeshFlags(U32 flags)
{
U32 curr_flags = getExtendedMeshFlags();
if (curr_flags != flags)
{
bool in_use = (flags != 0);
setParameterEntryInUse(LLNetworkData::PARAMS_EXTENDED_MESH, in_use, true);
LLExtendedMeshParams *param_block =
(LLExtendedMeshParams *)getParameterEntry(LLNetworkData::PARAMS_EXTENDED_MESH);
if (param_block)
{
param_block->setFlags(flags);
}
parameterChanged(LLNetworkData::PARAMS_EXTENDED_MESH, true);
}
}
bool LLVOVolume::canBeAnimatedObject() const
{
if (!isMesh())
{
return false;
}
// AXON remove this check if animated object attachments are allowed
#if 0
if (isAttachment())
{
return false;
}
#endif
if (!getVolume())
{
return false;
}
const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(getVolume()->getParams().getSculptID(), this);
if (!skin)
{
return false;
}
return true;
}
bool LLVOVolume::isAnimatedObject() const
{
LLVOVolume *root_vol = (LLVOVolume*)getRootEdit();
bool can_be_animated = canBeAnimatedObject();
bool root_can_be_animated = root_vol->canBeAnimatedObject();
bool root_is_animated = root_vol->getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG;
if (can_be_animated && root_can_be_animated && root_is_animated)
{
return true;
}
return false;
}
// Make sure animated objects in a linkset are consistent. The rules are:
// Only the root of a linkset can have the animated object flag set
// Only the root of a linkset can have a control avatar (iff the animated object flag is set)
// Only skinned mesh volumes can have the animated object flag set, or a control avatar
bool LLVOVolume::isAnimatedObjectStateConsistent() const
{
if (!canBeAnimatedObject())
{
if ((getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG) ||
mControlAvatar.notNull())
{
LL_WARNS("AXON") << "Non animatable object has mesh enabled flag or mControlAvatar. Flags "
<< getExtendedMeshFlags() << " cav " << mControlAvatar.get() << LL_ENDL;
return false;
}
}
if (!isRootEdit())
{
if ((getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG) ||
mControlAvatar.notNull())
{
LL_WARNS("AXON") << "Non root object has mesh enabled flag or mControlAvatar. Flags "
<< getExtendedMeshFlags() << " cav " << mControlAvatar.get() << LL_ENDL;
return false;
}
}
// If we get here, we have a potentially animatable root volume.
bool is_animation_enabled = getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG;
bool has_control_avatar = (mControlAvatar.notNull());
if (is_animation_enabled != has_control_avatar)
{
LL_WARNS("AXON") << "Inconsistent state: animation enabled " << is_animation_enabled
<< " has control avatar " << has_control_avatar
<< " flags " << getExtendedMeshFlags() << " cav " << mControlAvatar.get() << LL_ENDL;
return false;
}
return true;
}
// Called any time parenting changes for a volume. Update flags and
// control av accordingly. This is called after parent has been
// changed to new_parent.
void LLVOVolume::updateAnimatedObjectState(LLViewerObject *old_parent, LLViewerObject *new_parent)
{
LLVOVolume *old_volp = dynamic_cast<LLVOVolume*>(old_parent);
LLVOVolume *new_volp = dynamic_cast<LLVOVolume*>(new_parent);
// AXON - depending on whether animated objects can be attached,
// we may want to include or remove the isAvatar() check.
if (new_parent && !new_parent->isAvatar())
{
// Object should inherit control avatar and animated mesh flag
// from parent, so clear them out from our own state
if (getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG)
{
setExtendedMeshFlags(getExtendedMeshFlags() & ~LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG);
}
if (mControlAvatar.notNull())
{
LLControlAvatar *av = mControlAvatar;
mControlAvatar = NULL;
av->markForDeath();
}
// If this succeeds now, it's because the new_parent is an animated object
if (isAnimatedObject() && getControlAvatar())
{
getControlAvatar()->addAttachmentOverridesForObject(this);
}
}
if (old_volp && old_volp->isAnimatedObject())
{
if (old_volp->getControlAvatar())
{
// We have been removed from an animated object, need to do cleanup.
old_volp->getControlAvatar()->removeAttachmentOverridesForObject(this);
}
}
if (old_volp)
{
if (!old_volp->isAnimatedObjectStateConsistent())
{
LL_WARNS("AXON") << "old_volp failed consistency check" << LL_ENDL;
}
}
if (new_volp)
{
if (!new_volp->isAnimatedObjectStateConsistent())
{
LL_WARNS("AXON") << "new_volp failed consistency check" << LL_ENDL;
}
}
if (!isAnimatedObjectStateConsistent())
{
LL_WARNS("AXON") << "child object failed consistency check" << LL_ENDL;
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point) void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point)
@ -3502,7 +3712,7 @@ void LLVOVolume::updateRadius()
BOOL LLVOVolume::isAttachment() const BOOL LLVOVolume::isAttachment() const
{ {
return mState != 0 ; return mAttachmentState != 0 ;
} }
BOOL LLVOVolume::isHUDAttachment() const BOOL LLVOVolume::isHUDAttachment() const
@ -3510,7 +3720,7 @@ BOOL LLVOVolume::isHUDAttachment() const
// *NOTE: we assume hud attachment points are in defined range // *NOTE: we assume hud attachment points are in defined range
// since this range is constant for backwards compatibility // since this range is constant for backwards compatibility
// reasons this is probably a reasonable assumption to make // 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 ); return ( attachment_id >= 31 && attachment_id <= 38 );
} }
@ -4279,7 +4489,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
bool LLVOVolume::treatAsRigged() bool LLVOVolume::treatAsRigged()
{ {
return isSelected() && return isSelected() &&
isAttachment() && (isAttachment() || isAnimatedObject()) &&
mDrawable.notNull() && mDrawable.notNull() &&
mDrawable->isState(LLDrawable::RIGGED); mDrawable->isState(LLDrawable::RIGGED);
} }
@ -4374,6 +4584,9 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin); U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin);
LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, maxJoints, skin, avatar); LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, maxJoints, skin, avatar);
S32 rigged_vert_count = 0;
S32 rigged_face_count = 0;
LLVector4a box_min, box_max;
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
{ {
const LLVolumeFace& vol_face = volume->getVolumeFace(i); const LLVolumeFace& vol_face = volume->getVolumeFace(i);
@ -4395,6 +4608,8 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
LL_RECORD_BLOCK_TIME(FTM_SKIN_RIGGED); LL_RECORD_BLOCK_TIME(FTM_SKIN_RIGGED);
U32 max_joints = LLSkinningUtil::getMaxJointCount(); U32 max_joints = LLSkinningUtil::getMaxJointCount();
rigged_vert_count += dst_face.mNumVertices;
rigged_face_count++;
for (U32 j = 0; j < dst_face.mNumVertices; ++j) for (U32 j = 0; j < dst_face.mNumVertices; ++j)
{ {
LLMatrix4a final_mat; LLMatrix4a final_mat;
@ -4418,12 +4633,19 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
min = pos[0]; min = pos[0];
max = pos[1]; max = pos[1];
if (i==0)
{
box_min = min;
box_max = max;
}
for (U32 j = 1; j < dst_face.mNumVertices; ++j) for (U32 j = 1; j < dst_face.mNumVertices; ++j)
{ {
min.setMin(min, pos[j]); min.setMin(min, pos[j]);
max.setMax(max, pos[j]); max.setMax(max, pos[j]);
} }
box_min.setMin(min,box_min);
box_max.setMax(max,box_max);
dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]); dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]);
dst_face.mCenter->mul(0.5f); dst_face.mCenter->mul(0.5f);
@ -4459,6 +4681,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
} }
} }
} }
mExtraDebugText = llformat("rigged %d/%d - box (%f %f %f) (%f %f %f)",
rigged_face_count, rigged_vert_count,
box_min[0], box_min[1], box_min[2],
box_max[0], box_max[1], box_max[2]);
} }
U32 LLVOVolume::getPartitionType() const U32 LLVOVolume::getPartitionType() const
@ -5028,11 +5254,35 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
vobj->isMesh() && vobj->isMesh() &&
gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj);
if (vobj->isAnimatedObject())
{
if (!vobj->getControlAvatar())
{
vobj->linkControlAvatar();
}
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())
{
vobj->unlinkControlAvatar();
}
}
bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic();
// AXON why this variable? Only different from rigged if
// there are no LLFaces associated with the drawable.
bool is_rigged = false; bool is_rigged = false;
if (rigged && pAvatarVO) // AXON handle NPC case
if (rigged && pAvatarVO && !vobj->isAnimatedObject())
{ {
pAvatarVO->addAttachmentOverridesForObject(vobj); pAvatarVO->addAttachmentOverridesForObject(vobj);
if (!LLApp::isExiting() && pAvatarVO->isSelf() && debugLoggingEnabled("AvatarAttachments")) if (!LLApp::isExiting() && pAvatarVO->isSelf() && debugLoggingEnabled("AvatarAttachments"))
@ -5058,7 +5308,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//sum up face verts and indices //sum up face verts and indices
drawablep->updateFaceSize(i); drawablep->updateFaceSize(i);
if (rigged) if (rigged || (vobj->getControlAvatar() && vobj->getControlAvatar()->mPlaying))
{ {
if (!facep->isState(LLFace::RIGGED)) if (!facep->isState(LLFace::RIGGED))
{ //completely reset vertex buffer { //completely reset vertex buffer

View File

@ -62,6 +62,8 @@ public:
} }
void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume); void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume);
std::string mExtraDebugText;
}; };
// Base class for implementations of the volume - Primitive, Flexible Object, etc. // Base class for implementations of the volume - Primitive, Flexible Object, etc.
@ -262,10 +264,24 @@ public:
virtual BOOL isMesh() const; virtual BOOL isMesh() const;
virtual BOOL hasLightTexture() const; virtual BOOL hasLightTexture() const;
BOOL isVolumeGlobal() const; BOOL isVolumeGlobal() const;
BOOL canBeFlexible() const; BOOL canBeFlexible() const;
BOOL setIsFlexible(BOOL is_flexible); BOOL setIsFlexible(BOOL is_flexible);
// Extended Mesh Properties
U32 getExtendedMeshFlags() const;
void setExtendedMeshFlags(U32 flags);
bool canBeAnimatedObject() const;
bool isAnimatedObject() const;
bool isAnimatedObjectStateConsistent() const;
void updateAnimatedObjectState(LLViewerObject *old_parent, LLViewerObject *new_parent);
// AXON For animated objects, we need to track animations requested
// per-object, then reconcile those to manage the control avatar
// animation state.
std::map<LLUUID, S32> mObjectSignaledAnimations; // requested state of Animation name/value
// Functions that deal with media, or media navigation // Functions that deal with media, or media navigation
// Update this object's media data with the given media data array // Update this object's media data with the given media data array
@ -381,6 +397,7 @@ private:
public: public:
static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop
static F32 sLODFactor; // LOD scale factor static F32 sLODFactor; // LOD scale factor
static S32 sForceLOD; // LOD override
static F32 sDistanceFactor; // LOD distance factor static F32 sDistanceFactor; // LOD distance factor
static LLPointer<LLObjectMediaDataClient> sObjectMediaClient; static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;

View File

@ -6958,7 +6958,10 @@ BOOL LLPipeline::toggleRenderTypeControlNegated(void* data)
//static //static
void LLPipeline::toggleRenderDebug(void* data) void LLPipeline::toggleRenderDebug(void* data)
{ {
U32 bit = (U32)(intptr_t)data; // <FS:Ansariel> Need an unsigned long here
//U32 bit = (U32)(intptr_t)data;
U64 bit = *(U64*)data;
// </FS:Ansariel>
if (gPipeline.hasRenderDebugMask(bit)) if (gPipeline.hasRenderDebugMask(bit))
{ {
LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " off" << std::dec << LL_ENDL; LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " off" << std::dec << LL_ENDL;
@ -6974,7 +6977,10 @@ void LLPipeline::toggleRenderDebug(void* data)
//static //static
BOOL LLPipeline::toggleRenderDebugControl(void* data) BOOL LLPipeline::toggleRenderDebugControl(void* data)
{ {
U32 bit = (U32)(intptr_t)data; // <FS:Ansariel> Need an unsigned long here
//U32 bit = (U32)(intptr_t)data;
U64 bit = *(U64*)data;
// </FS:Ansariel>
return gPipeline.hasRenderDebugMask(bit); return gPipeline.hasRenderDebugMask(bit);
} }

View File

@ -330,10 +330,16 @@ public:
void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES); void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES);
BOOL hasRenderDebugFeatureMask(const U32 mask) const { return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; } BOOL hasRenderDebugFeatureMask(const U32 mask) const { return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; }
BOOL hasRenderDebugMask(const U32 mask) const { return (mRenderDebugMask & mask) ? TRUE : FALSE; } // <FS:Ansariel> Need an unsigned long here
//BOOL hasRenderDebugMask(const U32 mask) const { return (mRenderDebugMask & mask) ? TRUE : FALSE; }
BOOL hasRenderDebugMask(const U64 mask) const { return (mRenderDebugMask & mask) ? TRUE : FALSE; }
// </FS:Ansariel>
void setAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0xffffffff; } void setAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0xffffffff; }
void clearAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0x0; } void clearAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0x0; }
void setAllRenderDebugDisplays() { mRenderDebugMask = 0xffffffff; } // <FS:Ansariel> Need an unsigned long here
//void setAllRenderDebugDisplays() { mRenderDebugMask = 0xffffffff; }
void setAllRenderDebugDisplays() { mRenderDebugMask = 0xffffffffffffffff; }
// </FS:Ansariel>
void clearAllRenderDebugDisplays() { mRenderDebugMask = 0x0; } void clearAllRenderDebugDisplays() { mRenderDebugMask = 0x0; }
BOOL hasRenderType(const U32 type) const; BOOL hasRenderType(const U32 type) const;
@ -510,7 +516,7 @@ public:
RENDER_DEBUG_FEATURE_FOOT_SHADOWS = 0x0100, RENDER_DEBUG_FEATURE_FOOT_SHADOWS = 0x0100,
}; };
enum LLRenderDebugMask enum LLRenderDebugMask : U64 // <FS:Ansariel> Need an unsigned long here - needs C++11 support!
{ {
RENDER_DEBUG_COMPOSITION = 0x00000001, RENDER_DEBUG_COMPOSITION = 0x00000001,
RENDER_DEBUG_VERIFY = 0x00000002, RENDER_DEBUG_VERIFY = 0x00000002,
@ -523,11 +529,11 @@ public:
RENDER_DEBUG_TEXTURE_AREA = 0x00000100, RENDER_DEBUG_TEXTURE_AREA = 0x00000100,
RENDER_DEBUG_FACE_AREA = 0x00000200, RENDER_DEBUG_FACE_AREA = 0x00000200,
RENDER_DEBUG_PARTICLES = 0x00000400, RENDER_DEBUG_PARTICLES = 0x00000400,
RENDER_DEBUG_GLOW = 0x00000800, RENDER_DEBUG_GLOW = 0x00000800, // not used
RENDER_DEBUG_TEXTURE_ANIM = 0x00001000, RENDER_DEBUG_TEXTURE_ANIM = 0x00001000,
RENDER_DEBUG_LIGHTS = 0x00002000, RENDER_DEBUG_LIGHTS = 0x00002000,
RENDER_DEBUG_BATCH_SIZE = 0x00004000, RENDER_DEBUG_BATCH_SIZE = 0x00004000,
RENDER_DEBUG_ALPHA_BINS = 0x00008000, RENDER_DEBUG_ALPHA_BINS = 0x00008000, // not used
RENDER_DEBUG_RAYCAST = 0x00010000, RENDER_DEBUG_RAYCAST = 0x00010000,
RENDER_DEBUG_AVATAR_DRAW_INFO = 0x00020000, RENDER_DEBUG_AVATAR_DRAW_INFO = 0x00020000,
RENDER_DEBUG_SHADOW_FRUSTA = 0x00040000, RENDER_DEBUG_SHADOW_FRUSTA = 0x00040000,
@ -541,9 +547,10 @@ public:
RENDER_DEBUG_NORMALS = 0x04000000, RENDER_DEBUG_NORMALS = 0x04000000,
RENDER_DEBUG_LOD_INFO = 0x08000000, RENDER_DEBUG_LOD_INFO = 0x08000000,
RENDER_DEBUG_RENDER_COMPLEXITY = 0x10000000, RENDER_DEBUG_RENDER_COMPLEXITY = 0x10000000,
RENDER_DEBUG_ATTACHMENT_BYTES = 0x20000000, RENDER_DEBUG_ATTACHMENT_BYTES = 0x20000000, // not used
RENDER_DEBUG_TEXEL_DENSITY = 0x40000000, RENDER_DEBUG_TEXEL_DENSITY = 0x40000000,
RENDER_DEBUG_TEXTURE_SIZE = 0x80000000 RENDER_DEBUG_TRIANGLE_COUNT = 0x80000000,
RENDER_DEBUG_TEXTURE_SIZE = 0x100000000
}; };
public: public:
@ -689,10 +696,14 @@ protected:
std::stack<std::string> mRenderTypeEnableStack; std::stack<std::string> mRenderTypeEnableStack;
U32 mRenderDebugFeatureMask; U32 mRenderDebugFeatureMask;
U32 mRenderDebugMask; // <FS:Ansariel> Need an unsigned long here
//U32 mRenderDebugMask;
U64 mRenderDebugMask;
std::stack<U32> mRenderDebugFeatureStack; std::stack<U32> mRenderDebugFeatureStack;
U32 mOldRenderDebugMask; // <FS:Ansariel> Need an unsigned long here
//U32 mOldRenderDebugMask;
U64 mOldRenderDebugMask;
///////////////////////////////////////////// /////////////////////////////////////////////
// //

View File

@ -888,7 +888,7 @@ RlvObject::RlvObject(const LLUUID& idObj) : m_idObj(idObj), m_nLookupMisses(0)
{ {
LLViewerObject* pObj = gObjectList.findObject(idObj); LLViewerObject* pObj = gObjectList.findObject(idObj);
m_fLookup = (NULL != pObj); m_fLookup = (NULL != pObj);
m_idxAttachPt = (pObj) ? ATTACHMENT_ID_FROM_STATE(pObj->getState()) : 0; m_idxAttachPt = (pObj) ? ATTACHMENT_ID_FROM_STATE(pObj->getAttachmentState()) : 0;
m_idRoot = (pObj) ? pObj->getRootEdit()->getID() : LLUUID::null; m_idRoot = (pObj) ? pObj->getRootEdit()->getID() : LLUUID::null;
} }

View File

@ -418,7 +418,7 @@ inline S32 RlvAttachPtLookup::getAttachPointIndex(std::string strText)
// Checked: 2010-03-03 (RLVa-1.2.0a) | Modified: RLVa-0.2.0d // Checked: 2010-03-03 (RLVa-1.2.0a) | Modified: RLVa-0.2.0d
inline S32 RlvAttachPtLookup::getAttachPointIndex(const LLViewerObject* pObj) inline S32 RlvAttachPtLookup::getAttachPointIndex(const LLViewerObject* pObj)
{ {
return (pObj) ? ATTACHMENT_ID_FROM_STATE(pObj->getState()) : 0; return (pObj) ? ATTACHMENT_ID_FROM_STATE(pObj->getAttachmentState()) : 0;
} }
// ============================================================================ // ============================================================================

View File

@ -2484,13 +2484,23 @@ even though the user gets a free copy.
Edit object features: Edit object features:
</text> </text>
<check_box <check_box
height="19" height="15"
label="Animated Mesh"
layout="topleft"
left="10"
name="Animated Mesh Checkbox Ctrl"
tool_tip="Allows rigged mesh objects to be animated independently"
top_pad="5"
width="121" />
<check_box
height="10"
label="Flexible Path" label="Flexible Path"
follows="left|top"
layout="topleft" layout="topleft"
left="10" left="10"
name="Flexible1D Checkbox Ctrl" name="Flexible1D Checkbox Ctrl"
tool_tip="Allows object to flex about the Z axis (Client-side only)" tool_tip="Allows object to flex about the Z axis (Client-side only)"
top_pad="10" top_pad="5"
width="121" /> width="121" />
<spinner <spinner
follows="left|top" follows="left|top"
@ -2503,7 +2513,7 @@ even though the user gets a free copy.
left_delta="0" left_delta="0"
max_val="3" max_val="3"
name="FlexNumSections" name="FlexNumSections"
top_pad="10" top_pad="4"
width="128" /> width="128" />
<spinner <spinner
follows="left|top" follows="left|top"

View File

@ -3714,6 +3714,16 @@
function="Advanced.ToggleInfoDisplay" function="Advanced.ToggleInfoDisplay"
parameter="lod info" /> parameter="lod info" />
</menu_item_check> </menu_item_check>
<menu_item_check
label="Triangle Count"
name="Triangle Count">
<menu_item_check.on_check
function="Advanced.CheckInfoDisplay"
parameter="triangle count" />
<menu_item_check.on_click
function="Advanced.ToggleInfoDisplay"
parameter="triangle count" />
</menu_item_check>
<menu_item_check <menu_item_check
label="Build Queue" label="Build Queue"
name="Build Queue"> name="Build Queue">

View File

@ -11805,6 +11805,15 @@ Your access privileges don't allow you to duplicate objects here.
You are not allowed to change this shape. You are not allowed to change this shape.
</notification> </notification>
<notification
icon="alertmodal.tga"
name="NoPermsTooManyAttachedAnimatedObjects"
type="notify">
<tag>fail</tag>
Operation would cause the number of attached animated objects to exceed the limit.
</notification>
<notification <notification
icon="alertmodal.tga" icon="alertmodal.tga"
name="NoAccessToClaimObjects" name="NoAccessToClaimObjects"

View File

@ -2542,13 +2542,23 @@ even though the user gets a free copy.
Edit object features: Edit object features:
</text> </text>
<check_box <check_box
height="19" height="15"
label="Animated Mesh"
layout="topleft"
left="10"
name="Animated Mesh Checkbox Ctrl"
tool_tip="Allows rigged mesh objects to be animated independently"
top_pad="5"
width="121" />
<check_box
height="10"
label="Flexible Path" label="Flexible Path"
follows="left|top"
layout="topleft" layout="topleft"
left="10" left="10"
name="Flexible1D Checkbox Ctrl" name="Flexible1D Checkbox Ctrl"
tool_tip="Allows object to flex about the Z axis (Client-side only)" tool_tip="Allows object to flex about the Z axis (Client-side only)"
top_pad="10" top_pad="5"
width="121" /> width="121" />
<spinner <spinner
follows="left|top" follows="left|top"
@ -2561,7 +2571,7 @@ even though the user gets a free copy.
left_delta="0" left_delta="0"
max_val="3" max_val="3"
name="FlexNumSections" name="FlexNumSections"
top_pad="10" top_pad="4"
width="128" /> width="128" />
<spinner <spinner
follows="left|top" follows="left|top"

View File

@ -2542,13 +2542,23 @@ even though the user gets a free copy.
Edit object features: Edit object features:
</text> </text>
<check_box <check_box
height="19" height="15"
label="Animated Mesh"
layout="topleft"
left="10"
name="Animated Mesh Checkbox Ctrl"
tool_tip="Allows rigged mesh objects to be animated independently"
top_pad="5"
width="121" />
<check_box
height="10"
label="Flexible Path" label="Flexible Path"
follows="left|top"
layout="topleft" layout="topleft"
left="10" left="10"
name="Flexible1D Checkbox Ctrl" name="Flexible1D Checkbox Ctrl"
tool_tip="Allows object to flex about the Z axis (Client-side only)" tool_tip="Allows object to flex about the Z axis (Client-side only)"
top_pad="10" top_pad="5"
width="121" /> width="121" />
<spinner <spinner
follows="left|top" follows="left|top"
@ -2561,7 +2571,7 @@ even though the user gets a free copy.
left_delta="0" left_delta="0"
max_val="3" max_val="3"
name="FlexNumSections" name="FlexNumSections"
top_pad="10" top_pad="4"
width="128" /> width="128" />
<spinner <spinner
follows="left|top" follows="left|top"

View File

@ -2476,13 +2476,23 @@ even though the user gets a free copy.
Edit object features: Edit object features:
</text> </text>
<check_box <check_box
height="19" height="15"
label="Animated Mesh"
layout="topleft"
left="10"
name="Animated Mesh Checkbox Ctrl"
tool_tip="Allows rigged mesh objects to be animated independently"
top_pad="5"
width="121" />
<check_box
height="10"
label="Flexible Path" label="Flexible Path"
follows="left|top"
layout="topleft" layout="topleft"
left="10" left="10"
name="Flexible1D Checkbox Ctrl" name="Flexible1D Checkbox Ctrl"
tool_tip="Allows object to flex about the Z axis (Client-side only)" tool_tip="Allows object to flex about the Z axis (Client-side only)"
top_pad="10" top_pad="5"
width="121" /> width="121" />
<spinner <spinner
follows="left|top" follows="left|top"
@ -2495,7 +2505,7 @@ even though the user gets a free copy.
left_delta="0" left_delta="0"
max_val="3" max_val="3"
name="FlexNumSections" name="FlexNumSections"
top_pad="10" top_pad="4"
width="128" /> width="128" />
<spinner <spinner
follows="left|top" follows="left|top"

View File

@ -384,7 +384,7 @@ namespace tut
accountCredential->setCredentialData(identifier, authenticator); accountCredential->setCredentialData(identifier, authenticator);
logininstance->setNotificationsInterface(&notifications); logininstance->setNotificationsInterface(&notifications);
logininstance->setPlatformInfo("win", "1.3.5"); logininstance->setPlatformInfo("win", "1.3.5", "Windows Bogus Version 100.6.6.6");
} }
LLLoginInstance* logininstance; LLLoginInstance* logininstance;
@ -500,109 +500,4 @@ namespace tut
ensure_equals("Default for agree to tos", gLoginCreds["params"]["read_critical"].asBoolean(), false); ensure_equals("Default for agree to tos", gLoginCreds["params"]["read_critical"].asBoolean(), false);
} }
template<> template<>
void lllogininstance_object::test<3>()
{
set_test_name("Test Mandatory Update User Accepts");
// Part 1 - Mandatory Update, with User accepts response.
// Test connect with update needed.
logininstance->connect(agentCredential);
ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);
// Update needed failure response.
LLSD response;
response["state"] = "offline";
response["change"] = "fail.login";
response["progress"] = 0.0;
response["transfer_rate"] = 7;
response["data"]["reason"] = "update";
gTestPump.post(response);
ensure_equals("Notification added", notifications.addedCount(), 1);
notifications.sendYesResponse();
ensure("Disconnected", !(logininstance->authSuccess()));
}
template<> template<>
void lllogininstance_object::test<4>()
{
set_test_name("Test Mandatory Update User Decline");
// Test connect with update needed.
logininstance->connect(agentCredential);
ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);
// Update needed failure response.
LLSD response;
response["state"] = "offline";
response["change"] = "fail.login";
response["progress"] = 0.0;
response["transfer_rate"] = 7;
response["data"]["reason"] = "update";
gTestPump.post(response);
ensure_equals("Notification added", notifications.addedCount(), 1);
notifications.sendNoResponse();
ensure("Disconnected", !(logininstance->authSuccess()));
}
template<> template<>
void lllogininstance_object::test<6>()
{
set_test_name("Test Optional Update User Accept");
// Part 3 - Mandatory Update, with bogus response.
// Test connect with update needed.
logininstance->connect(agentCredential);
ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);
// Update needed failure response.
LLSD response;
response["state"] = "offline";
response["change"] = "fail.login";
response["progress"] = 0.0;
response["transfer_rate"] = 7;
response["data"]["reason"] = "optional";
gTestPump.post(response);
ensure_equals("Notification added", notifications.addedCount(), 1);
notifications.sendYesResponse();
ensure("Disconnected", !(logininstance->authSuccess()));
}
template<> template<>
void lllogininstance_object::test<7>()
{
set_test_name("Test Optional Update User Denies");
// Part 3 - Mandatory Update, with bogus response.
// Test connect with update needed.
logininstance->connect(agentCredential);
ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);
// Update needed failure response.
LLSD response;
response["state"] = "offline";
response["change"] = "fail.login";
response["progress"] = 0.0;
response["transfer_rate"] = 7;
response["data"]["reason"] = "optional";
gTestPump.post(response);
ensure_equals("Notification added", notifications.addedCount(), 1);
notifications.sendNoResponse();
// User skips, should be reconnecting.
ensure_equals("reconnect uri", gLoginURI, VIEWERLOGIN_URI);
ensure_equals("skipping optional update", gLoginCreds["params"]["skipoptional"].asBoolean(), true);
}
} }

View File

@ -34,7 +34,6 @@
* *
*/ */
#include "linden_common.h" #include "linden_common.h"
#include "llerrorcontrol.h" #include "llerrorcontrol.h"
#include "lltut.h" #include "lltut.h"
@ -698,5 +697,4 @@ int main(int argc, char **argv)
return retval; return retval;
//delete mycallback; //delete mycallback;
} }

View File

@ -8,7 +8,7 @@ version 2.0
// for each type is listed below: // for each type is listed below:
// Low: 429 // Low: 429
// Medium: 18 // Medium: 18
// High: 29 // High: 30
// PLEASE UPDATE THIS WHEN YOU ADD A NEW MESSAGE! // PLEASE UPDATE THIS WHEN YOU ADD A NEW MESSAGE!
@ -3574,7 +3574,6 @@ version 2.0
} }
} }
// AvatarAppearance - Update visual params // AvatarAppearance - Update visual params
{ {
AvatarAppearance Low 158 Trusted Zerocoded AvatarAppearance Low 158 Trusted Zerocoded
@ -7307,6 +7306,29 @@ version 2.0
} }
// *************************************************************************
// Object animation messages
// *************************************************************************
// Note this is basically identical to AvatarAnimation.
// Needs to be a different message because existing viewers
// have insufficiently smart handler functions.
// ObjectAnimation - Update animation state
// simulator --> viewer
{
ObjectAnimation High 30 Trusted Unencoded
{
Sender Single
{ ID LLUUID }
}
{
AnimationList Variable
{ AnimID LLUUID }
{ AnimSequenceID S32 }
}
}
// ************************************************************************* // *************************************************************************
// Asset storage messages // Asset storage messages
// ************************************************************************* // *************************************************************************

View File

@ -1 +1 @@
8535acbfaf222a8e026283a74d869402a0458314 65309e77b91facecb65ea0dfac478d7737e9641f

View File

@ -0,0 +1,54 @@
list buttons = ["anim start", "anim stop", "step", "verbose on", "verbose off", " "];
string dialogInfo = "\nPlease make a choice.";
key ToucherID;
integer dialogChannel;
integer listenHandle;
integer commandChannel;
default
{
state_entry()
{
dialogChannel = -1 - (integer)("0x" + llGetSubString( (string)llGetKey(), -7, -1) );
commandChannel = -2001;
}
touch_start(integer num_detected)
{
ToucherID = llDetectedKey(0);
llListenRemove(listenHandle);
listenHandle = llListen(dialogChannel, "", ToucherID, "");
llDialog(ToucherID, dialogInfo, buttons, dialogChannel);
//llSetTimerEvent(60.0); // Here we set a time limit for responses
}
listen(integer channel, string name, key id, string message)
{
if (message == "-")
{
llDialog(ToucherID, dialogInfo, buttons, dialogChannel);
return;
}
llListenRemove(listenHandle);
// stop timer since the menu was clicked
llSetTimerEvent(0);
//llOwnerSay("Sending message " + message + " on channel " + (string)commandChannel);
llRegionSay(commandChannel, message);
}
timer()
{
// stop timer
llSetTimerEvent(0);
llListenRemove(listenHandle);
//llWhisper(0, "Sorry. You snooze; you lose.");
}
}
// Local Variables:
// shadow-file-name: "$SW_HOME/axon/scripts/testing/lsl/axon_test_region_driver.lsl"
// End:

View File

@ -0,0 +1,118 @@
integer listenHandle;
integer verbose;
integer current_animation_number;
string NowPlaying;
say_if_verbose(integer channel, string message)
{
if (verbose)
{
llSay(channel, message);
}
}
stop_all_animations()
{
integer count = llGetInventoryNumber(INVENTORY_ANIMATION);
string ItemName;
string NowPlaying;
while (count--)
{
ItemName = llGetInventoryName(INVENTORY_ANIMATION, count);
say_if_verbose(0, "Stopping " + ItemName);
llStopObjectAnimation(ItemName);
}
}
start_cycle_animations()
{
current_animation_number = llGetInventoryNumber(INVENTORY_ANIMATION);
next_animation(); // Do first iteration without waiting for timer
llSetTimerEvent(5.0);
}
next_animation()
{
string ItemName;
if (NowPlaying != "")
{
say_if_verbose(0, "Stopping " + NowPlaying);
llStopObjectAnimation(NowPlaying);
}
if (current_animation_number--)
{
ItemName = llGetInventoryName(INVENTORY_ANIMATION, current_animation_number);
say_if_verbose(0, "Starting " + ItemName);
llStartObjectAnimation(ItemName);
NowPlaying = ItemName;
}
else
{
// Start again at the top
current_animation_number = llGetInventoryNumber(INVENTORY_ANIMATION);
}
}
stop_cycle_animations()
{
llSetTimerEvent(0);
}
default
{
state_entry()
{
say_if_verbose(0, "Animated Object here");
listenHandle = llListen(-2001,"","","");
verbose = 0;
stop_all_animations();
}
listen(integer channel, string name, key id, string message)
{
//llOwnerSay("got message " + name + " " + (string) id + " " + message);
list words = llParseString2List(message,[" "],[]);
string command = llList2String(words,0);
string option = llList2String(words,1);
if (command=="anim")
{
stop_all_animations();
if (option=="start")
{
start_cycle_animations();
}
else if (option=="stop")
{
stop_cycle_animations();
}
}
if (command=="verbose")
{
if (option=="on")
{
verbose = 1;
}
else if (option=="off")
{
verbose = 0;
}
}
}
timer()
{
say_if_verbose(0, "timer triggered");
next_animation();
}
touch_start(integer total_number)
{
say_if_verbose(0, "Touch started.");
start_cycle_animations();
}
}
// Local Variables:
// shadow-file-name: "$SW_HOME/axon/scripts/testing/lsl/cycle_object_animations.lsl"
// End:

View File

@ -0,0 +1,133 @@
integer listenHandle;
integer verbose;
integer current_animation_number;
string NowPlaying;
say_if_verbose(integer channel, string message)
{
if (verbose)
{
llSay(channel, message);
}
}
stop_all_animations()
{
list curr_anims = llGetObjectAnimationNames();
say_if_verbose(0,"stopping all, curr_anims are " + (string) curr_anims);
integer length = llGetListLength(curr_anims);
integer index = 0;
while (index < length)
{
string anim = llList2String(curr_anims, index);
say_if_verbose(0, "Stopping " + anim);
llStopObjectAnimation(anim);
// This check isn't really needed, just included to demonstrate is_animation_running()
if (is_animation_running(anim))
{
say_if_verbose(0, "ERROR - failed to stop " + anim + "!");
}
++index;
}
}
integer is_animation_running(string anim)
{
list curr_anims = llGetObjectAnimationNames();
return ~llListFindList(curr_anims, (list)anim);
}
start_cycle_animations()
{
current_animation_number = llGetInventoryNumber(INVENTORY_ANIMATION);
next_animation(); // Do first iteration without waiting for timer
llSetTimerEvent(5.0);
}
next_animation()
{
string ItemName;
if (NowPlaying != "")
{
say_if_verbose(0, "Stopping " + NowPlaying);
llStopObjectAnimation(NowPlaying);
}
if (current_animation_number--)
{
ItemName = llGetInventoryName(INVENTORY_ANIMATION, current_animation_number);
say_if_verbose(0, "Starting " + ItemName);
llStartObjectAnimation(ItemName);
key anim_id = llGetInventoryKey(ItemName);
say_if_verbose(0, "Started item " + ItemName + " inv key " + (string) anim_id);
NowPlaying = ItemName;
}
else
{
// Start again at the top
current_animation_number = llGetInventoryNumber(INVENTORY_ANIMATION);
}
}
stop_cycle_animations()
{
llSetTimerEvent(0);
}
default
{
state_entry()
{
say_if_verbose(0, "Animated Object here");
listenHandle = llListen(-2001,"","","");
verbose = 0;
stop_all_animations();
}
listen(integer channel, string name, key id, string message)
{
//llOwnerSay("got message " + name + " " + (string) id + " " + message);
list words = llParseString2List(message,[" "],[]);
string command = llList2String(words,0);
string option = llList2String(words,1);
if (command=="anim")
{
stop_all_animations();
if (option=="start")
{
start_cycle_animations();
}
else if (option=="stop")
{
stop_cycle_animations();
}
}
if (command=="verbose")
{
if (option=="on")
{
verbose = 1;
}
else if (option=="off")
{
verbose = 0;
}
}
}
timer()
{
say_if_verbose(0, "timer triggered");
next_animation();
}
touch_start(integer total_number)
{
say_if_verbose(0, "Touch started.");
start_cycle_animations();
}
}
// Local Variables:
// shadow-file-name: "$SW_HOME/axon/scripts/testing/lsl/cycle_object_animations_v2.lsl"
// End:

View File

@ -0,0 +1,90 @@
integer listenHandle;
integer verbose;
integer num_steps = 12;
float circle_time = 5.0;
integer circle_step;
vector circle_pos;
vector circle_center;
float circle_radius;
start_circle(vector center, float radius)
{
vector currentPosition = llGetPos();
circle_center = center;
circle_radius = radius;
circle_step = 0;
llSetTimerEvent(circle_time/num_steps);
llTargetOmega(<0.0, 0.0, 1.0>, TWO_PI/circle_time, 1.0);
}
stop_circle()
{
llSetTimerEvent(0);
llTargetOmega(<0.0, 0.0, 1.0>, TWO_PI/circle_time, 0.0);
llSetRegionPos(circle_center);
}
next_circle()
{
float rad = (circle_step * TWO_PI)/num_steps;
float x = circle_center.x + llCos(rad)*circle_radius;
float y = circle_center.y + llSin(rad)*circle_radius;
float z = circle_center.z;
llSetRegionPos(<x,y,z>);
circle_step = (circle_step+1)%num_steps;
}
default
{
state_entry()
{
//llSay(0, "Hello, Avatar!");
listenHandle = llListen(-2001,"","","");
verbose = 0;
circle_center = llGetPos();
}
listen(integer channel, string name, key id, string message)
{
//llOwnerSay("got message " + name + " " + (string) id + " " + message);
list words = llParseString2List(message,[" "],[]);
string command = llList2String(words,0);
string option = llList2String(words,1);
if (command=="anim")
{
if (option=="start")
{
start_circle(llGetPos(), 3.0);
}
else if (option=="stop")
{
stop_circle();
}
}
if (command=="verbose")
{
if (option=="on")
{
verbose = 1;
}
else if (option=="off")
{
verbose = 0;
}
}
if (command=="step")
{
llSetTimerEvent(0);
next_circle();
}
}
timer()
{
next_circle();
}
}
// Local Variables:
// shadow-file-name: "$SW_HOME/axon/scripts/testing/lsl/move_in_circle_using_llSetRegionPos.lsl"
// End: