mirror of
https://github.com/overte-org/overte.git
synced 2025-04-15 22:07:34 +02:00
Merge pull request #14351 from luiscuenca/tweakTransitAnimations
Tweak transit animations
This commit is contained in:
commit
33da88f174
6 changed files with 219 additions and 148 deletions
BIN
interface/resources/avatar/animations/teleport.fbx
Normal file
BIN
interface/resources/avatar/animations/teleport.fbx
Normal file
Binary file not shown.
|
@ -1,70 +1,138 @@
|
|||
{
|
||||
"version": "1.1",
|
||||
"root": {
|
||||
"id": "userAnimStateMachine",
|
||||
"id": "networkAnimStateMachine",
|
||||
"type": "stateMachine",
|
||||
"data": {
|
||||
"currentState": "idleAnim",
|
||||
"currentState": "transitAnimStateMachine",
|
||||
"states": [
|
||||
{
|
||||
"id": "idleAnim",
|
||||
"id": "transitAnimStateMachine",
|
||||
"interpTarget": 6,
|
||||
"interpDuration": 6,
|
||||
"transitions": [
|
||||
{ "var": "postTransitAnim", "state": "postTransitAnim" },
|
||||
{ "var": "preTransitAnim", "state": "preTransitAnim" }
|
||||
{ "var": "userNetworkAnimA", "state": "userNetworkAnimA" },
|
||||
{ "var": "userNetworkAnimB", "state": "userNetworkAnimB" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "preTransitAnim",
|
||||
"id": "userNetworkAnimA",
|
||||
"interpTarget": 6,
|
||||
"interpDuration": 6,
|
||||
"transitions": [
|
||||
{ "var": "idleAnim", "state": "idleAnim" },
|
||||
{ "var": "transitAnim", "state": "transitAnim" }
|
||||
{ "var": "transitAnimStateMachine", "state": "transitAnimStateMachine" },
|
||||
{ "var": "userNetworkAnimB", "state": "userNetworkAnimB" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "transitAnim",
|
||||
"id": "userNetworkAnimB",
|
||||
"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" }
|
||||
{ "var": "transitAnimStateMachine", "state": "transitAnimStateMachine" },
|
||||
{ "var": "userNetworkAnimA", "state": "userNetworkAnimA" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"id": "idleAnim",
|
||||
"id": "transitAnimStateMachine",
|
||||
"type": "stateMachine",
|
||||
"data": {
|
||||
"currentState": "idleAnim",
|
||||
"states": [
|
||||
{
|
||||
"id": "idleAnim",
|
||||
"interpTarget": 6,
|
||||
"interpDuration": 6,
|
||||
"transitions": [
|
||||
{ "var": "postTransitAnim", "state": "postTransitAnim" },
|
||||
{ "var": "preTransitAnim", "state": "preTransitAnim" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "preTransitAnim",
|
||||
"interpTarget": 4,
|
||||
"interpDuration": 4,
|
||||
"transitions": [
|
||||
{ "var": "idleAnim", "state": "idleAnim" },
|
||||
{ "var": "transitAnim", "state": "transitAnim" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "transitAnim",
|
||||
"interpTarget": 2,
|
||||
"interpDuration": 2,
|
||||
"transitions": [
|
||||
{ "var": "preTransitAnim", "state": "preTransitAnim" },
|
||||
{ "var": "postTransitAnim", "state": "postTransitAnim" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "postTransitAnim",
|
||||
"interpTarget": 4,
|
||||
"interpDuration": 4,
|
||||
"transitions": [
|
||||
{ "var": "transitAnim", "state": "transitAnim" },
|
||||
{ "var": "idleAnim", "state": "idleAnim" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"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": "qrc:///avatar/animations/teleport.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 10.0,
|
||||
"timeScale": 1.0,
|
||||
"loopFlag": false
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"id": "transitAnim",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "qrc:///avatar/animations/teleport.fbx",
|
||||
"startFrame": 11.0,
|
||||
"endFrame": 18.0,
|
||||
"timeScale": 1.0,
|
||||
"loopFlag": false
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"id": "postTransitAnim",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "qrc:///avatar/animations/teleport.fbx",
|
||||
"startFrame": 19.0,
|
||||
"endFrame": 44.0,
|
||||
"timeScale": 1.0,
|
||||
"loopFlag": false
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "userNetworkAnimA",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "qrc:///avatar/animations/idle.fbx",
|
||||
|
@ -76,55 +144,7 @@
|
|||
"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",
|
||||
"id": "userNetworkAnimB",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "qrc:///avatar/animations/idle.fbx",
|
||||
|
|
|
@ -127,16 +127,16 @@ void AvatarManager::setSpace(workload::SpacePointer& space ) {
|
|||
void AvatarManager::handleTransitAnimations(AvatarTransit::Status status) {
|
||||
switch (status) {
|
||||
case AvatarTransit::Status::STARTED:
|
||||
_myAvatar->getSkeletonModel()->getRig().triggerNetworkAnimation("preTransitAnim");
|
||||
_myAvatar->getSkeletonModel()->getRig().triggerNetworkRole("preTransitAnim");
|
||||
break;
|
||||
case AvatarTransit::Status::START_TRANSIT:
|
||||
_myAvatar->getSkeletonModel()->getRig().triggerNetworkAnimation("transitAnim");
|
||||
_myAvatar->getSkeletonModel()->getRig().triggerNetworkRole("transitAnim");
|
||||
break;
|
||||
case AvatarTransit::Status::END_TRANSIT:
|
||||
_myAvatar->getSkeletonModel()->getRig().triggerNetworkAnimation("postTransitAnim");
|
||||
_myAvatar->getSkeletonModel()->getRig().triggerNetworkRole("postTransitAnim");
|
||||
break;
|
||||
case AvatarTransit::Status::ENDED:
|
||||
_myAvatar->getSkeletonModel()->getRig().triggerNetworkAnimation("idleAnim");
|
||||
_myAvatar->getSkeletonModel()->getRig().triggerNetworkRole("idleAnim");
|
||||
break;
|
||||
case AvatarTransit::Status::PRE_TRANSIT:
|
||||
break;
|
||||
|
|
|
@ -135,30 +135,6 @@ void Rig::overrideAnimation(const QString& url, float fps, bool loop, float firs
|
|||
_animVars.set("userAnimB", clipNodeEnum == UserAnimState::B);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Rig::restoreAnimation() {
|
||||
if (_userAnimState.clipNodeEnum != UserAnimState::None) {
|
||||
_userAnimState.clipNodeEnum = UserAnimState::None;
|
||||
|
@ -170,13 +146,87 @@ void Rig::restoreAnimation() {
|
|||
}
|
||||
}
|
||||
|
||||
void Rig::restoreNetworkAnimation() {
|
||||
if (_networkAnimState.clipNodeEnum != NetworkAnimState::Idle) {
|
||||
_networkAnimState.clipNodeEnum = NetworkAnimState::Idle;
|
||||
void Rig::overrideNetworkAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame) {
|
||||
|
||||
NetworkAnimState::ClipNodeEnum clipNodeEnum = NetworkAnimState::None;
|
||||
if (_networkAnimState.clipNodeEnum == NetworkAnimState::None || _networkAnimState.clipNodeEnum == NetworkAnimState::B) {
|
||||
clipNodeEnum = NetworkAnimState::A;
|
||||
} else if (_networkAnimState.clipNodeEnum == NetworkAnimState::A) {
|
||||
clipNodeEnum = NetworkAnimState::B;
|
||||
}
|
||||
|
||||
if (_networkNode) {
|
||||
// find an unused AnimClip clipNode
|
||||
std::shared_ptr<AnimClip> clip;
|
||||
if (clipNodeEnum == NetworkAnimState::A) {
|
||||
clip = std::dynamic_pointer_cast<AnimClip>(_networkNode->findByName("userNetworkAnimA"));
|
||||
} else {
|
||||
clip = std::dynamic_pointer_cast<AnimClip>(_networkNode->findByName("userNetworkAnimB"));
|
||||
}
|
||||
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("transitAnimStateMachine", false);
|
||||
_networkVars.set("userNetworkAnimA", clipNodeEnum == NetworkAnimState::A);
|
||||
_networkVars.set("userNetworkAnimB", clipNodeEnum == NetworkAnimState::B);
|
||||
if (!_computeNetworkAnimation) {
|
||||
_networkAnimState.blendTime = 0.0f;
|
||||
_computeNetworkAnimation = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Rig::triggerNetworkRole(const QString& role) {
|
||||
_networkVars.set("transitAnimStateMachine", false);
|
||||
_networkVars.set("idleAnim", false);
|
||||
_networkVars.set("userNetworkAnimA", false);
|
||||
_networkVars.set("userNetworkAnimB", false);
|
||||
_networkVars.set("preTransitAnim", false);
|
||||
_networkVars.set("preTransitAnim", false);
|
||||
_networkVars.set("transitAnim", false);
|
||||
_networkVars.set("postTransitAnim", false);
|
||||
_computeNetworkAnimation = true;
|
||||
if (role == "idleAnim") {
|
||||
_networkVars.set("idleAnim", true);
|
||||
_networkVars.set("preTransitAnim", false);
|
||||
_networkVars.set("transitAnim", false);
|
||||
_networkVars.set("postTransitAnim", false);
|
||||
_networkAnimState.clipNodeEnum = NetworkAnimState::None;
|
||||
_computeNetworkAnimation = false;
|
||||
_networkAnimState.blendTime = 0.0f;
|
||||
} else if (role == "preTransitAnim") {
|
||||
_networkVars.set("preTransitAnim", true);
|
||||
_networkAnimState.clipNodeEnum = NetworkAnimState::PreTransit;
|
||||
_networkAnimState.blendTime = 0.0f;
|
||||
} else if (role == "transitAnim") {
|
||||
_networkVars.set("transitAnim", true);
|
||||
_networkAnimState.clipNodeEnum = NetworkAnimState::Transit;
|
||||
} else if (role == "postTransitAnim") {
|
||||
_networkVars.set("postTransitAnim", true);
|
||||
_networkAnimState.clipNodeEnum = NetworkAnimState::PostTransit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Rig::restoreNetworkAnimation() {
|
||||
if (_networkAnimState.clipNodeEnum != NetworkAnimState::None) {
|
||||
if (_computeNetworkAnimation) {
|
||||
_networkAnimState.blendTime = 0.0f;
|
||||
_computeNetworkAnimation = false;
|
||||
}
|
||||
_networkAnimState.clipNodeEnum = NetworkAnimState::None;
|
||||
_networkVars.set("transitAnimStateMachine", true);
|
||||
_networkVars.set("userNetworkAnimA", false);
|
||||
_networkVars.set("userNetworkAnimB", false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1131,24 +1181,19 @@ void Rig::updateAnimations(float deltaTime, const glm::mat4& rootTransform, cons
|
|||
AnimVariantMap networkTriggersOut;
|
||||
_internalPoseSet._relativePoses = _animNode->evaluate(_animVars, context, deltaTime, triggersOut);
|
||||
if (_networkNode) {
|
||||
_networkPoseSet._relativePoses = _networkNode->evaluate(_networkVars, context, deltaTime, networkTriggersOut);
|
||||
const float NETWORK_ANIMATION_BLEND_FRAMES = 6.0f;
|
||||
// Manually blending networkPoseSet with internalPoseSet.
|
||||
float alpha = 1.0f;
|
||||
std::shared_ptr<AnimClip> clip;
|
||||
if (_networkAnimState.clipNodeEnum == NetworkAnimState::PreTransit) {
|
||||
clip = std::dynamic_pointer_cast<AnimClip>(_networkNode->findByName("preTransitAnim"));
|
||||
if (clip) {
|
||||
alpha = (clip->getFrame() - clip->getStartFrame()) / NETWORK_ANIMATION_BLEND_FRAMES;
|
||||
}
|
||||
} else if (_networkAnimState.clipNodeEnum == NetworkAnimState::PostTransit) {
|
||||
clip = std::dynamic_pointer_cast<AnimClip>(_networkNode->findByName("postTransitAnim"));
|
||||
if (clip) {
|
||||
alpha = (clip->getEndFrame() - clip->getFrame()) / NETWORK_ANIMATION_BLEND_FRAMES;
|
||||
}
|
||||
}
|
||||
const float FRAMES_PER_SECOND = 30.0f;
|
||||
const float TOTAL_BLEND_FRAMES = 6.0f;
|
||||
const float TOTAL_BLEND_TIME = TOTAL_BLEND_FRAMES / FRAMES_PER_SECOND;
|
||||
_sendNetworkNode = _computeNetworkAnimation || _networkAnimState.blendTime < TOTAL_BLEND_TIME;
|
||||
if (_sendNetworkNode) {
|
||||
_networkPoseSet._relativePoses = _networkNode->evaluate(_networkVars, context, deltaTime, networkTriggersOut);
|
||||
_networkAnimState.blendTime += deltaTime;
|
||||
alpha = _computeNetworkAnimation ? (_networkAnimState.blendTime / TOTAL_BLEND_TIME) : (1.0f - (_networkAnimState.blendTime / TOTAL_BLEND_TIME));
|
||||
alpha = glm::clamp(alpha, 0.0f, 1.0f);
|
||||
for (size_t i = 0; i < _networkPoseSet._relativePoses.size(); i++) {
|
||||
_networkPoseSet._relativePoses[i].blend(_internalPoseSet._relativePoses[i], (alpha > 1.0f ? 1.0f : alpha));
|
||||
_networkPoseSet._relativePoses[i].blend(_internalPoseSet._relativePoses[i], alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1840,16 +1885,16 @@ void Rig::initAnimGraph(const QUrl& url) {
|
|||
return;
|
||||
}
|
||||
_networkNode->setSkeleton(sharedSkeletonPtr);
|
||||
if (_networkAnimState.clipNodeEnum != NetworkAnimState::Idle) {
|
||||
if (_networkAnimState.clipNodeEnum != NetworkAnimState::None) {
|
||||
// restore the user animation we had before reset.
|
||||
NetworkAnimState origState = _networkAnimState;
|
||||
_networkAnimState = { NetworkAnimState::Idle, "", 30.0f, false, 0.0f, 0.0f };
|
||||
_networkAnimState = { NetworkAnimState::None, "", 30.0f, false, 0.0f, 0.0f };
|
||||
if (_networkAnimState.clipNodeEnum == NetworkAnimState::PreTransit) {
|
||||
triggerNetworkAnimation("preTransitAnim");
|
||||
triggerNetworkRole("preTransitAnim");
|
||||
} else if (_networkAnimState.clipNodeEnum == NetworkAnimState::Transit) {
|
||||
triggerNetworkAnimation("transitAnim");
|
||||
triggerNetworkRole("transitAnim");
|
||||
} else if (_networkAnimState.clipNodeEnum == NetworkAnimState::PostTransit) {
|
||||
triggerNetworkAnimation("postTransitAnim");
|
||||
triggerNetworkRole("postTransitAnim");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -114,8 +114,10 @@ public:
|
|||
void destroyAnimGraph();
|
||||
|
||||
void overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
|
||||
void triggerNetworkAnimation(const QString& animName);
|
||||
void restoreAnimation();
|
||||
|
||||
void overrideNetworkAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
|
||||
void triggerNetworkRole(const QString& role);
|
||||
void restoreNetworkAnimation();
|
||||
|
||||
QStringList getAnimationRoles() const;
|
||||
|
@ -327,12 +329,14 @@ protected:
|
|||
|
||||
struct NetworkAnimState {
|
||||
enum ClipNodeEnum {
|
||||
Idle = 0,
|
||||
None = 0,
|
||||
PreTransit,
|
||||
Transit,
|
||||
PostTransit
|
||||
PostTransit,
|
||||
A,
|
||||
B
|
||||
};
|
||||
NetworkAnimState() : clipNodeEnum(NetworkAnimState::Idle) {}
|
||||
NetworkAnimState() : clipNodeEnum(NetworkAnimState::None) {}
|
||||
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) {}
|
||||
|
||||
|
@ -342,6 +346,7 @@ protected:
|
|||
bool loop;
|
||||
float firstFrame;
|
||||
float lastFrame;
|
||||
float blendTime;
|
||||
};
|
||||
|
||||
struct UserAnimState {
|
||||
|
@ -411,6 +416,7 @@ protected:
|
|||
|
||||
int _rigId;
|
||||
bool _headEnabled { false };
|
||||
bool _computeNetworkAnimation { false };
|
||||
bool _sendNetworkNode { false };
|
||||
|
||||
AnimContext _lastContext;
|
||||
|
|
|
@ -341,10 +341,10 @@ const glm::vec3 START_LOCATION(6270, 211, 6000);
|
|||
// Avatar Transit Constants
|
||||
const float AVATAR_TRANSIT_MIN_TRIGGER_DISTANCE = 1.0f;
|
||||
const float AVATAR_TRANSIT_MAX_TRIGGER_DISTANCE = 30.0f;
|
||||
const int AVATAR_TRANSIT_FRAME_COUNT = 11;
|
||||
const int AVATAR_TRANSIT_FRAME_COUNT = 5;
|
||||
const float AVATAR_TRANSIT_FRAMES_PER_METER = 0.5f;
|
||||
const float AVATAR_TRANSIT_ABORT_DISTANCE = 0.1f;
|
||||
const bool AVATAR_TRANSIT_DISTANCE_BASED = true;
|
||||
const bool AVATAR_TRANSIT_DISTANCE_BASED = false;
|
||||
const float AVATAR_TRANSIT_FRAMES_PER_SECOND = 30.0f;
|
||||
const float AVATAR_PRE_TRANSIT_FRAME_COUNT = 10.0f;
|
||||
const float AVATAR_POST_TRANSIT_FRAME_COUNT = 27.0f;
|
||||
|
|
Loading…
Reference in a new issue