From bb5c042f16bc0dd86785861af429db54925a572d Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 18 Oct 2018 17:51:20 -0700 Subject: [PATCH] Blend network animation --- .../resources/avatar/network-animation.json | 140 ++++++++++++++++++ interface/src/avatar/AvatarManager.cpp | 37 +---- interface/src/avatar/MyAvatar.cpp | 17 --- interface/src/avatar/MyAvatar.h | 2 - libraries/animation/src/AnimClip.h | 2 + libraries/animation/src/Rig.cpp | 117 ++++++++------- libraries/animation/src/Rig.h | 23 ++- .../src/avatars-renderer/Avatar.cpp | 24 +-- .../src/avatars-renderer/Avatar.h | 21 --- .../controllers/controllerModules/teleport.js | 2 - 10 files changed, 241 insertions(+), 144 deletions(-) create mode 100644 interface/resources/avatar/network-animation.json diff --git a/interface/resources/avatar/network-animation.json b/interface/resources/avatar/network-animation.json new file mode 100644 index 0000000000..0ba4ea465c --- /dev/null +++ b/interface/resources/avatar/network-animation.json @@ -0,0 +1,140 @@ +{ + "version": "1.1", + "root": { + "id": "userAnimStateMachine", + "type": "stateMachine", + "data": { + "currentState": "idleAnim", + "states": [ + { + "id": "idleAnim", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { "var": "postTransitAnim", "state": "postTransitAnim" }, + { "var": "preTransitAnim", "state": "preTransitAnim" } + ] + }, + { + "id": "preTransitAnim", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { "var": "idleAnim", "state": "idleAnim" }, + { "var": "transitAnim", "state": "transitAnim" } + ] + }, + { + "id": "transitAnim", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { "var": "preTransitAnim", "state": "preTransitAnim" }, + { "var": "postTransitAnim", "state": "postTransitAnim" } + ] + }, + { + "id": "postTransitAnim", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { "var": "transitAnim", "state": "transitAnim" }, + { "var": "idleAnim", "state": "idleAnim" } + ] + }, + { + "id": "userAnimA", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { "var": "idleAnim", "state": "idleAnim" }, + { "var": "userAnimB", "state": "userAnimB" } + ] + }, + { + "id": "userAnimB", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { "var": "idleAnim", "state": "idleAnim" }, + { "var": "userAnimA", "state": "userAnimA" } + ] + } + ] + }, + "children": [ + { + "id": "idleAnim", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle.fbx", + "startFrame": 0.0, + "endFrame": 90.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "preTransitAnim", + "type": "clip", + "data": { + "url": "https://hifi-content.s3.amazonaws.com/luis/test_scripts/transitApp/animations/teleport01_warp.fbx", + "startFrame": 0.0, + "endFrame": 10.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "transitAnim", + "type": "clip", + "data": { + "url": "https://hifi-content.s3.amazonaws.com/luis/test_scripts/transitApp/animations/teleport01_warp.fbx", + "startFrame": 11.0, + "endFrame": 11.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "postTransitAnim", + "type": "clip", + "data": { + "url": "https://hifi-content.s3.amazonaws.com/luis/test_scripts/transitApp/animations/teleport01_warp.fbx", + "startFrame": 22.0, + "endFrame": 49.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "userAnimA", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle.fbx", + "startFrame": 0.0, + "endFrame": 90.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "userAnimB", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle.fbx", + "startFrame": 0.0, + "endFrame": 90.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + } +} diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index c3f6579e90..dd56c03d26 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -83,18 +83,10 @@ AvatarManager::AvatarManager(QObject* parent) : const int AVATAR_TRANSIT_FRAME_COUNT = 11; // Based on testing const float AVATAR_TRANSIT_FRAMES_PER_METER = 0.5f; // Based on testing - const QString START_ANIMATION_URL = "https://hifi-content.s3.amazonaws.com/luis/test_scripts/transitApp/animations/teleport01_warp.fbx"; - const QString MIDDLE_ANIMATION_URL = "https://hifi-content.s3.amazonaws.com/luis/test_scripts/transitApp/animations/teleport01_warp.fbx"; - const QString END_ANIMATION_URL = "https://hifi-content.s3.amazonaws.com/luis/test_scripts/transitApp/animations/teleport01_warp.fbx"; - _transitConfig._totalFrames = AVATAR_TRANSIT_FRAME_COUNT; _transitConfig._triggerDistance = AVATAR_TRANSIT_TRIGGER_DISTANCE; _transitConfig._framesPerMeter = AVATAR_TRANSIT_FRAMES_PER_METER; _transitConfig._isDistanceBased = true; - - _transitConfig._startTransitAnimation = AvatarTransit::TransitAnimation(START_ANIMATION_URL, 0, 10); - _transitConfig._middleTransitAnimation = AvatarTransit::TransitAnimation(MIDDLE_ANIMATION_URL, 15, 0); - _transitConfig._endTransitAnimation = AvatarTransit::TransitAnimation(END_ANIMATION_URL, 22, 27); } AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer& mixerWeakPointer) { @@ -143,30 +135,22 @@ void AvatarManager::setSpace(workload::SpacePointer& space ) { } void AvatarManager::handleTransitAnimations(AvatarTransit::Status status) { - auto startAnimation = _transitConfig._startTransitAnimation; - auto middleAnimation = _transitConfig._middleTransitAnimation; - auto endAnimation = _transitConfig._endTransitAnimation; - - const float REFERENCE_FPS = 30.0f; switch (status) { case AvatarTransit::Status::STARTED: qDebug() << "START_FRAME"; - _myAvatar->overrideNetworkAnimation(startAnimation._animationUrl, REFERENCE_FPS, false, startAnimation._firstFrame, - startAnimation._firstFrame + startAnimation._frameCount); + _myAvatar->getSkeletonModel()->getRig().triggerNetworkAnimation("preTransitAnim"); break; case AvatarTransit::Status::START_TRANSIT: qDebug() << "START_TRANSIT"; - _myAvatar->overrideNetworkAnimation(middleAnimation._animationUrl, REFERENCE_FPS, false, middleAnimation._firstFrame, - middleAnimation._firstFrame + middleAnimation._frameCount); + _myAvatar->getSkeletonModel()->getRig().triggerNetworkAnimation("transitAnim"); break; case AvatarTransit::Status::END_TRANSIT: qDebug() << "END_TRANSIT"; - _myAvatar->overrideNetworkAnimation(endAnimation._animationUrl, REFERENCE_FPS, false, endAnimation._firstFrame, - endAnimation._firstFrame + endAnimation._frameCount); + _myAvatar->getSkeletonModel()->getRig().triggerNetworkAnimation("postTransitAnim"); break; case AvatarTransit::Status::ENDED: qDebug() << "END_FRAME"; - _myAvatar->restoreNetworkAnimation(); + _myAvatar->getSkeletonModel()->getRig().triggerNetworkAnimation("idleAnim"); break; case AvatarTransit::Status::PRE_TRANSIT: break; @@ -188,9 +172,6 @@ void AvatarManager::updateMyAvatar(float deltaTime) { AvatarTransit::Status status = _myAvatar->updateTransit(deltaTime, _myAvatar->getNextPosition(), _transitConfig); handleTransitAnimations(status); - bool sendFirstTransitPacket = (status == AvatarTransit::Status::STARTED); - bool sendCurrentTransitPacket = (status != AvatarTransit::Status::IDLE && (status != AvatarTransit::Status::POST_TRANSIT || status != AvatarTransit::Status::ENDED)); - _myAvatar->update(deltaTime); render::Transaction transaction; _myAvatar->updateRenderItem(transaction); @@ -199,19 +180,13 @@ void AvatarManager::updateMyAvatar(float deltaTime) { quint64 now = usecTimestampNow(); quint64 dt = now - _lastSendAvatarDataTime; - if (sendFirstTransitPacket || (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS && !_myAvatarDataPacketsPaused)) { + if (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS && !_myAvatarDataPacketsPaused) { // send head/hand data to the avatar mixer and voxel server - PerformanceTimer perfTimer("send"); - if (sendFirstTransitPacket) { - _myAvatar->overrideNextPacketPositionData(_myAvatar->getTransit()->getEndPosition()); - } else if (sendCurrentTransitPacket) { - _myAvatar->overrideNextPacketPositionData(_myAvatar->getTransit()->getCurrentPosition()); - } + PerformanceTimer perfTimer("send"); _myAvatar->sendAvatarDataPacket(); _lastSendAvatarDataTime = now; _myAvatarSendRate.increment(); } - } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 152215e717..b347963cf1 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1124,15 +1124,6 @@ void MyAvatar::overrideAnimation(const QString& url, float fps, bool loop, float _skeletonModel->getRig().overrideAnimation(url, fps, loop, firstFrame, lastFrame); } -void MyAvatar::overrideNetworkAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame) { - if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "overrideNetworkAnimation", Q_ARG(const QString&, url), Q_ARG(float, fps), - Q_ARG(bool, loop), Q_ARG(float, firstFrame), Q_ARG(float, lastFrame)); - return; - } - _skeletonModel->getRig().overrideNetworkAnimation(url, fps, loop, firstFrame, lastFrame); -} - void MyAvatar::restoreAnimation() { if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "restoreAnimation"); @@ -1141,14 +1132,6 @@ void MyAvatar::restoreAnimation() { _skeletonModel->getRig().restoreAnimation(); } -void MyAvatar::restoreNetworkAnimation() { - if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "restoreNetworkAnimation"); - return; - } - _skeletonModel->getRig().restoreNetworkAnimation(); -} - QStringList MyAvatar::getAnimationRoles() { if (QThread::currentThread() != thread()) { QStringList result; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 9770a5bb1a..16b765711a 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -376,7 +376,6 @@ public: * }, 3000); */ Q_INVOKABLE void overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame); - Q_INVOKABLE void overrideNetworkAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame); /**jsdoc * The avatar animation system includes a set of default animations along with rules for how those animations are blended together with @@ -393,7 +392,6 @@ public: * }, 3000); */ Q_INVOKABLE void restoreAnimation(); - Q_INVOKABLE void restoreNetworkAnimation(); /**jsdoc * Each avatar has an avatar-animation.json file that defines which animations are used and how they are blended together with procedural data diff --git a/libraries/animation/src/AnimClip.h b/libraries/animation/src/AnimClip.h index eba361fd4c..92f4c01dcc 100644 --- a/libraries/animation/src/AnimClip.h +++ b/libraries/animation/src/AnimClip.h @@ -51,6 +51,8 @@ public: bool getMirrorFlag() const { return _mirrorFlag; } void setMirrorFlag(bool mirrorFlag) { _mirrorFlag = mirrorFlag; } + float getFrame() const { return _frame; } + void loadURL(const QString& url); protected: diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index b9e654964a..df7e322da7 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -31,6 +31,7 @@ #include "AnimSkeleton.h" #include "AnimUtil.h" #include "IKTarget.h" +#include "PathUtils.h" static int nextRigId = 1; @@ -133,41 +134,28 @@ void Rig::overrideAnimation(const QString& url, float fps, bool loop, float firs _animVars.set("userAnimB", clipNodeEnum == UserAnimState::B); } -void Rig::overrideNetworkAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame) { - UserAnimState::ClipNodeEnum clipNodeEnum; - if (_networkAnimState.clipNodeEnum == UserAnimState::None || _networkAnimState.clipNodeEnum == UserAnimState::B) { - clipNodeEnum = UserAnimState::A; +void Rig::triggerNetworkAnimation(const QString& animName) { + _networkVars.set("idleAnim", false); + _networkVars.set("preTransitAnim", false); + _networkVars.set("transitAnim", false); + _networkVars.set("postTransitAnim", false); + _sendNetworkNode = true; + + if (animName == "idleAnim") { + _networkVars.set("idleAnim", true); + _networkAnimState.clipNodeEnum = NetworkAnimState::Idle; + _sendNetworkNode = false; + } else if (animName == "preTransitAnim") { + _networkVars.set("preTransitAnim", true); + _networkAnimState.clipNodeEnum = NetworkAnimState::PreTransit; + } else if (animName == "transitAnim") { + _networkVars.set("transitAnim", true); + _networkAnimState.clipNodeEnum = NetworkAnimState::Transit; + } else if (animName == "postTransitAnim") { + _networkVars.set("postTransitAnim", true); + _networkAnimState.clipNodeEnum = NetworkAnimState::PostTransit; } - else { - clipNodeEnum = UserAnimState::B; - } - if (_networkNode) { - // find an unused AnimClip clipNode - _sendNetworkNode = true; - std::shared_ptr clip; - if (clipNodeEnum == UserAnimState::A) { - clip = std::dynamic_pointer_cast(_networkNode->findByName("userAnimA")); - } - else { - clip = std::dynamic_pointer_cast(_networkNode->findByName("userAnimB")); - } - if (clip) { - // set parameters - clip->setLoopFlag(loop); - clip->setStartFrame(firstFrame); - clip->setEndFrame(lastFrame); - const float REFERENCE_FRAMES_PER_SECOND = 30.0f; - float timeScale = fps / REFERENCE_FRAMES_PER_SECOND; - clip->setTimeScale(timeScale); - clip->loadURL(url); - } - } - // store current user anim state. - _networkAnimState = { clipNodeEnum, url, fps, loop, firstFrame, lastFrame }; - // notify the userAnimStateMachine the desired state. - _networkVars.set("userAnimNone", false); - _networkVars.set("userAnimA", clipNodeEnum == UserAnimState::A); - _networkVars.set("userAnimB", clipNodeEnum == UserAnimState::B); + } void Rig::restoreAnimation() { @@ -182,13 +170,12 @@ void Rig::restoreAnimation() { } void Rig::restoreNetworkAnimation() { - _sendNetworkNode = false; - if (_networkAnimState.clipNodeEnum != UserAnimState::None) { - _networkAnimState.clipNodeEnum = UserAnimState::None; - // notify the userAnimStateMachine the desired state. - _networkVars.set("userAnimNone", true); - _networkVars.set("userAnimA", false); - _networkVars.set("userAnimB", false); + if (_networkAnimState.clipNodeEnum != NetworkAnimState::Idle) { + _networkAnimState.clipNodeEnum = NetworkAnimState::Idle; + _networkVars.set("idleAnim", true); + _networkVars.set("preTransitAnim", false); + _networkVars.set("transitAnim", false); + _networkVars.set("postTransitAnim", false); } } @@ -1137,6 +1124,24 @@ void Rig::updateAnimations(float deltaTime, const glm::mat4& rootTransform, cons _internalPoseSet._relativePoses = _animNode->evaluate(_animVars, context, deltaTime, triggersOut); if (_networkNode) { _networkPoseSet._relativePoses = _networkNode->evaluate(_networkVars, context, deltaTime, networkTriggersOut); + float alpha = 1.0f; + std::shared_ptr clip; + if (_networkAnimState.clipNodeEnum == NetworkAnimState::PreTransit) { + clip = std::dynamic_pointer_cast(_networkNode->findByName("preTransitAnim")); + if (clip) { + alpha = (clip->getFrame() - clip->getStartFrame()) / 6.0f; + } + } else if (_networkAnimState.clipNodeEnum == NetworkAnimState::PostTransit) { + clip = std::dynamic_pointer_cast(_networkNode->findByName("postTransitAnim")); + if (clip) { + alpha = (clip->getEndFrame() - clip->getFrame()) / 6.0f; + } + } + if (_sendNetworkNode) { + for (int i = 0; i < _networkPoseSet._relativePoses.size(); i++) { + _networkPoseSet._relativePoses[i].blend(_internalPoseSet._relativePoses[i], (alpha > 1.0f ? 1.0f : alpha)); + } + } } if ((int)_internalPoseSet._relativePoses.size() != _animSkeleton->getNumJoints()) { // animations haven't fully loaded yet. @@ -1798,10 +1803,10 @@ void Rig::initAnimGraph(const QUrl& url) { // load the anim graph _animLoader.reset(new AnimNodeLoader(url)); - _networkLoader.reset(new AnimNodeLoader(url)); - + auto networkUrl = PathUtils::resourcesUrl("avatar/network-animation.json"); + _networkLoader.reset(new AnimNodeLoader(networkUrl)); std::weak_ptr weakSkeletonPtr = _animSkeleton; - connect(_animLoader.get(), &AnimNodeLoader::success, [this, weakSkeletonPtr](AnimNode::Pointer nodeIn) { + connect(_animLoader.get(), &AnimNodeLoader::success, [this, weakSkeletonPtr, url](AnimNode::Pointer nodeIn) { _animNode = nodeIn; // abort load if the previous skeleton was deleted. @@ -1828,10 +1833,10 @@ void Rig::initAnimGraph(const QUrl& url) { emit onLoadComplete(); }); connect(_animLoader.get(), &AnimNodeLoader::error, [url](int error, QString str) { - qCCritical(animation) << "Error loading" << url.toDisplayString() << "code = " << error << "str =" << str; + qCritical(animation) << "Error loading" << url.toDisplayString() << "code = " << error << "str =" << str; }); - connect(_networkLoader.get(), &AnimNodeLoader::success, [this, weakSkeletonPtr](AnimNode::Pointer nodeIn) { + connect(_networkLoader.get(), &AnimNodeLoader::success, [this, weakSkeletonPtr, networkUrl](AnimNode::Pointer nodeIn) { _networkNode = nodeIn; // abort load if the previous skeleton was deleted. auto sharedSkeletonPtr = weakSkeletonPtr.lock(); @@ -1839,16 +1844,22 @@ void Rig::initAnimGraph(const QUrl& url) { return; } _networkNode->setSkeleton(sharedSkeletonPtr); - if (_networkAnimState.clipNodeEnum != UserAnimState::None) { + if (_networkAnimState.clipNodeEnum != NetworkAnimState::Idle) { // restore the user animation we had before reset. - UserAnimState origState = _networkAnimState; - _networkAnimState = { UserAnimState::None, "", 30.0f, false, 0.0f, 0.0f }; - overrideNetworkAnimation(origState.url, origState.fps, origState.loop, origState.firstFrame, origState.lastFrame); + NetworkAnimState origState = _networkAnimState; + _networkAnimState = { NetworkAnimState::Idle, "", 30.0f, false, 0.0f, 0.0f }; + if (_networkAnimState.clipNodeEnum == NetworkAnimState::PreTransit) { + triggerNetworkAnimation("preTransitAnim"); + } else if (_networkAnimState.clipNodeEnum == NetworkAnimState::Transit) { + triggerNetworkAnimation("transitAnim"); + } else if (_networkAnimState.clipNodeEnum == NetworkAnimState::PostTransit) { + triggerNetworkAnimation("postTransitAnim"); + } } - // emit onLoadComplete(); + }); - connect(_networkLoader.get(), &AnimNodeLoader::error, [url](int error, QString str) { - qCCritical(animation) << "Error loading" << url.toDisplayString() << "code = " << error << "str =" << str; + connect(_networkLoader.get(), &AnimNodeLoader::error, [networkUrl](int error, QString str) { + qCritical(animation) << "Error loading" << networkUrl.toDisplayString() << "code = " << error << "str =" << str; }); } } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 37d1ec1dd3..af786a5e70 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -113,7 +113,7 @@ public: void destroyAnimGraph(); void overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame); - void overrideNetworkAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame); + void triggerNetworkAnimation(const QString& animName); void restoreAnimation(); void restoreNetworkAnimation(); @@ -323,6 +323,25 @@ protected: RigRole _state { RigRole::Idle }; RigRole _desiredState { RigRole::Idle }; float _desiredStateAge { 0.0f }; + + struct NetworkAnimState { + enum ClipNodeEnum { + Idle = 0, + PreTransit, + Transit, + PostTransit + }; + NetworkAnimState() : clipNodeEnum(NetworkAnimState::Idle) {} + NetworkAnimState(ClipNodeEnum clipNodeEnumIn, const QString& urlIn, float fpsIn, bool loopIn, float firstFrameIn, float lastFrameIn) : + clipNodeEnum(clipNodeEnumIn), url(urlIn), fps(fpsIn), loop(loopIn), firstFrame(firstFrameIn), lastFrame(lastFrameIn) {} + + ClipNodeEnum clipNodeEnum; + QString url; + float fps; + bool loop; + float firstFrame; + float lastFrame; + }; struct UserAnimState { enum ClipNodeEnum { @@ -357,7 +376,7 @@ protected: }; UserAnimState _userAnimState; - UserAnimState _networkAnimState; + NetworkAnimState _networkAnimState; std::map _roleAnimStates; float _leftHandOverlayAlpha { 0.0f }; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index b43e1c23f6..705ebc0b13 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -114,12 +114,10 @@ void Avatar::setShowNamesAboveHeads(bool show) { } AvatarTransit::Status AvatarTransit::update(float deltaTime, const glm::vec3& avatarPosition, const AvatarTransit::TransitConfig& config) { - bool checkDistance = (!_isActive || (_status == Status::POST_TRANSIT || _status == Status::ENDED)); float oneFrameDistance = _isActive ? glm::length(avatarPosition - _endPosition) : glm::length(avatarPosition - _lastPosition); - const float TRANSIT_TRIGGER_MAX_DISTANCE = 30.0f; float scaledMaxTransitDistance = TRANSIT_TRIGGER_MAX_DISTANCE * _scale; - if (oneFrameDistance > config._triggerDistance && checkDistance) { + if (oneFrameDistance > config._triggerDistance) { if (oneFrameDistance < scaledMaxTransitDistance) { start(deltaTime, _lastPosition, avatarPosition, config); } else { @@ -132,12 +130,9 @@ AvatarTransit::Status AvatarTransit::update(float deltaTime, const glm::vec3& av const float SETTLE_ABORT_DISTANCE = 0.1f; float scaledSettleAbortDistance = SETTLE_ABORT_DISTANCE * _scale; - bool abortPostTransit = (_status == Status::POST_TRANSIT && _purpose == Purpose::SIT) || - (_isActive && oneFrameDistance > scaledSettleAbortDistance && _status == Status::POST_TRANSIT); - if (abortPostTransit) { + if (_isActive && oneFrameDistance > scaledSettleAbortDistance && _status == Status::POST_TRANSIT) { reset(); _status = Status::ENDED; - _purpose = Purpose::UNDEFINED; } return _status; } @@ -154,10 +149,13 @@ void AvatarTransit::start(float deltaTime, const glm::vec3& startPosition, const _transitLine = endPosition - startPosition; _totalDistance = glm::length(_transitLine); _easeType = config._easeType; - const float REFERENCE_FRAMES_PER_SECOND = 30.0f; - _preTransitTime = (float)config._startTransitAnimation._frameCount / REFERENCE_FRAMES_PER_SECOND; - _postTransitTime = (float)config._endTransitAnimation._frameCount / REFERENCE_FRAMES_PER_SECOND; + const float REFERENCE_FRAMES_PER_SECOND = 30.0f; + const float PRE_TRANSIT_FRAME_COUNT = 10.0f; + const float POST_TRANSIT_FRAME_COUNT = 27.0f; + + _preTransitTime = PRE_TRANSIT_FRAME_COUNT / REFERENCE_FRAMES_PER_SECOND; + _postTransitTime = POST_TRANSIT_FRAME_COUNT / REFERENCE_FRAMES_PER_SECOND; int transitFrames = (!config._isDistanceBased) ? config._totalFrames : config._framesPerMeter * _totalDistance; _transitTime = (float)transitFrames / REFERENCE_FRAMES_PER_SECOND; _totalTime = _transitTime + _preTransitTime + _postTransitTime; @@ -206,7 +204,6 @@ AvatarTransit::Status AvatarTransit::updatePosition(float deltaTime) { _currentPosition = _endPosition; if (nextTime >= _totalTime) { _isActive = false; - _purpose = Purpose::UNDEFINED; status = Status::ENDED; } else if (_currentTime < _totalTime - _postTransitTime) { status = Status::END_TRANSIT; @@ -2007,11 +2004,6 @@ void Avatar::setTransitScale(float scale) { _transit.setScale(scale); } -void Avatar::setTransitPurpose(int purpose) { - std::lock_guard lock(_transitLock); - _transit.setPurpose(static_cast(purpose)); -} - void Avatar::overrideNextPacketPositionData(const glm::vec3& position) { std::lock_guard lock(_transitLock); _overrideGlobalPosition = true; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index d375909609..2995c0f7b4 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -71,21 +71,6 @@ public: EASE_IN_OUT }; - enum Purpose { - UNDEFINED = 0, - TELEPORT, - SIT - }; - - struct TransitAnimation { - TransitAnimation(){}; - TransitAnimation(const QString& animationUrl, int firstFrame, int frameCount) : - _firstFrame(firstFrame), _frameCount(frameCount), _animationUrl(animationUrl){}; - int _firstFrame; - int _frameCount; - QString _animationUrl; - }; - struct TransitConfig { TransitConfig() {}; int _totalFrames { 0 }; @@ -93,9 +78,6 @@ public: bool _isDistanceBased { false }; float _triggerDistance { 0 }; EaseType _easeType { EaseType::EASE_OUT }; - TransitAnimation _startTransitAnimation; - TransitAnimation _middleTransitAnimation; - TransitAnimation _endTransitAnimation; }; AvatarTransit() {}; @@ -105,7 +87,6 @@ public: glm::vec3 getCurrentPosition() { return _currentPosition; } glm::vec3 getEndPosition() { return _endPosition; } void setScale(float scale) { _scale = scale; } - void setPurpose(const Purpose& purpose) { _purpose = purpose; } void reset(); private: @@ -130,7 +111,6 @@ private: EaseType _easeType { EaseType::EASE_OUT }; Status _status { Status::IDLE }; float _scale { 1.0f }; - Purpose _purpose { Purpose::UNDEFINED }; }; class Avatar : public AvatarData, public scriptable::ModelProvider { @@ -457,7 +437,6 @@ public: AvatarTransit::Status updateTransit(float deltaTime, const glm::vec3& avatarPosition, const AvatarTransit::TransitConfig& config); void setTransitScale(float scale); - Q_INVOKABLE void setTransitPurpose(int purpose); void overrideNextPacketPositionData(const glm::vec3& position); diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index d31f207b19..bf5022cdaf 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -781,13 +781,11 @@ Script.include("/~/system/libraries/controllers.js"); if (target === TARGET.NONE || target === TARGET.INVALID) { // Do nothing } else if (target === TARGET.SEAT) { - MyAvatar.setTransitPurpose(2); Entities.callEntityMethod(result.objectID, 'sit'); } else if (target === TARGET.SURFACE || target === TARGET.DISCREPANCY) { var offset = getAvatarFootOffset(); result.intersection.y += offset; var shouldLandSafe = target === TARGET.DISCREPANCY; - MyAvatar.setTransitPurpose(1); MyAvatar.goToLocation(result.intersection, true, HMD.orientation, false, shouldLandSafe); HMD.centerUI(); MyAvatar.centerBody();