From c892d8a81a21d609bea31f2533b9120cb243fd57 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Fri, 3 Mar 2017 10:41:47 -0800 Subject: [PATCH 1/5] Update Oculus SDK to 1.11 --- cmake/externals/LibOVR/CMakeLists.txt | 26 ++++++--------------- cmake/externals/LibOVR/LibOVRCMakeLists.txt | 15 ++++++++++++ 2 files changed, 22 insertions(+), 19 deletions(-) create mode 100644 cmake/externals/LibOVR/LibOVRCMakeLists.txt diff --git a/cmake/externals/LibOVR/CMakeLists.txt b/cmake/externals/LibOVR/CMakeLists.txt index 54a4a47929..d8b8307082 100644 --- a/cmake/externals/LibOVR/CMakeLists.txt +++ b/cmake/externals/LibOVR/CMakeLists.txt @@ -12,35 +12,23 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) # 0.5 public # URL http://static.oculus.com/sdk-downloads/ovr_sdk_win_0.5.0.1.zip # URL_MD5 d3fc4c02db9be5ff08af4ef4c97b32f9 -# 1.3 public -# URL http://hifi-public.s3.amazonaws.com/dependencies/ovr_sdk_win_1.3.0_public.zip -# URL_MD5 4d26faba0c1f35ff80bf674c96ed9259 if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://hifi-public.s3.amazonaws.com/dependencies/ovr_sdk_win_1.8.0_public.zip - URL_MD5 bea17e04acc1dd8cf7cabefa1b28cc3c - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" + URL https://static.oculus.com/sdk-downloads/1.11.0/Public/1486063832/ovr_sdk_win_1.11.0_public.zip + URL_MD5 ea484403757cbfdfa743b6577fb1f9d2 + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= + PATCH_COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/LibOVRCMakeLists.txt" /CMakeLists.txt LOG_DOWNLOAD 1 ) ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) - message("LIBOVR dir ${SOURCE_DIR}") - set(LIBOVR_DIR ${SOURCE_DIR}/LibOVR) - if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - set(LIBOVR_LIB_DIR ${LIBOVR_DIR}/Lib/Windows/x64/Release/VS2013 CACHE TYPE INTERNAL) - else() - set(LIBOVR_LIB_DIR ${LIBOVR_DIR}/Lib/Windows/Win32/Release/VS2013 CACHE TYPE INTERNAL) - endif() - + ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) + set(LIBOVR_DIR ${INSTALL_DIR}) set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${LIBOVR_DIR}/Include CACHE TYPE INTERNAL) - message("LIBOVR include dir ${${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS}") - set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${LIBOVR_LIB_DIR}/LibOVR.lib CACHE TYPE INTERNAL) - + set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${LIBOVR_DIR}/Lib/LibOVR.lib CACHE TYPE INTERNAL) elseif(APPLE) ExternalProject_Add( diff --git a/cmake/externals/LibOVR/LibOVRCMakeLists.txt b/cmake/externals/LibOVR/LibOVRCMakeLists.txt new file mode 100644 index 0000000000..bab6337ae2 --- /dev/null +++ b/cmake/externals/LibOVR/LibOVRCMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.2) +project(LibOVR) + +#set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DOVR_BUILD_DEBUG") + +include_directories(LibOVR/Include LibOVR/Src) +#include_directories(LibOVRKernel/Src/) +file(GLOB HEADER_FILES LibOVR/Include/*.h) +file(GLOB EXTRA_HEADER_FILES LibOVR/Include/Extras/*.h) +file(GLOB_RECURSE SOURCE_FILES LibOVR/Src/*.c LibOVR/Src/*.cpp) +add_library(LibOVR STATIC ${SOURCE_FILES} ${HEADER_FILES} ${EXTRA_HEADER_FILES}) + +install(TARGETS LibOVR DESTINATION Lib) +install(FILES ${HEADER_FILES} DESTINATION Include) +install(FILES ${EXTRA_HEADER_FILES} DESTINATION Include/Extras) \ No newline at end of file From ce9d637b3f65194bb8b0c3140fe5ee84cde12bec Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Fri, 3 Mar 2017 10:46:05 -0800 Subject: [PATCH 2/5] Expose ASW activation status, provide normalized present rate information --- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 5 +++++ .../src/display-plugins/OpenGLDisplayPlugin.h | 2 ++ libraries/plugins/src/plugins/DisplayPlugin.h | 7 ++++++- plugins/oculus/src/OculusDisplayPlugin.cpp | 17 +++++++++++++++-- plugins/oculus/src/OculusDisplayPlugin.h | 4 +++- plugins/oculus/src/OculusHelpers.cpp | 6 +++++- 6 files changed, 36 insertions(+), 5 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index cf6b39812a..b23b59d3f0 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -654,6 +654,11 @@ float OpenGLDisplayPlugin::presentRate() const { return _presentRate.rate(); } +void OpenGLDisplayPlugin::resetPresentRate() { + // FIXME + // _presentRate = RateCounter<100>(); +} + float OpenGLDisplayPlugin::renderRate() const { return _renderRate.rate(); } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index f4efc0267b..e1eea5de6c 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -59,6 +59,8 @@ public: float presentRate() const override; + void resetPresentRate() override; + float newFramePresentRate() const override; float droppedFrameRate() const override; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 2491aed817..754c919fd4 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -139,7 +139,7 @@ public: /// By default, all HMDs are stereo virtual bool isStereo() const { return isHmd(); } virtual bool isThrottled() const { return false; } - virtual float getTargetFrameRate() const { return 0.0f; } + virtual float getTargetFrameRate() const { return 1.0f; } virtual bool hasAsyncReprojection() const { return false; } /// Returns a boolean value indicating whether the display is currently visible @@ -189,6 +189,11 @@ public: virtual float renderRate() const { return -1.0f; } // Rate at which we present to the display device virtual float presentRate() const { return -1.0f; } + // Reset the present rate tracking (useful for if the target frame rate changes as in ASW for Oculus) + virtual void resetPresentRate() {} + // Return the present rate as fraction of the target present rate (hopefully 0.0 and 1.0) + virtual float normalizedPresentRate() const { return presentRate() / getTargetFrameRate(); } + // Rate at which old frames are presented to the device display virtual float stutterRate() const { return -1.0f; } // Rate at which new frames are being presented to the display device diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp index b076170ae5..db8c92ac23 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -28,6 +28,12 @@ OculusDisplayPlugin::OculusDisplayPlugin() { _compositorDroppedFrames.store(0); } +float OculusDisplayPlugin::getTargetFrameRate() const { + if (_aswActive) { + return _hmdDesc.DisplayRefreshRate / 2.0f; + } + return _hmdDesc.DisplayRefreshRate; +} bool OculusDisplayPlugin::internalActivate() { bool result = Parent::internalActivate(); @@ -185,8 +191,6 @@ void OculusDisplayPlugin::hmdPresent() { } } - - if (!OVR_SUCCESS(result)) { logWarning("Failed to present"); } @@ -195,12 +199,20 @@ void OculusDisplayPlugin::hmdPresent() { static int appDroppedFrames = 0; ovrPerfStats perfStats; ovr_GetPerfStats(_session, &perfStats); + bool shouldResetPresentRate = false; for (int i = 0; i < perfStats.FrameStatsCount; ++i) { const auto& frameStats = perfStats.FrameStats[i]; int delta = frameStats.CompositorDroppedFrameCount - compositorDroppedFrames; _stutterRate.increment(delta); compositorDroppedFrames = frameStats.CompositorDroppedFrameCount; appDroppedFrames = frameStats.AppDroppedFrameCount; + bool newAswState = ovrTrue == frameStats.AswIsActive; + if (_aswActive.exchange(newAswState) != newAswState) { + shouldResetPresentRate = true; + } + } + if (shouldResetPresentRate) { + resetPresentRate(); } _appDroppedFrames.store(appDroppedFrames); _compositorDroppedFrames.store(compositorDroppedFrames); @@ -212,6 +224,7 @@ void OculusDisplayPlugin::hmdPresent() { QJsonObject OculusDisplayPlugin::getHardwareStats() const { QJsonObject hardwareStats; + hardwareStats["asw_active"] = _aswActive.load(); hardwareStats["app_dropped_frame_count"] = _appDroppedFrames.load(); hardwareStats["compositor_dropped_frame_count"] = _compositorDroppedFrames.load(); hardwareStats["long_render_count"] = _longRenders.load(); diff --git a/plugins/oculus/src/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h index 6fc50b829f..9209fd373e 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.h +++ b/plugins/oculus/src/OculusDisplayPlugin.h @@ -20,7 +20,8 @@ public: QString getPreferredAudioInDevice() const override; QString getPreferredAudioOutDevice() const override; - + float getTargetFrameRate() const override; + virtual QJsonObject getHardwareStats() const; protected: @@ -39,6 +40,7 @@ private: gpu::FramebufferPointer _outputFramebuffer; bool _customized { false }; + std::atomic_bool _aswActive; std::atomic_int _compositorDroppedFrames; std::atomic_int _appDroppedFrames; std::atomic_int _longSubmits; diff --git a/plugins/oculus/src/OculusHelpers.cpp b/plugins/oculus/src/OculusHelpers.cpp index 340b804404..767d191c03 100644 --- a/plugins/oculus/src/OculusHelpers.cpp +++ b/plugins/oculus/src/OculusHelpers.cpp @@ -88,7 +88,11 @@ ovrSession acquireOculusSession() { } if (!session) { - if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { + ovrInitParams initParams { + ovrInit_RequestVersion | ovrInit_MixedRendering, OVR_MINOR_VERSION, nullptr, 0, 0 + }; + + if (!OVR_SUCCESS(ovr_Initialize(&initParams))) { logWarning("Failed to initialize Oculus SDK"); return session; } From d85cb645b0301338f5cedad9b547772d8e4b6890 Mon Sep 17 00:00:00 2001 From: Menithal Date: Sat, 4 Mar 2017 11:42:43 +0200 Subject: [PATCH 3/5] Changed limit logic, default limit is now 0 Clones now have a named based on the original entity id Limit is now calculated from the source instance, instead of just clone name to avoid a single box being calculated as something else Default limit is now 0, which disables limit --- .../system/controllers/handControllerGrab.js | 76 +++++++++---------- scripts/system/html/js/entityProperties.js | 6 +- 2 files changed, 39 insertions(+), 43 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 2e1d538db9..26178773e9 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -274,24 +274,24 @@ CONTROLLER_STATE_MACHINE[STATE_OVERLAY_LASER_TOUCHING] = CONTROLLER_STATE_MACHIN // Object assign polyfill if (typeof Object.assign != 'function') { - Object.assign = function(target, varArgs) { - 'use strict'; - if (target == null) { - throw new TypeError('Cannot convert undefined or null to object'); - } - var to = Object(target); - for (var index = 1; index < arguments.length; index++) { - var nextSource = arguments[index]; - if (nextSource != null) { - for (var nextKey in nextSource) { - if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { - to[nextKey] = nextSource[nextKey]; - } + Object.assign = function(target, varArgs) { + 'use strict'; + if (target == null) { + throw new TypeError('Cannot convert undefined or null to object'); } - } - } - return to; - }; + var to = Object(target); + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; + if (nextSource != null) { + for (var nextKey in nextSource) { + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + return to; + }; } function distanceBetweenPointAndEntityBoundingBox(point, entityProps) { @@ -1524,16 +1524,16 @@ function MyController(hand) { return true; }; this.entityIsCloneable = function(entityID) { - var entityProps = entityPropertiesCache.getGrabbableProps(entityID); - var props = entityPropertiesCache.getProps(entityID); - if (!props) { - return false; - } + var entityProps = entityPropertiesCache.getGrabbableProps(entityID); + var props = entityPropertiesCache.getProps(entityID); + if (!props) { + return false; + } - if (entityProps.hasOwnProperty("cloneable")) { - return entityProps.cloneable; - } - return false; + if (entityProps.hasOwnProperty("cloneable")) { + return entityProps.cloneable; + } + return false; } this.entityIsGrabbable = function(entityID) { var grabbableProps = entityPropertiesCache.getGrabbableProps(entityID); @@ -2229,7 +2229,7 @@ function MyController(hand) { // Can't set state of other controller to STATE_DISTANCE_HOLDING because then either: // (a) The entity would jump to line up with the formerly rotating controller's orientation, or // (b) The grab beam would need an orientation offset to the controller's true orientation. - // Neither of these options is good, so instead set STATE_SEARCHING and subsequently let the formerly distance + // Neither of these options is good, so instead set STATE_SEARCHING and subsequently let the formerly distance // rotating controller start distance holding the entity if it happens to be pointing at the entity. } return; @@ -2601,31 +2601,29 @@ function MyController(hand) { var userData = JSON.parse(grabbedProperties.userData); var grabInfo = userData.grabbableKey; if (grabInfo && grabInfo.cloneable) { - // Check if - var worldEntities = Entities.findEntitiesInBox(Vec3.subtract(MyAvatar.position, {x:25,y:25, z:25}), {x:50, y: 50, z: 50}) + var worldEntities = Entities.findEntities(MyAvatar.position, 50); var count = 0; worldEntities.forEach(function(item) { var item = Entities.getEntityProperties(item, ["name"]); - if (item.name === grabbedProperties.name) { + if (item.name.indexOf('-clone-' + grabbedProperties.id) !== -1) { count++; } }) + + var limit = grabInfo.cloneLimit ? grabInfo.cloneLimit : 0; + if (count >= limit && limit !== 0) { + delete limit; + return; + } + var cloneableProps = Entities.getEntityProperties(grabbedProperties.id); + cloneableProps.name = cloneableProps.name + '-clone-' + grabbedProperties.id; var lifetime = grabInfo.cloneLifetime ? grabInfo.cloneLifetime : 300; - var limit = grabInfo.cloneLimit ? grabInfo.cloneLimit : 10; var dynamic = grabInfo.cloneDynamic ? grabInfo.cloneDynamic : false; var cUserData = Object.assign({}, userData); var cProperties = Object.assign({}, cloneableProps); isClone = true; - if (count > limit) { - delete cloneableProps; - delete lifetime; - delete cUserData; - delete cProperties; - return; - } - delete cUserData.grabbableKey.cloneLifetime; delete cUserData.grabbableKey.cloneable; delete cUserData.grabbableKey.cloneDynamic; diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 3280e1f196..66abcaa67a 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -879,7 +879,7 @@ function loaded() { elCloneable.checked = false; elCloneableDynamic.checked = false; elCloneableGroup.style.display = elCloneable.checked ? "block": "none"; - elCloneableLimit.value = 10; + elCloneableLimit.value = 0; elCloneableLifetime.value = 300; var parsedUserData = {} @@ -899,8 +899,6 @@ function loaded() { if ("cloneable" in parsedUserData["grabbableKey"]) { elCloneable.checked = parsedUserData["grabbableKey"].cloneable; elCloneableGroup.style.display = elCloneable.checked ? "block": "none"; - elCloneableLimit.value = elCloneable.checked ? 10: 0; - elCloneableLifetime.value = elCloneable.checked ? 300: 0; elCloneableDynamic.checked = parsedUserData["grabbableKey"].cloneDynamic ? parsedUserData["grabbableKey"].cloneDynamic : properties.dynamic; elDynamic.checked = elCloneable.checked ? false: properties.dynamic; if (elCloneable.checked) { @@ -908,7 +906,7 @@ function loaded() { elCloneableLifetime.value = parsedUserData["grabbableKey"].cloneLifetime ? parsedUserData["grabbableKey"].cloneLifetime : 300; } if ("cloneLimit" in parsedUserData["grabbableKey"]) { - elCloneableLimit.value = parsedUserData["grabbableKey"].cloneLimit ? parsedUserData["grabbableKey"].cloneLimit : 10; + elCloneableLimit.value = parsedUserData["grabbableKey"].cloneLimit ? parsedUserData["grabbableKey"].cloneLimit : 0; } } } From f9dcfa54aab2d5fa998dcd69df9dac87eb462640 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 6 Mar 2017 16:08:21 -0800 Subject: [PATCH 4/5] Add debug/release builds to oculus lib --- cmake/externals/LibOVR/CMakeLists.txt | 8 +++++++- cmake/externals/LibOVR/LibOVRCMakeLists.txt | 5 ++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/cmake/externals/LibOVR/CMakeLists.txt b/cmake/externals/LibOVR/CMakeLists.txt index d8b8307082..c98aa8a04a 100644 --- a/cmake/externals/LibOVR/CMakeLists.txt +++ b/cmake/externals/LibOVR/CMakeLists.txt @@ -28,7 +28,13 @@ if (WIN32) ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) set(LIBOVR_DIR ${INSTALL_DIR}) set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${LIBOVR_DIR}/Include CACHE TYPE INTERNAL) - set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${LIBOVR_DIR}/Lib/LibOVR.lib CACHE TYPE INTERNAL) + set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${LIBOVR_DIR}/Lib/LibOVRd.lib CACHE TYPE INTERNAL) + set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${LIBOVR_DIR}/Lib/LibOVR.lib CACHE TYPE INTERNAL) + include(SelectLibraryConfigurations) + select_library_configurations(LIBOVR) + set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE TYPE INTERNAL) + message("Libs ${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES}") + elseif(APPLE) ExternalProject_Add( diff --git a/cmake/externals/LibOVR/LibOVRCMakeLists.txt b/cmake/externals/LibOVR/LibOVRCMakeLists.txt index bab6337ae2..556533f0c2 100644 --- a/cmake/externals/LibOVR/LibOVRCMakeLists.txt +++ b/cmake/externals/LibOVR/LibOVRCMakeLists.txt @@ -1,14 +1,13 @@ cmake_minimum_required(VERSION 3.2) project(LibOVR) -#set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DOVR_BUILD_DEBUG") - include_directories(LibOVR/Include LibOVR/Src) -#include_directories(LibOVRKernel/Src/) file(GLOB HEADER_FILES LibOVR/Include/*.h) file(GLOB EXTRA_HEADER_FILES LibOVR/Include/Extras/*.h) file(GLOB_RECURSE SOURCE_FILES LibOVR/Src/*.c LibOVR/Src/*.cpp) +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DOVR_BUILD_DEBUG") add_library(LibOVR STATIC ${SOURCE_FILES} ${HEADER_FILES} ${EXTRA_HEADER_FILES}) +set_target_properties(LibOVR PROPERTIES DEBUG_POSTFIX "d") install(TARGETS LibOVR DESTINATION Lib) install(FILES ${HEADER_FILES} DESTINATION Include) From d2a2ba18462f93a02eaffa5f7ac7f97949dc35b0 Mon Sep 17 00:00:00 2001 From: kunalgosar Date: Tue, 7 Mar 2017 17:19:21 -0800 Subject: [PATCH 5/5] Fixed recording bug --- libraries/avatars/src/AvatarData.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 06df75d451..3c33451f02 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -2000,6 +2000,11 @@ void AvatarData::fromJson(const QJsonObject& json, bool useFrameSkeleton) { } } + auto currentBasis = getRecordingBasis(); + if (!currentBasis) { + currentBasis = std::make_shared(Transform::fromJson(json[JSON_AVATAR_BASIS])); + } + if (json.contains(JSON_AVATAR_RELATIVE)) { // During playback you can either have the recording basis set to the avatar current state // meaning that all playback is relative to this avatars starting position, or @@ -2008,15 +2013,14 @@ void AvatarData::fromJson(const QJsonObject& json, bool useFrameSkeleton) { // The first is more useful for playing back recordings on your own avatar, while // the latter is more useful for playing back other avatars within your scene. - auto currentBasis = getRecordingBasis(); - if (!currentBasis) { - currentBasis = std::make_shared(Transform::fromJson(json[JSON_AVATAR_BASIS])); - } - auto relativeTransform = Transform::fromJson(json[JSON_AVATAR_RELATIVE]); auto worldTransform = currentBasis->worldTransform(relativeTransform); setPosition(worldTransform.getTranslation()); setOrientation(worldTransform.getRotation()); + } else { + // We still set the position in the case that there is no movement. + setPosition(currentBasis->getTranslation()); + setOrientation(currentBasis->getRotation()); } if (json.contains(JSON_AVATAR_SCALE)) {