mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-13 03:33:48 +00:00
anim-clip -- sequence selection by afx effects
This commit is contained in:
parent
8c65467697
commit
ab88b8f489
6 changed files with 511 additions and 14 deletions
|
|
@ -2746,7 +2746,12 @@ void Player::updateMove(const Move* move)
|
|||
// Desired move direction & speed
|
||||
VectorF moveVec;
|
||||
F32 moveSpeed;
|
||||
if ((mState == MoveState || (mState == RecoverState && mDataBlock->recoverRunForceScale > 0.0f)) && mDamageState == Enabled)
|
||||
// If BLOCK_USER_CONTROL is set in anim_clip_flags, the user won't be able to
|
||||
// resume control over the player character. This generally happens for
|
||||
// short periods of time synchronized with script driven animation at places
|
||||
// where it makes sense that user motion is prohibited, such as when the
|
||||
// player is lifted off the ground or knocked down.
|
||||
if ((mState == MoveState || (mState == RecoverState && mDataBlock->recoverRunForceScale > 0.0f)) && mDamageState == Enabled && !isAnimationLocked())
|
||||
{
|
||||
zRot.getColumn(0,&moveVec);
|
||||
moveVec *= (move->x * (mPose == SprintPose ? mDataBlock->sprintStrafeScale : 1.0f));
|
||||
|
|
@ -3031,7 +3036,9 @@ void Player::updateMove(const Move* move)
|
|||
mContactTimer++;
|
||||
|
||||
// Acceleration from Jumping
|
||||
if (move->trigger[sJumpTrigger] && canJump())// !isMounted() &&
|
||||
// While BLOCK_USER_CONTROL is set in anim_clip_flags, the user won't be able to
|
||||
// make the player character jump.
|
||||
if (move->trigger[sJumpTrigger] && canJump() && !isAnimationLocked())
|
||||
{
|
||||
// Scale the jump impulse base on maxJumpSpeed
|
||||
F32 zSpeedScale = mVelocity.z;
|
||||
|
|
@ -3539,6 +3546,8 @@ void Player::updateLookAnimation(F32 dt)
|
|||
|
||||
bool Player::inDeathAnim()
|
||||
{
|
||||
if ((anim_clip_flags & ANIM_OVERRIDDEN) != 0 && (anim_clip_flags & IS_DEATH_ANIM) == 0)
|
||||
return false;
|
||||
if (mActionAnimation.thread && mActionAnimation.action >= 0)
|
||||
if (mActionAnimation.action < mDataBlock->actionCount)
|
||||
return mDataBlock->actionList[mActionAnimation.action].death;
|
||||
|
|
@ -3748,6 +3757,8 @@ bool Player::setArmThread(U32 action)
|
|||
|
||||
bool Player::setActionThread(const char* sequence,bool hold,bool wait,bool fsp)
|
||||
{
|
||||
if (anim_clip_flags & ANIM_OVERRIDDEN)
|
||||
return false;
|
||||
for (U32 i = 1; i < mDataBlock->actionCount; i++)
|
||||
{
|
||||
PlayerData::ActionAnimation &anim = mDataBlock->actionList[i];
|
||||
|
|
@ -3947,8 +3958,10 @@ void Player::updateActionThread()
|
|||
pickActionAnimation();
|
||||
}
|
||||
|
||||
// prevent scaling of AFX picked actions
|
||||
if ( (mActionAnimation.action != PlayerData::LandAnim) &&
|
||||
(mActionAnimation.action != PlayerData::NullAnimation) )
|
||||
(mActionAnimation.action != PlayerData::NullAnimation) &&
|
||||
!(anim_clip_flags & ANIM_OVERRIDDEN))
|
||||
{
|
||||
// Update action animation time scale to match ground velocity
|
||||
PlayerData::ActionAnimation &anim =
|
||||
|
|
@ -4566,6 +4579,10 @@ void Player::updateAnimation(F32 dt)
|
|||
if (mImageStateThread)
|
||||
mShapeInstance->advanceTime(dt,mImageStateThread);
|
||||
|
||||
// update any active blend clips
|
||||
if (isGhost())
|
||||
for (S32 i = 0; i < blend_clips.size(); i++)
|
||||
mShapeInstance->advanceTime(dt, blend_clips[i].thread);
|
||||
// If we are the client's player on this machine, then we need
|
||||
// to make sure the transforms are up to date as they are used
|
||||
// to setup the camera.
|
||||
|
|
@ -4579,6 +4596,11 @@ void Player::updateAnimation(F32 dt)
|
|||
else
|
||||
{
|
||||
updateAnimationTree(false);
|
||||
// This addition forces recently visible players to animate their
|
||||
// skeleton now rather than in pre-render so that constrained effects
|
||||
// get up-to-date node transforms.
|
||||
if (didRenderLastRender())
|
||||
mShapeInstance->animate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7249,6 +7271,165 @@ void Player::afx_unpackUpdate(NetConnection* con, BitStream* stream)
|
|||
mark_fx_c_triggers = mask;
|
||||
}
|
||||
}
|
||||
|
||||
// Code for overriding player's animation with sequences selected by the
|
||||
// anim-clip component effect.
|
||||
|
||||
void Player::restoreAnimation(U32 tag)
|
||||
{
|
||||
// check if this is a blended clip
|
||||
if ((tag & BLENDED_CLIP) != 0)
|
||||
{
|
||||
restoreBlendAnimation(tag);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tag != 0 && tag == last_anim_tag)
|
||||
{
|
||||
bool is_death_anim = ((anim_clip_flags & IS_DEATH_ANIM) != 0);
|
||||
|
||||
anim_clip_flags &= ~(ANIM_OVERRIDDEN | IS_DEATH_ANIM);
|
||||
|
||||
if (isClientObject())
|
||||
{
|
||||
if (mDamageState != Enabled)
|
||||
{
|
||||
if (!is_death_anim)
|
||||
{
|
||||
// this is a bit hardwired and desperate,
|
||||
// but if he's dead he needs to look like it.
|
||||
setActionThread("death10", false, false, false);
|
||||
}
|
||||
}
|
||||
else if (mState != MoveState)
|
||||
{
|
||||
// not sure what happens here
|
||||
}
|
||||
else
|
||||
{
|
||||
pickActionAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
last_anim_tag = 0;
|
||||
last_anim_id = -1;
|
||||
}
|
||||
}
|
||||
|
||||
U32 Player::getAnimationID(const char* name)
|
||||
{
|
||||
for (U32 i = 0; i < mDataBlock->actionCount; i++)
|
||||
{
|
||||
PlayerData::ActionAnimation &anim = mDataBlock->actionList[i];
|
||||
if (dStricmp(anim.name, name) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
Con::errorf("Player::getAnimationID() -- Player does not contain a sequence that matches the name, %s.", name);
|
||||
return BAD_ANIM_ID;
|
||||
}
|
||||
|
||||
U32 Player::playAnimationByID(U32 anim_id, F32 pos, F32 rate, F32 trans, bool hold, bool wait, bool is_death_anim)
|
||||
{
|
||||
if (anim_id == BAD_ANIM_ID)
|
||||
return 0;
|
||||
|
||||
S32 seq_id = mDataBlock->actionList[anim_id].sequence;
|
||||
if (seq_id == -1)
|
||||
{
|
||||
Con::errorf("Player::playAnimation() problem. BAD_SEQ_ID");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mShapeInstance->getShape()->sequences[seq_id].isBlend())
|
||||
return playBlendAnimation(seq_id, pos, rate);
|
||||
|
||||
if (isClientObject())
|
||||
{
|
||||
PlayerData::ActionAnimation &anim = mDataBlock->actionList[anim_id];
|
||||
if (anim.sequence != -1)
|
||||
{
|
||||
mActionAnimation.action = anim_id;
|
||||
mActionAnimation.forward = (rate >= 0);
|
||||
mActionAnimation.firstPerson = false;
|
||||
mActionAnimation.holdAtEnd = hold;
|
||||
mActionAnimation.waitForEnd = hold? true: wait;
|
||||
mActionAnimation.animateOnServer = false;
|
||||
mActionAnimation.atEnd = false;
|
||||
mActionAnimation.delayTicks = (S32)sNewAnimationTickTime;
|
||||
|
||||
F32 transTime = (trans < 0) ? sAnimationTransitionTime : trans;
|
||||
|
||||
mShapeInstance->setTimeScale(mActionAnimation.thread, rate);
|
||||
mShapeInstance->transitionToSequence(mActionAnimation.thread,anim.sequence,
|
||||
pos, transTime, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_death_anim)
|
||||
anim_clip_flags |= IS_DEATH_ANIM;
|
||||
else
|
||||
anim_clip_flags &= ~IS_DEATH_ANIM;
|
||||
|
||||
anim_clip_flags |= ANIM_OVERRIDDEN;
|
||||
last_anim_tag = unique_anim_tag_counter++;
|
||||
last_anim_id = anim_id;
|
||||
|
||||
return last_anim_tag;
|
||||
}
|
||||
|
||||
F32 Player::getAnimationDurationByID(U32 anim_id)
|
||||
{
|
||||
if (anim_id == BAD_ANIM_ID)
|
||||
return 0.0f;
|
||||
S32 seq_id = mDataBlock->actionList[anim_id].sequence;
|
||||
if (seq_id >= 0 && seq_id < mDataBlock->mShape->sequences.size())
|
||||
return mDataBlock->mShape->sequences[seq_id].duration;
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
bool Player::isBlendAnimation(const char* name)
|
||||
{
|
||||
U32 anim_id = getAnimationID(name);
|
||||
if (anim_id == BAD_ANIM_ID)
|
||||
return false;
|
||||
|
||||
S32 seq_id = mDataBlock->actionList[anim_id].sequence;
|
||||
if (seq_id >= 0 && seq_id < mDataBlock->mShape->sequences.size())
|
||||
return mDataBlock->mShape->sequences[seq_id].isBlend();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* Player::getLastClipName(U32 clip_tag)
|
||||
{
|
||||
if (clip_tag != last_anim_tag || last_anim_id >= PlayerData::NumActionAnims)
|
||||
return "";
|
||||
|
||||
return mDataBlock->actionList[last_anim_id].name;
|
||||
}
|
||||
|
||||
void Player::unlockAnimation(U32 tag, bool force)
|
||||
{
|
||||
if ((tag != 0 && tag == last_anim_lock_tag) || force)
|
||||
anim_clip_flags &= ~BLOCK_USER_CONTROL;
|
||||
}
|
||||
|
||||
U32 Player::lockAnimation()
|
||||
{
|
||||
anim_clip_flags |= BLOCK_USER_CONTROL;
|
||||
last_anim_lock_tag = unique_anim_tag_counter++;
|
||||
|
||||
return last_anim_lock_tag;
|
||||
}
|
||||
|
||||
ConsoleMethod(Player, isAnimationLocked, bool, 2, 2, "isAnimationLocked()")
|
||||
{
|
||||
return object->isAnimationLocked();
|
||||
}
|
||||
|
||||
|
||||
#ifdef TORQUE_OPENVR
|
||||
void Player::setControllers(Vector<OpenVRTrackedObject*> controllerList)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue