Merge axon

meow-7.2.2
Ansariel 2018-01-04 15:53:22 +01:00
commit 0669906f4b
19 changed files with 188 additions and 72 deletions

View File

@ -1753,7 +1753,7 @@ void LLAvatarAppearance::makeJointAliases(LLAvatarBoneInfo *bone_info)
}
mJointAliasMap[*i] = bone_name;
}
LLAvatarBoneInfo::child_list_t::const_iterator iter;
for (iter = bone_info->mChildList.begin(); iter != bone_info->mChildList.end(); ++iter)
{
@ -1768,13 +1768,34 @@ const LLAvatarAppearance::joint_alias_map_t& LLAvatarAppearance::getJointAliases
{
LLAvatarSkeletonInfo::bone_info_list_t::const_iterator iter;
for (iter = sAvatarSkeletonInfo->mBoneInfoList.begin(); iter != sAvatarSkeletonInfo->mBoneInfoList.end(); ++iter)
for (iter = sAvatarSkeletonInfo->mBoneInfoList.begin();
iter != sAvatarSkeletonInfo->mBoneInfoList.end();
++iter)
{
//LLAvatarBoneInfo *bone_info = *iter;
makeJointAliases( *iter );
}
LLAvatarXmlInfo::attachment_info_list_t::iterator attach_iter;
for (attach_iter = sAvatarXmlInfo->mAttachmentInfoList.begin();
attach_iter != sAvatarXmlInfo->mAttachmentInfoList.end();
++attach_iter)
{
LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *attach_iter;
std::string bone_name = info->mName;
// Also accept the name with spaces substituted with
// underscores. This gives a mechanism for referencing such joints
// in daes, which don't allow spaces.
std::string sub_space_to_underscore = bone_name;
LLStringUtil::replaceChar(sub_space_to_underscore, ' ', '_');
if (sub_space_to_underscore != bone_name)
{
mJointAliasMap[sub_space_to_underscore] = bone_name;
}
}
}
return mJointAliasMap;
}

View File

@ -136,7 +136,7 @@ LLMotionController::LLMotionController()
mLastTime(0.0f),
mHasRunOnce(FALSE),
mPaused(FALSE),
mPauseTime(0.f),
mPausedFrame(0),
mTimeStep(0.f),
mTimeStepCount(0),
mLastInterp(0.f),
@ -1133,6 +1133,7 @@ void LLMotionController::pauseAllMotions()
{
//LL_INFOS() << "Pausing animations..." << LL_ENDL;
mPaused = TRUE;
mPausedFrame = LLFrameTimer::getFrameCount();
}
}

View File

@ -148,6 +148,7 @@ public:
void pauseAllMotions();
void unpauseAllMotions();
BOOL isPaused() const { return mPaused; }
S32 getPausedFrame() const { return mPausedFrame; }
void setTimeStep(F32 step);
F32 getTimeStep() const { return mTimeStep; }
@ -225,7 +226,7 @@ protected:
F32 mLastTime;
BOOL mHasRunOnce;
BOOL mPaused;
F32 mPauseTime;
S32 mPausedFrame;
F32 mTimeStep;
S32 mTimeStepCount;
F32 mLastInterp;

View File

@ -3781,6 +3781,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>AnimatedObjectsAllowLeftClick</key>
<map>
<key>Comment</key>
<string>Allow left-click interaction with animated objects. Uncertain how much performance impact this will have.</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>

View File

@ -113,7 +113,7 @@ void LLControlAvatar::setGlobalScale(F32 scale)
{
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?
// should we be scaling from the pelvis or the root?
recursiveScaleJoint(mPelvisp,adjust_scale);
mGlobalScale = scale;
}
@ -167,7 +167,10 @@ void LLControlAvatar::updateVolumeGeom()
matchVolumeTransform();
// AXON testing scale
// Initial exploration of allowing scaling skeleton to match root
// prim bounding box. If enabled, would probably be controlled by
// an additional checkbox and default to off. Not enabled for
// initial release.
// What should the scale be? What we really want is the ratio
// between the scale at which the object was originally designed
@ -239,6 +242,7 @@ void LLControlAvatar::updateDebugText()
std::string lod_string;
S32 total_tris = 0;
S32 total_verts = 0;
S32 est_tris = 0;
for (std::vector<LLVOVolume*>::iterator it = volumes.begin();
it != volumes.end(); ++it)
{
@ -246,6 +250,7 @@ void LLControlAvatar::updateDebugText()
S32 verts = 0;
total_tris += volp->getTriangleCount(&verts);
total_verts += verts;
est_tris += volp->getEstTrianglesMax();
lod_string += llformat("%d",volp->getLOD());
if (volp && volp->mDrawable)
{
@ -282,8 +287,9 @@ void LLControlAvatar::updateDebugText()
addDebugText(llformat("CAV obj %d anim %d active %s impost %d",
total_linkset_count, animated_volume_count, active_string.c_str(), (S32) isImpostor()));
addDebugText(llformat("types %s lods %s", type_string.c_str(), lod_string.c_str()));
addDebugText(llformat("tris %d verts %d", total_tris, total_verts));
addDebugText(llformat("tris %d (est %d), verts %d", total_tris, est_tris, total_verts));
addDebugText(llformat("pxarea %s", LLStringOps::getReadableNumber(getPixelArea()).c_str()));
#if 0
std::string region_name = "no region";
if (mRootVolp->getRegion())
{
@ -297,10 +303,7 @@ void LLControlAvatar::updateDebugText()
addDebugText(llformat("region %x %s skel %x %s",
mRootVolp->getRegion(), region_name.c_str(),
getRegion(), skel_region_name.c_str()));
//addDebugText(llformat("anim time %.1f (step %f factor %f)",
// mMotionController.getAnimTime(),
// mMotionController.getTimeStep(),
// mMotionController.getTimeFactor()));
#endif
}
LLVOAvatar::updateDebugText();

View File

@ -140,7 +140,7 @@ LLViewerTexture *LLDrawPool::getDebugTexture()
return NULL;
}
//virtual
//virtuals
void LLDrawPool::beginRenderPass( S32 pass )
{
}

View File

@ -116,6 +116,32 @@ LLDrawPoolAvatar::LLDrawPoolAvatar() :
{
}
LLDrawPoolAvatar::~LLDrawPoolAvatar()
{
if (!isDead())
{
LL_WARNS() << "Destroying avatar drawpool that still contains faces" << LL_ENDL;
}
}
// virtual
BOOL LLDrawPoolAvatar::isDead()
{
if (!LLFacePool::isDead())
{
return FALSE;
}
for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i)
{
if (mRiggedFace[i].size() > 0)
{
return FALSE;
}
}
return TRUE;
}
//-----------------------------------------------------------------------------
// instancePool()
//-----------------------------------------------------------------------------
@ -2345,11 +2371,16 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const
void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)
{
llassert (facep->isState(LLFace::RIGGED));
llassert(getType() == LLDrawPool::POOL_AVATAR);
if (facep->getPool() && facep->getPool() != this)
{
LL_ERRS() << "adding rigged face that's already in another pool" << LL_ENDL;
}
if (type >= NUM_RIGGED_PASSES)
{
LL_ERRS() << "Invalid rigged face type." << LL_ENDL;
}
if (facep->getRiggedIndex(type) != -1)
{
LL_ERRS() << "Tried to add a rigged face that's referenced elsewhere." << LL_ENDL;
@ -2362,6 +2393,12 @@ void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)
void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep)
{
llassert (facep->isState(LLFace::RIGGED));
llassert(getType() == LLDrawPool::POOL_AVATAR);
if (facep->getPool() != this)
{
LL_ERRS() << "Tried to remove a rigged face from the wrong pool" << LL_ENDL;
}
facep->setPool(NULL);
for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i)

View File

@ -60,6 +60,8 @@ public:
virtual S32 getVertexShaderLevel() const;
LLDrawPoolAvatar();
~LLDrawPoolAvatar();
/*virtual*/ BOOL isDead();
static LLMatrix4& getModelView();

View File

@ -793,7 +793,7 @@ void LLToolDragAndDrop::dragOrDrop3D( S32 x, S32 y, MASK mask, BOOL drop, EAccep
mDrop = drop;
if (mDrop)
{
// don't allow drag and drop onto transparent objects
// don't allow drag and drop onto rigged or transparent objects
pick(gViewerWindow->pickImmediate(x, y, FALSE, FALSE));
}
else

View File

@ -120,9 +120,12 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
mMouseOutsideSlop = FALSE;
mMouseDownX = x;
mMouseDownY = y;
LLTimer pick_timer;
// AXON experimental feature
BOOL pick_rigged = gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
//left mouse down always picks transparent (but see handleMouseUp)
mPick = gViewerWindow->pickImmediate(x, y, TRUE, FALSE);
mPick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged);
LL_INFOS() << "pick_rigged is " << (S32) pick_rigged << " pick time elapsed " << pick_timer.getElapsedTimeF32() << LL_ENDL;
mPick.mKeyMask = mask;
mMouseButtonDown = true;
@ -137,7 +140,10 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
// don't pick transparent so users can't "pay" transparent objects
mPick = gViewerWindow->pickImmediate(x, y, /*BOOL pick_transparent*/ FALSE, /*BOOL pick_rigged*/ TRUE, /*BOOL pick_particle*/ TRUE);
mPick = gViewerWindow->pickImmediate(x, y,
/*BOOL pick_transparent*/ FALSE,
/*BOOL pick_rigged*/ TRUE,
/*BOOL pick_particle*/ TRUE);
mPick.mKeyMask = mask;
// claim not handled so UI focus stays same
@ -579,7 +585,9 @@ void LLToolPie::selectionPropertiesReceived()
BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
{
mHoverPick = gViewerWindow->pickImmediate(x, y, FALSE, FALSE);
// AXON experimental feature
BOOL pick_rigged = gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
mHoverPick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged);
LLViewerObject *parent = NULL;
LLViewerObject *object = mHoverPick.getObject();
// [RLVa:KB] - Checked: RLVa-1.1.0
@ -640,7 +648,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
else
{
// perform a separate pick that detects transparent objects since they respond to 1-click actions
LLPickInfo click_action_pick = gViewerWindow->pickImmediate(x, y, TRUE, FALSE);
LLPickInfo click_action_pick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged);
LLViewerObject* click_action_object = click_action_pick.getObject();
@ -732,6 +740,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
LLPickInfo savedPick = mPick;
mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY,
FALSE /* ignore transparent */,
FALSE /* ignore rigged */,
FALSE /* ignore particles */);
// if (!mPick.mPosGlobal.isExactlyZero() // valid coordinates for pick
@ -835,6 +844,7 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)
LLPickInfo savedPick = mPick;
mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY,
FALSE /* ignore transparent */,
FALSE /* ignore rigged */,
FALSE /* ignore particles */);
if(mPick.mPickType == LLPickInfo::PICK_OBJECT)

View File

@ -68,7 +68,9 @@ LLToolSelect::LLToolSelect( LLToolComposite* composite )
BOOL LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)
{
// do immediate pick query
mPick = gViewerWindow->pickImmediate(x, y, TRUE, FALSE);
// AXON experimental feature
BOOL pick_rigged = gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
mPick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged);
// Pass mousedown to agent
LLTool::handleMouseDown(x, y, mask);

View File

@ -71,7 +71,9 @@ void dialog_refresh_all(void);
BOOL LLToolSelectRect::handleMouseDown(S32 x, S32 y, MASK mask)
{
handlePick(gViewerWindow->pickImmediate(x, y, TRUE, FALSE));
// AXON experimental feature
BOOL pick_rigged = gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
handlePick(gViewerWindow->pickImmediate(x, y, TRUE /* pick_transparent */, pick_rigged));
LLTool::handleMouseDown(x, y, mask);

View File

@ -6676,6 +6676,7 @@ void process_object_animation(LLMessageSystem *mesgsys, void **user_data)
return;
}
volp->updateControlAvatar();
LLControlAvatar *avatarp = volp->getControlAvatar();
if (!avatarp)
{

View File

@ -3018,6 +3018,34 @@ LLControlAvatar *LLViewerObject::getControlAvatar() const
return getRootEdit()->mControlAvatar.get();
}
void LLViewerObject::updateControlAvatar()
{
LLViewerObject *root = getRootEdit();
if (root->isAnimatedObject() && !root->getControlAvatar())
{
bool any_mesh = root->isMesh();
LLViewerObject::const_child_list_t& child_list = root->getChildren();
for (LLViewerObject::const_child_list_t::const_iterator iter = child_list.begin();
iter != child_list.end(); ++iter)
{
const LLViewerObject* child = *iter;
any_mesh = any_mesh || child->isMesh();
}
if (any_mesh)
{
std::string vobj_name = llformat("Vol%u", (U32) root);
LL_DEBUGS("AnimatedObjects") << vobj_name << " calling linkControlAvatar()" << LL_ENDL;
root->linkControlAvatar();
}
}
if (!root->isAnimatedObject() && root->getControlAvatar())
{
std::string vobj_name = llformat("Vol%u", (U32) root);
LL_DEBUGS("AnimatedObjects") << vobj_name << " calling unlinkControlAvatar()" << LL_ENDL;
root->unlinkControlAvatar();
}
}
void LLViewerObject::linkControlAvatar()
{
if (!getControlAvatar() && isRootEdit())

View File

@ -720,6 +720,8 @@ public:
void linkControlAvatar();
// Remove any reference to control av for this prim
void unlinkControlAvatar();
// Link or unlink as needed
void updateControlAvatar();
virtual bool isAnimatedObject() const;

View File

@ -1233,7 +1233,9 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi
if (prim_media_dnd_enabled)
{
LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY, TRUE /*BOOL pick_transparent*/, FALSE );
LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY,
TRUE /* pick_transparent */,
FALSE /* pick_rigged */);
LLUUID object_id = pick_info.getObjectID();
S32 object_face = pick_info.mObjectFace;

View File

@ -4020,7 +4020,10 @@ void LLVOAvatar::updateDebugText()
LLVOVolume *volp = control_av->mRootVolp;
if (volp)
{
volp->requestInventory();
if (volp->getInventorySerial()<=0)
{
volp->requestInventory();
}
LLViewerInventoryItem* item = volp->getInventoryItemByAsset(motionp->getID());
if (item)
{
@ -4525,7 +4528,6 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w
root_pos = gAgent.getPosGlobalFromAgent(getRenderPosition());
root_pos.mdV[VZ] += getVisualParamWeight(AVATAR_HOVER);
// AXON need to review mInAir calcs for animated objects, if the value even matters.
LLVector3 normal;
resolveHeightGlobal(root_pos, ground_under_pelvis, normal);
F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]);
@ -4574,9 +4576,8 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w
//--------------------------------------------------------------------
if (!isControlAvatar() && !isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS))
{
// AXON - should we always skip for control avatars?
// Rotation fixups for avatars in motion, some may be
// relevant.
// Rotation fixups for avatars in motion.
// Skip for animated objects.
updateOrientation(agent, speed, delta_time);
}
}
@ -6823,8 +6824,7 @@ void LLVOAvatar::getGround(const LLVector3 &in_pos_agent, LLVector3 &out_pos_age
LLVector3d z_vec(0.0f, 0.0f, 1.0f);
LLVector3d p0_global, p1_global;
// AXON UPDATE FOR CONTROL AVS?
if (mIsDummy)
if (isUIAvatar())
{
outNorm.setVec(z_vec);
out_pos_agent = in_pos_agent;

View File

@ -1452,16 +1452,12 @@ BOOL LLVOVolume::calcLOD()
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TRIANGLE_COUNT) && mDrawable->getFace(0))
{
if (isRootEdit() && getChildren().size()>0)
if (isRootEdit())
{
S32 total_tris = recursiveGetTriangleCount();
setDebugText(llformat("TRIS %d TOTAL %d", getTriangleCount(), total_tris));
S32 est_max_tris = recursiveGetEstTrianglesMax();
setDebugText(llformat("TRIS SHOWN %d EST %d", total_tris, est_max_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) &&
@ -3544,12 +3540,11 @@ U32 LLVOVolume::getExtendedMeshFlags() const
void LLVOVolume::onSetExtendedMeshFlags(U32 flags)
{
// AXON - the check against isAnySelected() is "empirically
// derived": doing rebuildGeom() while in selection trashes the
// graphics state of animated objects. Skipping this update is OK
// because we get another one on deselect.
if (!getRootEdit()->isAnySelected() && mDrawable.notNull())
// The isAnySelected() check was needed at one point to prevent
// graphics problems. These are now believed to be fixed so the
// check has been disabled.
if (/*!getRootEdit()->isAnySelected() &&*/ mDrawable.notNull())
{
// Need to trigger rebuildGeom(), which is where control avatars get created/removed
getRootEdit()->recursiveMarkForUpdate(TRUE);
@ -4646,6 +4641,21 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
{
copyVolumeFaces(volume);
}
else
{
#if 1
bool is_paused = avatar && avatar->areAnimationsPaused();
if (is_paused)
{
S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame();
if (frames_paused > 2)
{
return;
}
}
#endif
}
//build matrix palette
static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT;
@ -5343,38 +5353,13 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() &&
vobj->getControlAvatar() && vobj->getControlAvatar()->mPlaying);
if (vobj->isAnimatedObject())
vobj->updateControlAvatar();
if (vobj->getControlAvatar())
{
if (!vobj->getControlAvatar())
{
F32 tri_count = vobj->getRootEdit()->recursiveGetEstTrianglesMax();
if (tri_count <= 0.f)
{
LL_DEBUGS("AnimatedObjects") << vobj_name << " not calling linkControlAvatar(), because no tris" << LL_ENDL;
}
else
{
LL_DEBUGS("AnimatedObjects") << vobj_name << " calling linkControlAvatar()" << LL_ENDL;
vobj->linkControlAvatar();
}
}
if (vobj->getControlAvatar())
{
rigged_av = vobj->getControlAvatar();
rigged_av->rebuildAttachmentOverrides();
}
rigged_av = vobj->getControlAvatar();
rigged_av->rebuildAttachmentOverrides();
}
else
{
// Not animated but has a control avatar - probably
// the checkbox has changed since the last rebuild.
if (vobj->getControlAvatar())
{
LL_DEBUGS("AnimatedObjects") << vobj_name << " calling unlinkControlAvatar()" << LL_ENDL;
vobj->unlinkControlAvatar();
}
}
bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic();
bool any_rigged_face = false;

View File

@ -11683,6 +11683,14 @@ You have been teleported by the object '[OBJECT_NAME]' owned by an unknown user.
type="notify">
<tag>fail</tag>
Unable to create requested object. The region is full.
</notification>
<notification
icon="alertmodal.tga"
name="CantCreateAnimatedObjectTooLarge"
type="notify">
<tag>fail</tag>
Unable to create requested animated object because it exceeds the size limit.
</notification>
<notification