Merge axon
commit
01d8e7e347
|
|
@ -236,6 +236,14 @@
|
|||
<boolean>false</boolean>
|
||||
</map>
|
||||
|
||||
<key>ObjectAnimation</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>template</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>false</boolean>
|
||||
</map>
|
||||
|
||||
<key>AvatarAppearance</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
|
|
|
|||
|
|
@ -150,10 +150,13 @@ public:
|
|||
BOOL isPaused() const { return mPaused; }
|
||||
|
||||
void setTimeStep(F32 step);
|
||||
F32 getTimeStep() const { return mTimeStep; }
|
||||
|
||||
void setTimeFactor(F32 time_factor);
|
||||
F32 getTimeFactor() const { return mTimeFactor; }
|
||||
|
||||
F32 getAnimTime() const { return mAnimTime; }
|
||||
|
||||
// <FS:Ansariel> Fix impostered animation speed based on a fix by Henri Beauchamp
|
||||
void setUpdateFactor(F32 update_factor) { mUpdateFactor = update_factor; }
|
||||
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT;
|
|||
|
||||
// attachment constants
|
||||
const S32 MAX_AGENT_ATTACHMENTS = 38;
|
||||
const S32 MAX_AGENT_ANIMATED_OBJECT_ATTACHMENTS = 1;
|
||||
const U8 ATTACHMENT_ADD = 0x80;
|
||||
|
||||
// god levels
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
/**
|
||||
|
||||
* @file llvolume.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
|
|
|
|||
|
|
@ -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_AgentAnimation = LLMessageStringTable::getInstance()->getString("AgentAnimation");
|
||||
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_ParcelGodMarkAsContent = LLMessageStringTable::getInstance()->getString("ParcelGodMarkAsContent");
|
||||
char const* const _PREHASH_UsePhysics = LLMessageStringTable::getInstance()->getString("UsePhysics");
|
||||
|
|
|
|||
|
|
@ -818,6 +818,7 @@ extern char const* const _PREHASH_StateSave;
|
|||
extern char const* const _PREHASH_RoleData;
|
||||
extern char const* const _PREHASH_AgentAnimation;
|
||||
extern char const* const _PREHASH_AvatarAnimation;
|
||||
extern char const* const _PREHASH_ObjectAnimation;
|
||||
extern char const* const _PREHASH_LogDwellTime;
|
||||
extern char const* const _PREHASH_ParcelGodMarkAsContent;
|
||||
extern char const* const _PREHASH_UsePhysics;
|
||||
|
|
|
|||
|
|
@ -1607,6 +1607,8 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size)
|
|||
return (size == 17);
|
||||
case PARAMS_LIGHT_IMAGE:
|
||||
return (size == 28);
|
||||
case PARAMS_EXTENDED_MESH:
|
||||
return (size == 4);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
|
@ -2034,3 +2036,67 @@ bool LLLightImageParams::fromLLSD(LLSD& sd)
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ public:
|
|||
PARAMS_LIGHT_IMAGE = 0x40,
|
||||
PARAMS_RESERVED = 0x50, // Used on server-side
|
||||
PARAMS_MESH = 0x60,
|
||||
PARAMS_EXTENDED_MESH = 0x70,
|
||||
};
|
||||
|
||||
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
|
||||
// now to make the connection to code in
|
||||
|
|
|
|||
|
|
@ -256,6 +256,7 @@ set(viewer_SOURCE_FILES
|
|||
llcommunicationchannel.cpp
|
||||
llcompilequeue.cpp
|
||||
llconfirmationmanager.cpp
|
||||
llcontrolavatar.cpp
|
||||
llconversationlog.cpp
|
||||
llconversationloglist.cpp
|
||||
llconversationloglistitem.cpp
|
||||
|
|
@ -1007,6 +1008,7 @@ set(viewer_HEADER_FILES
|
|||
llcommunicationchannel.h
|
||||
llcompilequeue.h
|
||||
llconfirmationmanager.h
|
||||
llcontrolavatar.h
|
||||
llconversationlog.h
|
||||
llconversationloglist.h
|
||||
llconversationloglistitem.h
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
</array>
|
||||
<key>tags</key>
|
||||
<array>
|
||||
|
||||
<string>AXON</string>
|
||||
<!-- sample entry for debugging specific items
|
||||
<string>Avatar</string>
|
||||
<string>Inventory</string>
|
||||
|
|
|
|||
|
|
@ -3748,6 +3748,17 @@
|
|||
<key>Backup</key>
|
||||
<integer>0</integer>
|
||||
</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>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -13007,6 +13018,17 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<integer>0</integer>
|
||||
<key>Backup</key>
|
||||
<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>
|
||||
<key>RenderVolumeLODFactor</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -379,7 +379,7 @@ void FSFloaterObjectExport::addPrim(LLViewerObject* object, bool root)
|
|||
{
|
||||
if (object->isAttachment())
|
||||
{
|
||||
prim["attachment_point"] = ATTACHMENT_ID_FROM_STATE(object->getState());
|
||||
prim["attachment_point"] = ATTACHMENT_ID_FROM_STATE(object->getAttachmentState());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -893,10 +893,10 @@ void LLWearableHoldingPattern::onAllComplete()
|
|||
// ++it)
|
||||
// {
|
||||
// LLViewerObject *objectp = *it;
|
||||
// if (!objectp->isAnimatedObject())
|
||||
// {
|
||||
// gAgentAvatarp->addAttachmentOverridesForObject(objectp);
|
||||
// }
|
||||
//
|
||||
// // Add new attachments to match those requested.
|
||||
// LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL;
|
||||
// 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)
|
||||
{
|
||||
LLViewerObject *objectp = *it;
|
||||
if (!objectp->isAnimatedObject())
|
||||
{
|
||||
gAgentAvatarp->addAttachmentOverridesForObject(objectp);
|
||||
}
|
||||
}
|
||||
|
||||
// Add new attachments to match those requested.
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -670,6 +670,7 @@ static void settings_to_globals()
|
|||
// </FS:Ansariel>
|
||||
LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
|
||||
LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures");
|
||||
LLVOVolume::sForceLOD = gSavedSettings.getS32("RenderForceVolumeLOD");
|
||||
LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor");
|
||||
LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
|
||||
LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
|
||||
|
|
@ -823,7 +824,7 @@ LLAppViewer::LLAppViewer()
|
|||
//
|
||||
|
||||
LLLoginInstance::instance().setUpdaterService(mUpdater.get());
|
||||
LLLoginInstance::instance().setPlatformInfo(gPlatform, getOSInfo().getOSVersionString());
|
||||
LLLoginInstance::instance().setPlatformInfo(gPlatform, getOSInfo().getOSVersionString(), getOSInfo().getOSStringSimple());
|
||||
}
|
||||
|
||||
LLAppViewer::~LLAppViewer()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -50,6 +50,7 @@
|
|||
#include "llviewerobjectlist.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llvocache.h"
|
||||
#include "llcontrolavatar.h"
|
||||
|
||||
const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f;
|
||||
const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f;
|
||||
|
|
@ -550,7 +551,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
|
|||
if (isState(ACTIVE) &&
|
||||
!isState(ACTIVE_CHILD) &&
|
||||
!mVObjp->isAttachment() &&
|
||||
!mVObjp->isFlexible())
|
||||
!mVObjp->isFlexible() &&
|
||||
!mVObjp->isAnimatedObject())
|
||||
{
|
||||
clearState(ACTIVE | ANIMATED_CHILD);
|
||||
|
||||
|
|
|
|||
|
|
@ -482,6 +482,7 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
|
|||
}
|
||||
LLVOAvatar *avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get();
|
||||
|
||||
// AXON fix
|
||||
if (avatarp->isDead() || avatarp->mIsDummy || avatarp->mDrawable.isNull())
|
||||
{
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1842,9 +1842,17 @@ void LLModelPreview::getJointAliases( JointMap& joint_map)
|
|||
//Joint names and aliases come from avatar_skeleton.xml
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,12 +59,22 @@
|
|||
#include "llupdaterservice.h"
|
||||
#include "llevents.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llsdserialize.h"
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <sstream>
|
||||
|
||||
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 {
|
||||
public:
|
||||
virtual ~Disposable() {}
|
||||
|
|
@ -495,10 +505,12 @@ LLLoginInstance::LLLoginInstance() :
|
|||
}
|
||||
|
||||
void LLLoginInstance::setPlatformInfo(const std::string platform,
|
||||
const std::string platform_version)
|
||||
const std::string platform_version,
|
||||
const std::string platform_name)
|
||||
{
|
||||
mPlatform = platform;
|
||||
mPlatformVersion = platform_version;
|
||||
mPlatformVersionName = platform_name;
|
||||
}
|
||||
|
||||
LLLoginInstance::~LLLoginInstance()
|
||||
|
|
@ -567,7 +579,6 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
|
|||
requested_options.append("event_notifications");
|
||||
requested_options.append("classified_categories");
|
||||
requested_options.append("adult_compliant");
|
||||
//requested_options.append("inventory-targets");
|
||||
requested_options.append("buddy-list");
|
||||
requested_options.append("newuser-config");
|
||||
requested_options.append("ui-config");
|
||||
|
|
@ -604,8 +615,7 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
|
|||
#endif // OPENSIM // <FS:AW optional opensim support>
|
||||
// </FS:AW various patches>
|
||||
|
||||
// (re)initialize the request params with creds.
|
||||
LLSD request_params = user_credential->getLoginParams();
|
||||
LLSD request_params;
|
||||
|
||||
unsigned char hashed_unique_id_string[MD5HEX_STR_SIZE];
|
||||
if ( ! llHashedUniqueID(hashed_unique_id_string) )
|
||||
|
|
@ -622,11 +632,26 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
|
|||
request_params["version"] = LLVersionInfo::getVersion();
|
||||
request_params["channel"] = LLVersionInfo::getChannel();
|
||||
request_params["platform"] = mPlatform;
|
||||
request_params["address_size"] = ADDRESS_SIZE;
|
||||
request_params["platform_version"] = mPlatformVersion;
|
||||
request_params["platform_string"] = mPlatformVersionName;
|
||||
request_params["id0"] = mSerialNumber;
|
||||
request_params["host_id"] = gSavedSettings.getString("HostID");
|
||||
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
|
||||
LLSD http_params;
|
||||
http_params["timeout"] = gSavedSettings.getF32("LoginSRVTimeout");
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ public:
|
|||
void setSerialNumber(const std::string& sn) { mSerialNumber = sn; }
|
||||
void setLastExecEvent(int lee) { mLastExecEvent = lee; }
|
||||
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; }
|
||||
LLNotificationsInterface& getNotificationsInterface() const { return *mNotifications; }
|
||||
|
|
@ -108,6 +108,7 @@ private:
|
|||
S32 mLastExecDuration;
|
||||
std::string mPlatform;
|
||||
std::string mPlatformVersion;
|
||||
std::string mPlatformVersionName;
|
||||
UpdaterLauncherCallback mUpdaterLauncher;
|
||||
LLEventDispatcher mDispatcher;
|
||||
LLUpdaterService * mUpdaterService;
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@
|
|||
#include "llviewercontrol.h"
|
||||
#include "llmeshrepository.h"
|
||||
|
||||
#include "llvoavatarself.h"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
// "Features" Tab
|
||||
|
|
@ -86,6 +88,7 @@ BOOL LLPanelVolume::postBuild()
|
|||
{
|
||||
// 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("FlexNumSections",onCommitFlexible,this);
|
||||
getChild<LLUICtrl>("FlexNumSections")->setValidateBeforeCommit(precommitValidate);
|
||||
|
|
@ -237,6 +240,11 @@ void LLPanelVolume::getState( )
|
|||
{
|
||||
volobjp = (LLVOVolume *)objectp;
|
||||
}
|
||||
LLVOVolume *root_volobjp = NULL;
|
||||
if (root_objectp && (root_objectp->getPCode() == LL_PCODE_VOLUME))
|
||||
{
|
||||
root_volobjp = (LLVOVolume *)root_objectp;
|
||||
}
|
||||
|
||||
if( !objectp )
|
||||
{
|
||||
|
|
@ -260,6 +268,8 @@ void LLPanelVolume::getState( )
|
|||
BOOL editable = root_objectp->permModify() && !root_objectp->isPermanentEnforced();
|
||||
BOOL single_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME )
|
||||
&& LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1;
|
||||
BOOL single_root_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) &&
|
||||
LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1;
|
||||
|
||||
// Select Single Message
|
||||
if (single_volume)
|
||||
|
|
@ -352,6 +362,25 @@ void LLPanelVolume::getState( )
|
|||
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
|
||||
BOOL is_flexible = volobjp && volobjp->isFlexible();
|
||||
getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(is_flexible);
|
||||
|
|
@ -593,6 +622,7 @@ void LLPanelVolume::clearCtrls()
|
|||
getChildView("Light Radius")->setEnabled(false);
|
||||
getChildView("Light Falloff")->setEnabled(false);
|
||||
|
||||
getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(false);
|
||||
getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false);
|
||||
getChildView("FlexNumSections")->setEnabled(false);
|
||||
getChildView("FlexGravity")->setEnabled(false);
|
||||
|
|
@ -908,6 +938,31 @@ void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata )
|
|||
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*)
|
||||
{
|
||||
if (mObject->flagObjectPermanent())
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ public:
|
|||
static void onCommitLight( LLUICtrl* ctrl, void* userdata);
|
||||
void onCommitIsFlexible( 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 onCommitMaterial( LLUICtrl* ctrl, void* userdata);
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include "llundo.h"
|
||||
#include "lluuid.h"
|
||||
#include "llvolume.h"
|
||||
#include "llcontrolavatar.h"
|
||||
#include "message.h"
|
||||
#include "object_flags.h"
|
||||
#include "llquaternion.h"
|
||||
|
|
@ -6834,6 +6835,9 @@ S32 get_family_count(LLViewerObject *parent)
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
// updateSelectionCenter
|
||||
//
|
||||
// FIXME this is a grab bag of functionality only some of which has to do
|
||||
// with the selection center
|
||||
// -----------------------------------------------------------------------------
|
||||
void LLSelectMgr::updateSelectionCenter()
|
||||
{
|
||||
|
|
@ -6852,48 +6856,12 @@ void LLSelectMgr::updateSelectionCenter()
|
|||
mSelectionCenterGlobal.clearVec();
|
||||
mShowSelection = FALSE;
|
||||
mSelectionBBox = LLBBox();
|
||||
mPauseRequest = NULL;
|
||||
resetAgentHUDZoom();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
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())
|
||||
{
|
||||
// reset hud ZOOM
|
||||
|
|
@ -6970,6 +6938,59 @@ void LLSelectMgr::updateSelectionCenter()
|
|||
{
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -821,6 +821,8 @@ public:
|
|||
LLVector3d getSelectionCenterGlobal() const { return mSelectionCenterGlobal; }
|
||||
void updateSelectionCenter();
|
||||
|
||||
void pauseAssociatedAvatars();
|
||||
|
||||
void resetAgentHUDZoom();
|
||||
void setAgentHUDZoom(F32 target_zoom, F32 current_zoom);
|
||||
void getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const;
|
||||
|
|
@ -924,7 +926,7 @@ private:
|
|||
LLFrameTimer mEffectsTimer;
|
||||
BOOL mForceSelection;
|
||||
|
||||
LLAnimPauseRequest mPauseRequest;
|
||||
std::vector<LLAnimPauseRequest> mPauseRequests;
|
||||
|
||||
// <FS:KC> show/hide build highlight
|
||||
EFSShowHideHighlight mFSShowHideHighlight;
|
||||
|
|
|
|||
|
|
@ -3191,6 +3191,7 @@ void register_viewer_callbacks(LLMessageSystem* msg)
|
|||
msg->setHandlerFuncFast(_PREHASH_NameValuePair, process_name_value);
|
||||
msg->setHandlerFuncFast(_PREHASH_RemoveNameValuePair, process_remove_name_value);
|
||||
msg->setHandlerFuncFast(_PREHASH_AvatarAnimation, process_avatar_animation);
|
||||
msg->setHandlerFuncFast(_PREHASH_ObjectAnimation, process_object_animation);
|
||||
msg->setHandlerFuncFast(_PREHASH_AvatarAppearance, process_avatar_appearance);
|
||||
// <FS:Ansariel> [Legacy Bake]
|
||||
msg->setHandlerFunc("AgentCachedTextureResponse", LLAgent::processAgentCachedTextureResponse);
|
||||
|
|
|
|||
|
|
@ -2096,8 +2096,7 @@ BOOL LLToolPie::handleRightClickPick()
|
|||
gMenuHolder->setObjectSelection(LLSelectMgr::getInstance()->getSelection());
|
||||
|
||||
bool is_other_attachment = (object->isAttachment() && !object->isHUDAttachment() && !object->permYouOwner());
|
||||
if (object->isAvatar()
|
||||
|| is_other_attachment)
|
||||
if (object->isAvatar() || is_other_attachment)
|
||||
{
|
||||
// Find the attachment's avatar
|
||||
while( object && object->isAttachment())
|
||||
|
|
|
|||
|
|
@ -280,6 +280,12 @@ static bool handleAnisotropicChanged(const LLSD& newvalue)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool handleForceLODChanged(const LLSD& newvalue)
|
||||
{
|
||||
LLVOVolume::sForceLOD = (F32) newvalue.asReal();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool handleVolumeLODChanged(const LLSD& newvalue)
|
||||
{
|
||||
LLVOVolume::sLODFactor = (F32) newvalue.asReal();
|
||||
|
|
@ -978,6 +984,7 @@ void settings_setup_listeners()
|
|||
gSavedSettings.getControl("RenderAvatarCloth")->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("RenderForceVolumeLOD")->getSignal()->connect(boost::bind(&handleForceLODChanged, _2));
|
||||
gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2));
|
||||
gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2));
|
||||
gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2));
|
||||
|
|
|
|||
|
|
@ -395,6 +395,25 @@ void LLViewerJointAttachment::setOriginalPosition(LLVector3& 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()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ public:
|
|||
S32 getGroup() const { return mGroup; }
|
||||
S32 getPieSlice() const { return mPieSlice; }
|
||||
S32 getNumObjects() const { return mAttachedObjects.size(); }
|
||||
S32 getNumAnimatedObjects() const;
|
||||
|
||||
void clampObjectPosition();
|
||||
|
||||
|
|
|
|||
|
|
@ -1113,7 +1113,10 @@ class LLAdvancedSetDisplayTextureDensity : public view_listener_t
|
|||
//////////////////
|
||||
// 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)
|
||||
{
|
||||
|
|
@ -1227,6 +1230,10 @@ U32 info_display_from_string(std::string info_display)
|
|||
{
|
||||
return LLPipeline::RENDER_DEBUG_TEXEL_DENSITY;
|
||||
}
|
||||
else if ("triangle count" == info_display)
|
||||
{
|
||||
return LLPipeline::RENDER_DEBUG_TRIANGLE_COUNT;
|
||||
}
|
||||
else if ("texture size" == info_display)
|
||||
{
|
||||
return LLPipeline::RENDER_DEBUG_TEXTURE_SIZE;
|
||||
|
|
@ -1242,13 +1249,19 @@ class LLAdvancedToggleInfoDisplay : public view_listener_t
|
|||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
|
|
@ -1260,12 +1273,18 @@ class LLAdvancedCheckInfoDisplay : public view_listener_t
|
|||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
|
|
@ -8529,7 +8548,7 @@ class LLAttachmentEnableDrop : public view_listener_t
|
|||
// Do not enable drop if all faces of object are not enabled
|
||||
if (object && LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES ))
|
||||
{
|
||||
S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getState());
|
||||
S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getAttachmentState());
|
||||
attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL);
|
||||
|
||||
if (attachment)
|
||||
|
|
|
|||
|
|
@ -164,7 +164,10 @@ void handle_export_selected( void * );
|
|||
// Convert strings to internal types
|
||||
U32 render_type_from_string(std::string render_type);
|
||||
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
|
||||
bool enable_object_export();
|
||||
// </FS:Techwolf Lupindo>
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
#include "llagentcamera.h"
|
||||
#include "llcallingcard.h"
|
||||
#include "llbuycurrencyhtml.h"
|
||||
#include "llcontrolavatar.h"
|
||||
#include "llfirstuse.h"
|
||||
#include "llfloaterbump.h"
|
||||
#include "llfloaterbuyland.h"
|
||||
|
|
@ -107,6 +108,7 @@
|
|||
#include "llviewerwindow.h"
|
||||
#include "llvlmanager.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "llvovolume.h"
|
||||
#include "llworld.h"
|
||||
#include "llworldmap.h"
|
||||
#include "pipeline.h"
|
||||
|
|
@ -6510,12 +6512,15 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
|
|||
LLUUID animation_id;
|
||||
LLUUID uuid;
|
||||
S32 anim_sequence_id;
|
||||
LLVOAvatar *avatarp;
|
||||
LLVOAvatar *avatarp = NULL;
|
||||
|
||||
mesgsys->getUUIDFast(_PREHASH_Sender, _PREHASH_ID, uuid);
|
||||
|
||||
//clear animation flags
|
||||
avatarp = (LLVOAvatar *)gObjectList.findObject(uuid);
|
||||
LLViewerObject *objp = gObjectList.findObject(uuid);
|
||||
if (objp)
|
||||
{
|
||||
avatarp = objp->asAvatar();
|
||||
}
|
||||
|
||||
if (!avatarp)
|
||||
{
|
||||
|
|
@ -6527,6 +6532,7 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
|
|||
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationList);
|
||||
S32 num_source_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationSourceList);
|
||||
|
||||
//clear animation flags
|
||||
avatarp->mSignaledAnimations.clear();
|
||||
|
||||
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)
|
||||
{
|
||||
LLUUID uuid;
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ void process_health_message(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_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_camera_constraint(LLMessageSystem *mesgsys, void **user_data);
|
||||
void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
#include "llbbox.h"
|
||||
#include "llbox.h"
|
||||
#include "llcylinder.h"
|
||||
#include "llcontrolavatar.h"
|
||||
#include "lldrawable.h"
|
||||
#include "llface.h"
|
||||
#include "llfloaterproperties.h"
|
||||
|
|
@ -150,7 +151,7 @@ const F32 PHYSICS_TIMESTEP = 1.f / 45.f;
|
|||
static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object");
|
||||
|
||||
// static
|
||||
LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
|
||||
LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, S32 flags)
|
||||
{
|
||||
LLViewerObject *res = NULL;
|
||||
LL_RECORD_BLOCK_TIME(FTM_CREATE_OBJECT);
|
||||
|
|
@ -184,6 +185,12 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
|
|||
}
|
||||
res = gAgentAvatarp;
|
||||
}
|
||||
else if (flags & CO_FLAG_CONTROL_AVATAR)
|
||||
{
|
||||
LLControlAvatar *avatar = new LLControlAvatar(id, pcode, regionp);
|
||||
avatar->initInstance();
|
||||
res = avatar;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVOAvatar *avatar = new LLVOAvatar(id, pcode, regionp);
|
||||
|
|
@ -253,6 +260,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
|
|||
mText(),
|
||||
mHudText(""),
|
||||
mHudTextColor(LLColor4::white),
|
||||
mControlAvatar(NULL),
|
||||
mLastInterpUpdateSecs(0.f),
|
||||
mLastMessageUpdateSecs(0.f),
|
||||
mLatestRecvPacketID(0),
|
||||
|
|
@ -277,7 +285,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
|
|||
mRotTime(0.f),
|
||||
mAngularVelocityRot(),
|
||||
mPreviousRotation(),
|
||||
mState(0),
|
||||
mAttachmentState(0),
|
||||
mMedia(NULL),
|
||||
mClickAction(0),
|
||||
mObjectCost(0),
|
||||
|
|
@ -381,16 +389,22 @@ void LLViewerObject::markDead()
|
|||
//LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL;
|
||||
|
||||
// Root object of this hierarchy unlinks itself.
|
||||
LLVOAvatar *av = getAvatarAncestor();
|
||||
if (getParent())
|
||||
{
|
||||
((LLViewerObject *)getParent())->removeChild(this);
|
||||
}
|
||||
LLUUID mesh_id;
|
||||
{
|
||||
LLVOAvatar *av = getAvatar();
|
||||
if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id))
|
||||
{
|
||||
// This case is needed for indirectly attached mesh objects.
|
||||
av->resetJointsOnDetach(mesh_id);
|
||||
av->removeAttachmentOverridesForObject(mesh_id);
|
||||
}
|
||||
}
|
||||
if (getControlAvatar())
|
||||
{
|
||||
unlinkControlAvatar();
|
||||
}
|
||||
|
||||
// Mark itself as dead
|
||||
|
|
@ -1408,7 +1422,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
|
||||
U8 state;
|
||||
mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
|
||||
mState = state;
|
||||
mAttachmentState = state;
|
||||
|
||||
// ...new objects that should come in selected need to be added to the selected list
|
||||
mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
|
||||
|
|
@ -1684,7 +1698,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
|
||||
U8 state;
|
||||
mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
|
||||
mState = state;
|
||||
mAttachmentState = state;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1707,7 +1721,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
U8 state;
|
||||
|
||||
dp->unpackU8(state, "State");
|
||||
mState = state;
|
||||
mAttachmentState = state;
|
||||
|
||||
switch(update_type)
|
||||
{
|
||||
|
|
@ -2050,7 +2064,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
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())
|
||||
S32 idxAttachPt = ATTACHMENT_ID_FROM_STATE(getState());
|
||||
S32 idxAttachPt = ATTACHMENT_ID_FROM_STATE(getAttachmentState());
|
||||
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
|
||||
|
|
@ -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
|
||||
{
|
||||
LLUUID mTaskID;
|
||||
|
|
@ -3950,7 +4019,7 @@ const LLVector3 LLViewerObject::getRenderPosition() const
|
|||
if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED))
|
||||
{
|
||||
LLVOAvatar* avatar = getAvatar();
|
||||
if (avatar)
|
||||
if (avatar && !getControlAvatar())
|
||||
{
|
||||
return avatar->getPositionAgent();
|
||||
}
|
||||
|
|
@ -5213,7 +5282,13 @@ LLVOAvatar* LLViewerObject::asAvatar()
|
|||
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()
|
||||
{
|
||||
LLViewerObject *pobj = (LLViewerObject*) getParent();
|
||||
|
|
@ -5560,6 +5635,11 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para
|
|||
new_block = new LLLightImageParams();
|
||||
break;
|
||||
}
|
||||
case LLNetworkData::PARAMS_EXTENDED_MESH:
|
||||
{
|
||||
new_block = new LLExtendedMeshParams();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LL_INFOS() << "Unknown param type." << LL_ENDL;
|
||||
|
|
@ -6461,6 +6541,10 @@ const std::string& LLViewerObject::getAttachmentItemName() const
|
|||
//virtual
|
||||
LLVOAvatar* LLViewerObject::getAvatar() const
|
||||
{
|
||||
if (getControlAvatar())
|
||||
{
|
||||
return getControlAvatar();
|
||||
}
|
||||
if (isAttachment())
|
||||
{
|
||||
LLViewerObject* vobj = (LLViewerObject*) getParent();
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ class LLAgent; // TODO: Get rid of this.
|
|||
class LLAudioSource;
|
||||
class LLAudioSourceVO;
|
||||
class LLColor4;
|
||||
class LLControlAvatar;
|
||||
class LLDataPacker;
|
||||
class LLDataPackerBinaryBuffer;
|
||||
class LLDrawable;
|
||||
|
|
@ -378,9 +379,9 @@ public:
|
|||
|
||||
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
|
||||
U8 getState() const { return mState; }
|
||||
U8 getAttachmentState() const { return mAttachmentState; }
|
||||
// [/RLVa:KB]
|
||||
|
||||
F32 getAppAngle() const { return mAppAngle; }
|
||||
|
|
@ -700,6 +701,21 @@ public:
|
|||
|
||||
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:
|
||||
// delete an item in the inventory, but don't tell the
|
||||
// server. This is used internally by remove, update, and
|
||||
|
|
@ -710,8 +726,10 @@ protected:
|
|||
// updateInventory.
|
||||
void doUpdateInventory(LLPointer<LLViewerInventoryItem>& item, U8 key, bool is_new);
|
||||
|
||||
// Flags for createObject
|
||||
static const S32 CO_FLAG_CONTROL_AVATAR = 1 << 1;
|
||||
|
||||
static LLViewerObject *createObject(const LLUUID &id, LLPCode pcode, LLViewerRegion *regionp);
|
||||
static LLViewerObject *createObject(const LLUUID &id, LLPCode pcode, LLViewerRegion *regionp, S32 flags = 0);
|
||||
|
||||
BOOL setData(const U8 *datap, const U32 data_size);
|
||||
|
||||
|
|
@ -799,7 +817,7 @@ protected:
|
|||
LLQuaternion mAngularVelocityRot; // accumulated rotation from the angular velocity computations
|
||||
LLQuaternion mPreviousRotation;
|
||||
|
||||
U8 mState; // legacy
|
||||
U8 mAttachmentState; // this encodes the attachment id in a somewhat complex way. 0 if not an attachment.
|
||||
LLViewerObjectMedia* mMedia; // NULL if no media associated
|
||||
U8 mClickAction;
|
||||
F32 mObjectCost; //resource cost of this object or -1 if unknown
|
||||
|
|
|
|||
|
|
@ -2127,12 +2127,12 @@ void LLViewerObjectList::resetObjectBeacons()
|
|||
mDebugBeacons.clear();
|
||||
}
|
||||
|
||||
LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp)
|
||||
LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp, S32 flags)
|
||||
{
|
||||
LLUUID fullid;
|
||||
fullid.generate();
|
||||
|
||||
LLViewerObject *objectp = LLViewerObject::createObject(fullid, pcode, regionp);
|
||||
LLViewerObject *objectp = LLViewerObject::createObject(fullid, pcode, regionp, flags);
|
||||
if (!objectp)
|
||||
{
|
||||
// LL_WARNS() << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public:
|
|||
inline LLViewerObject *getObject(const S32 index);
|
||||
|
||||
inline LLViewerObject *findObject(const LLUUID &id);
|
||||
LLViewerObject *createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp); // Create a viewer-side object
|
||||
LLViewerObject *createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp, S32 flags = 0); // Create a viewer-side object
|
||||
LLViewerObject *createObjectFromCache(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id);
|
||||
LLViewerObject *createObject(const LLPCode pcode, LLViewerRegion *regionp,
|
||||
const LLUUID &uuid, const U32 local_id, const LLHost &sender);
|
||||
|
|
|
|||
|
|
@ -3056,6 +3056,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
|
|||
capabilityNames.append("MeshUploadFlag");
|
||||
capabilityNames.append("NavMeshGenerationStatus");
|
||||
capabilityNames.append("NewFileAgentInventory");
|
||||
capabilityNames.append("ObjectAnimation");
|
||||
capabilityNames.append("ObjectMedia");
|
||||
capabilityNames.append("ObjectMediaNavigate");
|
||||
capabilityNames.append("ObjectNavMeshProperties");
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -170,7 +170,8 @@ public:
|
|||
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
|
||||
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
|
||||
BOOL pick_transparent = FALSE,
|
||||
BOOL pick_rigged = FALSE,
|
||||
|
|
@ -207,8 +208,8 @@ public:
|
|||
LLJoint* getJoint(S32 num);
|
||||
|
||||
void addAttachmentOverridesForObject(LLViewerObject *vo);
|
||||
void resetJointsOnDetach(const LLUUID& mesh_id);
|
||||
void resetJointsOnDetach(LLViewerObject *vo);
|
||||
void removeAttachmentOverridesForObject(const LLUUID& mesh_id);
|
||||
void removeAttachmentOverridesForObject(LLViewerObject *vo);
|
||||
bool jointIsRiggedTo(const std::string& joint_name);
|
||||
bool jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo);
|
||||
void clearAttachmentOverrides();
|
||||
|
|
@ -238,6 +239,8 @@ public:
|
|||
public:
|
||||
virtual bool isSelf() const { return false; } // True if this avatar is for this viewer's agent
|
||||
|
||||
virtual bool isControlAvatar() const { return mIsControlAvatar; } // True if this avatar is a control av (no associated user)
|
||||
|
||||
private: //aligned members
|
||||
LL_ALIGN_16(LLVector4a mImpostorExtents[2]);
|
||||
|
||||
|
|
@ -245,8 +248,14 @@ private: //aligned members
|
|||
// Updates
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void updateDebugText();
|
||||
virtual void updateDebugText();
|
||||
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 idleUpdateMisc(bool detailed_update);
|
||||
virtual void idleUpdateAppearanceAnimation();
|
||||
|
|
@ -452,6 +461,13 @@ public:
|
|||
|
||||
VisualMuteSettings mVisuallyMuteSetting; // Always or never visually mute this AV
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// animated object status
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
bool mIsControlAvatar;
|
||||
bool mEnableDefaultMotions;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Morph masks
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -769,9 +785,9 @@ public:
|
|||
static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
|
||||
/*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const;
|
||||
LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const;
|
||||
LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
|
||||
|
||||
//-TT Patch: ReplaceWornItemsOnly
|
||||
LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
|
||||
//-TT
|
||||
protected:
|
||||
//LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
|
||||
|
|
@ -794,10 +810,11 @@ public:
|
|||
BOOL hasHUDAttachment() const;
|
||||
LLBBox getHUDBBox() const;
|
||||
void resetHUDAttachments();
|
||||
BOOL canAttachMoreObjects() const;
|
||||
BOOL canAttachMoreObjects(U32 n) const;
|
||||
BOOL canAttachMoreObjects(U32 n=1) const;
|
||||
BOOL canAttachMoreAnimatedObjects(U32 n=1) const;
|
||||
protected:
|
||||
U32 getNumAttachments() const; // O(N), not O(1)
|
||||
U32 getNumAnimatedObjectAttachments() const; // O(N), not O(1)
|
||||
|
||||
/** Wearables
|
||||
** **
|
||||
|
|
|
|||
|
|
@ -3370,7 +3370,7 @@ BOOL LLVOAvatarSelf::needsRenderBeam()
|
|||
// don't render selection beam on hud objects
|
||||
is_touching_or_grabbing = FALSE;
|
||||
}
|
||||
return is_touching_or_grabbing || (mState & AGENT_STATE_EDITING && LLSelectMgr::getInstance()->shouldShowSelection());
|
||||
return is_touching_or_grabbing || (getAttachmentState() & AGENT_STATE_EDITING && LLSelectMgr::getInstance()->shouldShowSelection());
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
|||
|
|
@ -92,7 +92,8 @@ LLVOGrass::~LLVOGrass()
|
|||
|
||||
void LLVOGrass::updateSpecies()
|
||||
{
|
||||
mSpecies = mState;
|
||||
// AXON is grass still even supported? This use of state seems odd.
|
||||
mSpecies = getAttachmentState();
|
||||
|
||||
if (!sSpeciesTable.count(mSpecies))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -76,8 +76,13 @@
|
|||
#include "lldatapacker.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llcontrolavatar.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "llvocache.h"
|
||||
#include "llmaterialmgr.h"
|
||||
#include "llanimationstates.h"
|
||||
#include "llinventorytype.h"
|
||||
#include "llviewerinventory.h"
|
||||
// [RLVa:KB] - Checked: RLVa-2.0.0
|
||||
#include "rlvactions.h"
|
||||
#include "rlvlocks.h"
|
||||
|
|
@ -90,6 +95,8 @@ U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 1;
|
|||
BOOL gAnimateTextures = TRUE;
|
||||
//extern BOOL gHideSelectedObjects;
|
||||
|
||||
// AXON TEMP
|
||||
S32 LLVOVolume::sForceLOD = -1;
|
||||
F32 LLVOVolume::sLODFactor = 1.f;
|
||||
F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop
|
||||
F32 LLVOVolume::sDistanceFactor = 1.0f;
|
||||
|
|
@ -1361,6 +1368,13 @@ void LLVOVolume::sculpt()
|
|||
S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius)
|
||||
{
|
||||
S32 cur_detail;
|
||||
// AXON TEMP
|
||||
if (LLVOVolume::sForceLOD>=0 && LLVOVolume::sForceLOD<=3)
|
||||
{
|
||||
cur_detail = LLVOVolume::sForceLOD;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LLPipeline::sDynamicLOD)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
return cur_detail;
|
||||
}
|
||||
|
||||
|
|
@ -1427,13 +1442,36 @@ BOOL LLVOVolume::calcLOD()
|
|||
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
|
||||
//if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) &&
|
||||
// mDrawable->getFace(0))
|
||||
//{
|
||||
// //setDebugText(llformat("%.2f:%.2f, %d", mDrawable->mDistanceWRTCamera, radius, cur_detail));
|
||||
|
||||
// setDebugText(llformat("%d", mDrawable->getFace(0)->getTextureIndex()));
|
||||
//// This is a debug display for LODs. Please don't put the texture index here.
|
||||
//setDebugText(llformat("%d", cur_detail));
|
||||
//}
|
||||
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO))
|
||||
{
|
||||
|
|
@ -1542,7 +1580,8 @@ void LLVOVolume::updateFaceFlags()
|
|||
BOOL LLVOVolume::setParent(LLViewerObject* parent)
|
||||
{
|
||||
BOOL ret = FALSE ;
|
||||
if (parent != getParent())
|
||||
LLViewerObject *old_parent = (LLViewerObject*) getParent();
|
||||
if (parent != old_parent)
|
||||
{
|
||||
ret = LLViewerObject::setParent(parent);
|
||||
if (ret && mDrawable)
|
||||
|
|
@ -1550,6 +1589,7 @@ BOOL LLVOVolume::setParent(LLViewerObject* parent)
|
|||
gPipeline.markMoved(mDrawable);
|
||||
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
|
||||
}
|
||||
updateAnimatedObjectState(old_parent, parent);
|
||||
}
|
||||
|
||||
return ret ;
|
||||
|
|
@ -3441,6 +3481,176 @@ BOOL LLVOVolume::setIsFlexible(BOOL is_flexible)
|
|||
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)
|
||||
|
|
@ -3502,7 +3712,7 @@ void LLVOVolume::updateRadius()
|
|||
|
||||
BOOL LLVOVolume::isAttachment() const
|
||||
{
|
||||
return mState != 0 ;
|
||||
return mAttachmentState != 0 ;
|
||||
}
|
||||
|
||||
BOOL LLVOVolume::isHUDAttachment() const
|
||||
|
|
@ -3510,7 +3720,7 @@ BOOL LLVOVolume::isHUDAttachment() const
|
|||
// *NOTE: we assume hud attachment points are in defined range
|
||||
// since this range is constant for backwards compatibility
|
||||
// reasons this is probably a reasonable assumption to make
|
||||
S32 attachment_id = ATTACHMENT_ID_FROM_STATE(mState);
|
||||
S32 attachment_id = ATTACHMENT_ID_FROM_STATE(mAttachmentState);
|
||||
return ( attachment_id >= 31 && attachment_id <= 38 );
|
||||
}
|
||||
|
||||
|
|
@ -4279,7 +4489,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
|
|||
bool LLVOVolume::treatAsRigged()
|
||||
{
|
||||
return isSelected() &&
|
||||
isAttachment() &&
|
||||
(isAttachment() || isAnimatedObject()) &&
|
||||
mDrawable.notNull() &&
|
||||
mDrawable->isState(LLDrawable::RIGGED);
|
||||
}
|
||||
|
|
@ -4374,6 +4584,9 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
|
|||
U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
U32 max_joints = LLSkinningUtil::getMaxJointCount();
|
||||
rigged_vert_count += dst_face.mNumVertices;
|
||||
rigged_face_count++;
|
||||
for (U32 j = 0; j < dst_face.mNumVertices; ++j)
|
||||
{
|
||||
LLMatrix4a final_mat;
|
||||
|
|
@ -4418,12 +4633,19 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
|
|||
|
||||
min = pos[0];
|
||||
max = pos[1];
|
||||
if (i==0)
|
||||
{
|
||||
box_min = min;
|
||||
box_max = max;
|
||||
}
|
||||
|
||||
for (U32 j = 1; j < dst_face.mNumVertices; ++j)
|
||||
{
|
||||
min.setMin(min, 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->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
|
||||
|
|
@ -5028,11 +5254,35 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
vobj->isMesh() &&
|
||||
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();
|
||||
|
||||
// AXON why this variable? Only different from rigged if
|
||||
// there are no LLFaces associated with the drawable.
|
||||
bool is_rigged = false;
|
||||
|
||||
if (rigged && pAvatarVO)
|
||||
// AXON handle NPC case
|
||||
if (rigged && pAvatarVO && !vobj->isAnimatedObject())
|
||||
{
|
||||
pAvatarVO->addAttachmentOverridesForObject(vobj);
|
||||
if (!LLApp::isExiting() && pAvatarVO->isSelf() && debugLoggingEnabled("AvatarAttachments"))
|
||||
|
|
@ -5058,7 +5308,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
//sum up face verts and indices
|
||||
drawablep->updateFaceSize(i);
|
||||
|
||||
if (rigged)
|
||||
if (rigged || (vobj->getControlAvatar() && vobj->getControlAvatar()->mPlaying))
|
||||
{
|
||||
if (!facep->isState(LLFace::RIGGED))
|
||||
{ //completely reset vertex buffer
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ public:
|
|||
}
|
||||
|
||||
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.
|
||||
|
|
@ -262,10 +264,24 @@ public:
|
|||
virtual BOOL isMesh() const;
|
||||
virtual BOOL hasLightTexture() const;
|
||||
|
||||
|
||||
BOOL isVolumeGlobal() const;
|
||||
BOOL canBeFlexible() const;
|
||||
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
|
||||
|
||||
// Update this object's media data with the given media data array
|
||||
|
|
@ -381,6 +397,7 @@ private:
|
|||
public:
|
||||
static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop
|
||||
static F32 sLODFactor; // LOD scale factor
|
||||
static S32 sForceLOD; // LOD override
|
||||
static F32 sDistanceFactor; // LOD distance factor
|
||||
|
||||
static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;
|
||||
|
|
|
|||
|
|
@ -6958,7 +6958,10 @@ BOOL LLPipeline::toggleRenderTypeControlNegated(void* data)
|
|||
//static
|
||||
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))
|
||||
{
|
||||
LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " off" << std::dec << LL_ENDL;
|
||||
|
|
@ -6974,7 +6977,10 @@ void LLPipeline::toggleRenderDebug(void* data)
|
|||
//static
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -330,10 +330,16 @@ public:
|
|||
void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES);
|
||||
|
||||
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 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; }
|
||||
|
||||
BOOL hasRenderType(const U32 type) const;
|
||||
|
|
@ -510,7 +516,7 @@ public:
|
|||
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_VERIFY = 0x00000002,
|
||||
|
|
@ -523,11 +529,11 @@ public:
|
|||
RENDER_DEBUG_TEXTURE_AREA = 0x00000100,
|
||||
RENDER_DEBUG_FACE_AREA = 0x00000200,
|
||||
RENDER_DEBUG_PARTICLES = 0x00000400,
|
||||
RENDER_DEBUG_GLOW = 0x00000800,
|
||||
RENDER_DEBUG_GLOW = 0x00000800, // not used
|
||||
RENDER_DEBUG_TEXTURE_ANIM = 0x00001000,
|
||||
RENDER_DEBUG_LIGHTS = 0x00002000,
|
||||
RENDER_DEBUG_BATCH_SIZE = 0x00004000,
|
||||
RENDER_DEBUG_ALPHA_BINS = 0x00008000,
|
||||
RENDER_DEBUG_ALPHA_BINS = 0x00008000, // not used
|
||||
RENDER_DEBUG_RAYCAST = 0x00010000,
|
||||
RENDER_DEBUG_AVATAR_DRAW_INFO = 0x00020000,
|
||||
RENDER_DEBUG_SHADOW_FRUSTA = 0x00040000,
|
||||
|
|
@ -541,9 +547,10 @@ public:
|
|||
RENDER_DEBUG_NORMALS = 0x04000000,
|
||||
RENDER_DEBUG_LOD_INFO = 0x08000000,
|
||||
RENDER_DEBUG_RENDER_COMPLEXITY = 0x10000000,
|
||||
RENDER_DEBUG_ATTACHMENT_BYTES = 0x20000000,
|
||||
RENDER_DEBUG_ATTACHMENT_BYTES = 0x20000000, // not used
|
||||
RENDER_DEBUG_TEXEL_DENSITY = 0x40000000,
|
||||
RENDER_DEBUG_TEXTURE_SIZE = 0x80000000
|
||||
RENDER_DEBUG_TRIANGLE_COUNT = 0x80000000,
|
||||
RENDER_DEBUG_TEXTURE_SIZE = 0x100000000
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
@ -689,10 +696,14 @@ protected:
|
|||
std::stack<std::string> mRenderTypeEnableStack;
|
||||
|
||||
U32 mRenderDebugFeatureMask;
|
||||
U32 mRenderDebugMask;
|
||||
// <FS:Ansariel> Need an unsigned long here
|
||||
//U32 mRenderDebugMask;
|
||||
U64 mRenderDebugMask;
|
||||
std::stack<U32> mRenderDebugFeatureStack;
|
||||
|
||||
U32 mOldRenderDebugMask;
|
||||
// <FS:Ansariel> Need an unsigned long here
|
||||
//U32 mOldRenderDebugMask;
|
||||
U64 mOldRenderDebugMask;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
|
|
|
|||
|
|
@ -888,7 +888,7 @@ RlvObject::RlvObject(const LLUUID& idObj) : m_idObj(idObj), m_nLookupMisses(0)
|
|||
{
|
||||
LLViewerObject* pObj = gObjectList.findObject(idObj);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ inline S32 RlvAttachPtLookup::getAttachPointIndex(std::string strText)
|
|||
// Checked: 2010-03-03 (RLVa-1.2.0a) | Modified: RLVa-0.2.0d
|
||||
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;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
|
|
|||
|
|
@ -2484,13 +2484,23 @@ even though the user gets a free copy.
|
|||
Edit object features:
|
||||
</text>
|
||||
<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"
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="Flexible1D Checkbox Ctrl"
|
||||
tool_tip="Allows object to flex about the Z axis (Client-side only)"
|
||||
top_pad="10"
|
||||
top_pad="5"
|
||||
width="121" />
|
||||
<spinner
|
||||
follows="left|top"
|
||||
|
|
@ -2503,7 +2513,7 @@ even though the user gets a free copy.
|
|||
left_delta="0"
|
||||
max_val="3"
|
||||
name="FlexNumSections"
|
||||
top_pad="10"
|
||||
top_pad="4"
|
||||
width="128" />
|
||||
<spinner
|
||||
follows="left|top"
|
||||
|
|
|
|||
|
|
@ -3714,6 +3714,16 @@
|
|||
function="Advanced.ToggleInfoDisplay"
|
||||
parameter="lod info" />
|
||||
</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
|
||||
label="Build Queue"
|
||||
name="Build Queue">
|
||||
|
|
|
|||
|
|
@ -11805,6 +11805,15 @@ Your access privileges don't allow you to duplicate objects here.
|
|||
You are not allowed to change this shape.
|
||||
</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
|
||||
icon="alertmodal.tga"
|
||||
name="NoAccessToClaimObjects"
|
||||
|
|
|
|||
|
|
@ -2542,13 +2542,23 @@ even though the user gets a free copy.
|
|||
Edit object features:
|
||||
</text>
|
||||
<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"
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="Flexible1D Checkbox Ctrl"
|
||||
tool_tip="Allows object to flex about the Z axis (Client-side only)"
|
||||
top_pad="10"
|
||||
top_pad="5"
|
||||
width="121" />
|
||||
<spinner
|
||||
follows="left|top"
|
||||
|
|
@ -2561,7 +2571,7 @@ even though the user gets a free copy.
|
|||
left_delta="0"
|
||||
max_val="3"
|
||||
name="FlexNumSections"
|
||||
top_pad="10"
|
||||
top_pad="4"
|
||||
width="128" />
|
||||
<spinner
|
||||
follows="left|top"
|
||||
|
|
|
|||
|
|
@ -2542,13 +2542,23 @@ even though the user gets a free copy.
|
|||
Edit object features:
|
||||
</text>
|
||||
<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"
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="Flexible1D Checkbox Ctrl"
|
||||
tool_tip="Allows object to flex about the Z axis (Client-side only)"
|
||||
top_pad="10"
|
||||
top_pad="5"
|
||||
width="121" />
|
||||
<spinner
|
||||
follows="left|top"
|
||||
|
|
@ -2561,7 +2571,7 @@ even though the user gets a free copy.
|
|||
left_delta="0"
|
||||
max_val="3"
|
||||
name="FlexNumSections"
|
||||
top_pad="10"
|
||||
top_pad="4"
|
||||
width="128" />
|
||||
<spinner
|
||||
follows="left|top"
|
||||
|
|
|
|||
|
|
@ -2476,13 +2476,23 @@ even though the user gets a free copy.
|
|||
Edit object features:
|
||||
</text>
|
||||
<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"
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="Flexible1D Checkbox Ctrl"
|
||||
tool_tip="Allows object to flex about the Z axis (Client-side only)"
|
||||
top_pad="10"
|
||||
top_pad="5"
|
||||
width="121" />
|
||||
<spinner
|
||||
follows="left|top"
|
||||
|
|
@ -2495,7 +2505,7 @@ even though the user gets a free copy.
|
|||
left_delta="0"
|
||||
max_val="3"
|
||||
name="FlexNumSections"
|
||||
top_pad="10"
|
||||
top_pad="4"
|
||||
width="128" />
|
||||
<spinner
|
||||
follows="left|top"
|
||||
|
|
|
|||
|
|
@ -384,7 +384,7 @@ namespace tut
|
|||
accountCredential->setCredentialData(identifier, authenticator);
|
||||
|
||||
logininstance->setNotificationsInterface(¬ifications);
|
||||
logininstance->setPlatformInfo("win", "1.3.5");
|
||||
logininstance->setPlatformInfo("win", "1.3.5", "Windows Bogus Version 100.6.6.6");
|
||||
}
|
||||
|
||||
LLLoginInstance* logininstance;
|
||||
|
|
@ -500,109 +500,4 @@ namespace tut
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llerrorcontrol.h"
|
||||
#include "lltut.h"
|
||||
|
|
@ -698,5 +697,4 @@ int main(int argc, char **argv)
|
|||
return retval;
|
||||
|
||||
//delete mycallback;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ version 2.0
|
|||
// for each type is listed below:
|
||||
// Low: 429
|
||||
// Medium: 18
|
||||
// High: 29
|
||||
// High: 30
|
||||
// PLEASE UPDATE THIS WHEN YOU ADD A NEW MESSAGE!
|
||||
|
||||
|
||||
|
|
@ -3574,7 +3574,6 @@ version 2.0
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
// AvatarAppearance - Update visual params
|
||||
{
|
||||
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
|
||||
// *************************************************************************
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
8535acbfaf222a8e026283a74d869402a0458314
|
||||
65309e77b91facecb65ea0dfac478d7737e9641f
|
||||
|
|
@ -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:
|
||||
|
|
@ -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:
|
||||
|
|
@ -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:
|
||||
|
|
@ -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:
|
||||
Loading…
Reference in New Issue