Merge branch 'master' into transitAddAnimation
1
android/gradle.properties
Normal file
|
@ -0,0 +1 @@
|
|||
org.gradle.jvmargs=-Xms2g -Xmx4g
|
|
@ -368,11 +368,7 @@ void Agent::executeScript() {
|
|||
|
||||
// setup an Avatar for the script to use
|
||||
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
||||
|
||||
scriptedAvatar->setID(getSessionUUID());
|
||||
|
||||
connect(_scriptEngine.data(), SIGNAL(update(float)),
|
||||
scriptedAvatar.data(), SLOT(update(float)), Qt::ConnectionType::QueuedConnection);
|
||||
scriptedAvatar->setForceFaceTrackerConnected(true);
|
||||
|
||||
// call model URL setters with empty URLs so our avatar, if user, will have the default models
|
||||
|
@ -504,8 +500,6 @@ void Agent::executeScript() {
|
|||
|
||||
DependencyManager::set<AssignmentParentFinder>(_entityViewer.getTree());
|
||||
|
||||
_avatarAudioTimer.start();
|
||||
|
||||
// Agents should run at 45hz
|
||||
static const int AVATAR_DATA_HZ = 45;
|
||||
static const int AVATAR_DATA_IN_MSECS = MSECS_PER_SECOND / AVATAR_DATA_HZ;
|
||||
|
@ -530,7 +524,8 @@ void Agent::executeScript() {
|
|||
}
|
||||
|
||||
avatarDataTimer->stop();
|
||||
_avatarAudioTimer.stop();
|
||||
|
||||
setIsAvatar(false); // will stop timers for sending identity packets
|
||||
}
|
||||
|
||||
setFinished(true);
|
||||
|
@ -582,28 +577,33 @@ void Agent::setIsAvatar(bool isAvatar) {
|
|||
}
|
||||
_isAvatar = isAvatar;
|
||||
|
||||
if (_isAvatar && !_avatarIdentityTimer) {
|
||||
// set up the avatar timers
|
||||
_avatarIdentityTimer = new QTimer(this);
|
||||
_avatarQueryTimer = new QTimer(this);
|
||||
auto scriptableAvatar = DependencyManager::get<ScriptableAvatar>();
|
||||
if (_isAvatar) {
|
||||
if (!_avatarIdentityTimer) {
|
||||
// set up the avatar timers
|
||||
_avatarIdentityTimer = new QTimer(this);
|
||||
_avatarQueryTimer = new QTimer(this);
|
||||
|
||||
// connect our slot
|
||||
connect(_avatarIdentityTimer, &QTimer::timeout, this, &Agent::sendAvatarIdentityPacket);
|
||||
connect(_avatarQueryTimer, &QTimer::timeout, this, &Agent::queryAvatars);
|
||||
// connect our slot
|
||||
connect(_avatarIdentityTimer, &QTimer::timeout, this, &Agent::sendAvatarIdentityPacket);
|
||||
connect(_avatarQueryTimer, &QTimer::timeout, this, &Agent::queryAvatars);
|
||||
|
||||
static const int AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS = 1000;
|
||||
static const int AVATAR_VIEW_PACKET_SEND_INTERVAL_MSECS = 1000;
|
||||
static const int AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS = 1000;
|
||||
static const int AVATAR_VIEW_PACKET_SEND_INTERVAL_MSECS = 1000;
|
||||
|
||||
// start the timers
|
||||
_avatarIdentityTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS); // FIXME - we shouldn't really need to constantly send identity packets
|
||||
_avatarQueryTimer->start(AVATAR_VIEW_PACKET_SEND_INTERVAL_MSECS);
|
||||
// start the timers
|
||||
_avatarIdentityTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS); // FIXME - we shouldn't really need to constantly send identity packets
|
||||
_avatarQueryTimer->start(AVATAR_VIEW_PACKET_SEND_INTERVAL_MSECS);
|
||||
|
||||
// tell the avatarAudioTimer to start ticking
|
||||
QMetaObject::invokeMethod(&_avatarAudioTimer, "start");
|
||||
}
|
||||
connect(_scriptEngine.data(), &ScriptEngine::update,
|
||||
scriptableAvatar.data(), &ScriptableAvatar::update, Qt::QueuedConnection);
|
||||
|
||||
if (!_isAvatar) {
|
||||
// tell the avatarAudioTimer to start ticking
|
||||
QMetaObject::invokeMethod(&_avatarAudioTimer, "start");
|
||||
}
|
||||
|
||||
_entityEditSender.setMyAvatar(scriptableAvatar.data());
|
||||
} else {
|
||||
if (_avatarIdentityTimer) {
|
||||
_avatarIdentityTimer->stop();
|
||||
delete _avatarIdentityTimer;
|
||||
|
@ -630,14 +630,14 @@ void Agent::setIsAvatar(bool isAvatar) {
|
|||
packet->writePrimitive(KillAvatarReason::NoReason);
|
||||
nodeList->sendPacket(std::move(packet), *node);
|
||||
});
|
||||
|
||||
disconnect(_scriptEngine.data(), &ScriptEngine::update,
|
||||
scriptableAvatar.data(), &ScriptableAvatar::update);
|
||||
|
||||
QMetaObject::invokeMethod(&_avatarAudioTimer, "stop");
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(&_avatarAudioTimer, "stop");
|
||||
|
||||
_entityEditSender.setMyAvatar(nullptr);
|
||||
} else {
|
||||
auto scriptableAvatar = DependencyManager::get<ScriptableAvatar>();
|
||||
_entityEditSender.setMyAvatar(scriptableAvatar.data());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -788,7 +788,7 @@ void Agent::processAgentAvatarAudio() {
|
|||
// seek past the sequence number, will be packed when destination node is known
|
||||
audioPacket->seek(sizeof(quint16));
|
||||
|
||||
if (silentFrame) {
|
||||
if (silentFrame && !_flushEncoder) {
|
||||
|
||||
if (!_isListeningToAudioStream) {
|
||||
// if we have a silent frame and we're not listening then just send nothing and break out of here
|
||||
|
@ -810,7 +810,7 @@ void Agent::processAgentAvatarAudio() {
|
|||
|
||||
// no matter what, the loudness should be set to 0
|
||||
computeLoudness(nullptr, scriptedAvatar);
|
||||
} else if (nextSoundOutput) {
|
||||
} else if (nextSoundOutput || _flushEncoder) {
|
||||
|
||||
// write the codec
|
||||
audioPacket->writeString(_selectedCodecName);
|
||||
|
@ -864,8 +864,6 @@ void Agent::processAgentAvatarAudio() {
|
|||
}
|
||||
|
||||
void Agent::aboutToFinish() {
|
||||
setIsAvatar(false);// will stop timers for sending identity packets
|
||||
|
||||
// our entity tree is going to go away so tell that to the EntityScriptingInterface
|
||||
DependencyManager::get<EntityScriptingInterface>()->setEntityTree(nullptr);
|
||||
|
||||
|
|
|
@ -497,7 +497,7 @@ void AudioMixerClientData::processStreamPacket(ReceivedMessage& message, Concurr
|
|||
|
||||
if (newStream) {
|
||||
// whenever a stream is added, push it to the concurrent vector of streams added this frame
|
||||
addedStreams.emplace_back(getNodeID(), getNodeLocalID(), matchingStream->getStreamIdentifier(), matchingStream.get());
|
||||
addedStreams.push_back(AddedStream(getNodeID(), getNodeLocalID(), matchingStream->getStreamIdentifier(), matchingStream.get()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -380,6 +380,11 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node)
|
|||
if (lastSeqToReceiver == lastSeqFromSender && lastSeqToReceiver != 0) {
|
||||
++numAvatarsHeldBack;
|
||||
shouldIgnore = true;
|
||||
} else if (lastSeqFromSender == 0) {
|
||||
// We have have not yet recieved any data about this avatar. Ignore it for now
|
||||
// This is important for Agent scripts that are not avatar
|
||||
// so that they don't appear to be an avatar at the origin
|
||||
shouldIgnore = true;
|
||||
} else if (lastSeqFromSender - lastSeqToReceiver > 1) {
|
||||
// this is a skip - we still send the packet but capture the presence of the skip so we see it happening
|
||||
++numAvatarsWithSkippedFrames;
|
||||
|
|
|
@ -164,7 +164,7 @@ public:
|
|||
void setHasAudioEnabledFaceMovement(bool hasAudioEnabledFaceMovement);
|
||||
bool getHasAudioEnabledFaceMovement() const override { return _headData->getHasAudioEnabledFaceMovement(); }
|
||||
|
||||
private slots:
|
||||
public slots:
|
||||
void update(float deltatime);
|
||||
|
||||
private:
|
||||
|
|
|
@ -88,7 +88,7 @@ if (APPLE)
|
|||
set(OSX_SDK "${OSX_VERSION}" CACHE String "OS X SDK version to look for inside Xcode bundle or at OSX_SDK_PATH")
|
||||
|
||||
# set our OS X deployment target
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9)
|
||||
|
||||
# find the SDK path for the desired SDK
|
||||
find_path(
|
||||
|
|
14
cmake/externals/quazip/CMakeLists.txt
vendored
|
@ -1,14 +1,12 @@
|
|||
set(EXTERNAL_NAME quazip)
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
cmake_policy(SET CMP0046 OLD)
|
||||
|
||||
include(ExternalProject)
|
||||
|
||||
set(QUAZIP_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_PREFIX_PATH=${QT_CMAKE_PREFIX_PATH} -DCMAKE_INSTALL_NAME_DIR:PATH=<INSTALL_DIR>/lib -DZLIB_ROOT=${ZLIB_ROOT} -DCMAKE_POSITION_INDEPENDENT_CODE=ON)
|
||||
|
||||
if (APPLE)
|
||||
else ()
|
||||
set(QUAZIP_CMAKE_ARGS ${QUAZIP_CMAKE_ARGS} -DCMAKE_CXX_STANDARD=11)
|
||||
if (NOT APPLE)
|
||||
set(QUAZIP_CMAKE_ARGS ${QUAZIP_CMAKE_ARGS} -DCMAKE_CXX_STANDARD=11)
|
||||
endif ()
|
||||
|
||||
ExternalProject_Add(
|
||||
|
@ -22,10 +20,12 @@ ExternalProject_Add(
|
|||
LOG_BUILD 1
|
||||
)
|
||||
|
||||
add_dependencies(quazip zlib)
|
||||
if (WIN32)
|
||||
add_dependencies(quazip zlib)
|
||||
endif ()
|
||||
|
||||
# Hide this external target (for ide users)
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES
|
||||
FOLDER "hidden/externals"
|
||||
INSTALL_NAME_DIR ${INSTALL_DIR}/lib
|
||||
BUILD_WITH_INSTALL_RPATH True)
|
||||
|
@ -54,4 +54,4 @@ select_library_configurations(${EXTERNAL_NAME_UPPER})
|
|||
|
||||
# Force selected libraries into the cache
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY ${${EXTERNAL_NAME_UPPER}_LIBRARY} CACHE FILEPATH "Location of QuaZip libraries")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE FILEPATH "Location of QuaZip libraries")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE FILEPATH "Location of QuaZip libraries")
|
||||
|
|
|
@ -3,11 +3,11 @@ if (WIN32)
|
|||
endif (WIN32)
|
||||
|
||||
if (POLICY CMP0043)
|
||||
cmake_policy(SET CMP0043 OLD)
|
||||
cmake_policy(SET CMP0043 NEW)
|
||||
endif ()
|
||||
|
||||
if (POLICY CMP0042)
|
||||
cmake_policy(SET CMP0042 OLD)
|
||||
cmake_policy(SET CMP0042 NEW)
|
||||
endif ()
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
@ -34,7 +34,7 @@ file(GLOB HIFI_CUSTOM_MACROS "cmake/macros/*.cmake")
|
|||
foreach(CUSTOM_MACRO ${HIFI_CUSTOM_MACROS})
|
||||
include(${CUSTOM_MACRO})
|
||||
endforeach()
|
||||
unset(HIFI_CUSTOM_MACROS)
|
||||
unset(HIFI_CUSTOM_MACROS)
|
||||
|
||||
if (ANDROID)
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#
|
||||
#
|
||||
# Copyright 2015 High Fidelity, Inc.
|
||||
# Created by Bradley Austin Davis on 2015/10/10
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
#
|
||||
macro(TARGET_ZLIB)
|
||||
|
||||
if (WIN32)
|
||||
|
|
|
@ -2906,7 +2906,7 @@ void DomainServer::updateReplicationNodes(ReplicationServerDirection direction)
|
|||
// collect them in a vector to separately remove them with handleKillNode (since eachNode has a read lock and
|
||||
// we cannot recursively take the write lock required by handleKillNode)
|
||||
std::vector<SharedNodePointer> nodesToKill;
|
||||
nodeList->eachNode([direction, replicationNodesInSettings, replicationDirection, &nodesToKill](const SharedNodePointer& otherNode) {
|
||||
nodeList->eachNode([&direction, &replicationNodesInSettings, &replicationDirection, &nodesToKill](const SharedNodePointer& otherNode) {
|
||||
if ((direction == Upstream && NodeType::isUpstream(otherNode->getType()))
|
||||
|| (direction == Downstream && NodeType::isDownstream(otherNode->getType()))) {
|
||||
bool nodeInSettings = find(replicationNodesInSettings.cbegin(), replicationNodesInSettings.cend(),
|
||||
|
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 548 KiB |
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"compressed": {
|
||||
"COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT": "Default-Sky-9-cubemap_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT.ktx",
|
||||
"COMPRESSED_SRGB8_ETC2": "Default-Sky-9-cubemap_COMPRESSED_SRGB8_ETC2.ktx"
|
||||
},
|
||||
"original": "Default-Sky-9-cubemap.jpg",
|
||||
"uncompressed": "Default-Sky-9-cubemap.ktx"
|
||||
}
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 164 KiB |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 175 KiB |
|
@ -39,6 +39,7 @@ Item {
|
|||
property string sendingPubliclyEffectImage;
|
||||
property var http;
|
||||
property var listModelName;
|
||||
property var keyboardContainer: nil;
|
||||
|
||||
// This object is always used in a popup or full-screen Wallet section.
|
||||
// This MouseArea is used to prevent a user from being
|
||||
|
@ -1125,8 +1126,7 @@ Item {
|
|||
checked: Settings.getValue("sendAssetsNearbyPublicly", true);
|
||||
text: "Show Effect"
|
||||
// Anchors
|
||||
anchors.top: messageContainer.bottom;
|
||||
anchors.topMargin: 16;
|
||||
anchors.verticalCenter: bottomBarContainer.verticalCenter;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 20;
|
||||
width: 130;
|
||||
|
@ -1168,6 +1168,9 @@ Item {
|
|||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
if (keyboardContainer) {
|
||||
keyboardContainer.keyboardRaised = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1178,8 +1181,8 @@ Item {
|
|||
anchors.leftMargin: 20;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 20;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 20;
|
||||
anchors.top: messageContainer.bottom;
|
||||
anchors.topMargin: 20;
|
||||
height: 60;
|
||||
|
||||
// "CANCEL" button
|
||||
|
@ -1187,11 +1190,11 @@ Item {
|
|||
id: cancelButton_sendAssetStep;
|
||||
color: root.assetName === "" ? hifi.buttons.noneBorderlessWhite : hifi.buttons.noneBorderlessGray;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 24;
|
||||
anchors.right: sendButton.left;
|
||||
anchors.rightMargin: 24;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
height: 40;
|
||||
width: 150;
|
||||
width: 100;
|
||||
text: "CANCEL";
|
||||
onClicked: {
|
||||
resetSendAssetData();
|
||||
|
@ -1205,10 +1208,10 @@ Item {
|
|||
color: hifi.buttons.blue;
|
||||
colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 24;
|
||||
anchors.rightMargin: 0;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
height: 40;
|
||||
width: 150;
|
||||
width: 100;
|
||||
text: "SUBMIT";
|
||||
onClicked: {
|
||||
if (root.assetName === "" && parseInt(amountTextField.text) > parseInt(balanceText.text)) {
|
||||
|
|
|
@ -158,6 +158,7 @@ Rectangle {
|
|||
listModelName: "Gift Connections";
|
||||
z: 998;
|
||||
visible: root.activeView === "giftAsset";
|
||||
keyboardContainer: root;
|
||||
anchors.fill: parent;
|
||||
parentAppTitleBarHeight: 70;
|
||||
parentAppNavBarHeight: 0;
|
||||
|
@ -585,7 +586,7 @@ Rectangle {
|
|||
visible: purchasesModel.count !== 0;
|
||||
clip: true;
|
||||
model: purchasesModel;
|
||||
snapMode: ListView.SnapToItem;
|
||||
snapMode: ListView.NoSnap;
|
||||
// Anchors
|
||||
anchors.top: separator.bottom;
|
||||
anchors.left: parent.left;
|
||||
|
|
|
@ -354,6 +354,7 @@ Rectangle {
|
|||
listModelName: "Send Money Connections";
|
||||
z: 997;
|
||||
visible: root.activeView === "sendMoney";
|
||||
keyboardContainer: root;
|
||||
anchors.fill: parent;
|
||||
parentAppTitleBarHeight: titleBarContainer.height;
|
||||
parentAppNavBarHeight: tabButtonsContainer.height;
|
||||
|
|
|
@ -152,6 +152,8 @@
|
|||
#include <avatars-renderer/ScriptAvatar.h>
|
||||
#include <RenderableEntityItem.h>
|
||||
#include <procedural/ProceduralSkybox.h>
|
||||
#include <model-networking/MaterialCache.h>
|
||||
#include "recording/ClipCache.h"
|
||||
|
||||
#include "AudioClient.h"
|
||||
#include "audio/AudioScope.h"
|
||||
|
@ -328,9 +330,9 @@ static bool DISABLE_DEFERRED = QProcessEnvironment::systemEnvironment().contains
|
|||
#endif
|
||||
|
||||
#if !defined(Q_OS_ANDROID)
|
||||
static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16;
|
||||
static const uint32_t MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16;
|
||||
#else
|
||||
static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 4;
|
||||
static const uint32_t MAX_CONCURRENT_RESOURCE_DOWNLOADS = 4;
|
||||
#endif
|
||||
|
||||
// For processing on QThreadPool, we target a number of threads after reserving some
|
||||
|
@ -1327,7 +1329,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
|
||||
QString concurrentDownloadsStr = getCmdOption(argc, constArgv, "--concurrent-downloads");
|
||||
bool success;
|
||||
int concurrentDownloads = concurrentDownloadsStr.toInt(&success);
|
||||
uint32_t concurrentDownloads = concurrentDownloadsStr.toUInt(&success);
|
||||
if (!success) {
|
||||
concurrentDownloads = MAX_CONCURRENT_RESOURCE_DOWNLOADS;
|
||||
}
|
||||
|
@ -2054,7 +2056,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
}
|
||||
|
||||
properties["active_downloads"] = loadingRequests.size();
|
||||
properties["pending_downloads"] = ResourceCache::getPendingRequestCount();
|
||||
properties["pending_downloads"] = (int)ResourceCache::getPendingRequestCount();
|
||||
properties["active_downloads_details"] = loadingRequestsStats;
|
||||
|
||||
auto statTracker = DependencyManager::get<StatTracker>();
|
||||
|
@ -3532,6 +3534,7 @@ void Application::setIsInterstitialMode(bool interstitialMode) {
|
|||
if (enableInterstitial) {
|
||||
if (_interstitialMode != interstitialMode) {
|
||||
_interstitialMode = interstitialMode;
|
||||
emit interstitialModeChanged(_interstitialMode);
|
||||
|
||||
DependencyManager::get<AudioClient>()->setAudioPaused(_interstitialMode);
|
||||
DependencyManager::get<AvatarManager>()->setMyAvatarDataPacketsPaused(_interstitialMode);
|
||||
|
@ -4653,8 +4656,8 @@ void Application::idle() {
|
|||
PROFILE_COUNTER_IF_CHANGED(app, "present", float, displayPlugin->presentRate());
|
||||
}
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "renderLoopRate", float, _renderLoopCounter.rate());
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", int, ResourceCache::getLoadingRequests().length());
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", int, ResourceCache::getPendingRequestCount());
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", uint32_t, ResourceCache::getLoadingRequestCount());
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", uint32_t, ResourceCache::getPendingRequestCount());
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "currentProcessing", int, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "pendingProcessing", int, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
|
||||
auto renderConfig = _renderEngine->getConfiguration();
|
||||
|
@ -5399,13 +5402,21 @@ void Application::reloadResourceCaches() {
|
|||
|
||||
queryOctree(NodeType::EntityServer, PacketType::EntityQuery);
|
||||
|
||||
// Clear the entities and their renderables
|
||||
getEntities()->clear();
|
||||
|
||||
DependencyManager::get<AssetClient>()->clearCache();
|
||||
DependencyManager::get<ScriptCache>()->clearCache();
|
||||
|
||||
// Clear all the resource caches
|
||||
DependencyManager::get<ResourceCacheSharedItems>()->clear();
|
||||
DependencyManager::get<AnimationCache>()->refreshAll();
|
||||
DependencyManager::get<ModelCache>()->refreshAll();
|
||||
DependencyManager::get<SoundCache>()->refreshAll();
|
||||
MaterialCache::instance().refreshAll();
|
||||
DependencyManager::get<ModelCache>()->refreshAll();
|
||||
ShaderCache::instance().refreshAll();
|
||||
DependencyManager::get<TextureCache>()->refreshAll();
|
||||
DependencyManager::get<recording::ClipCache>()->refreshAll();
|
||||
|
||||
DependencyManager::get<NodeList>()->reset(); // Force redownload of .fst models
|
||||
|
||||
|
@ -6470,9 +6481,12 @@ void Application::clearDomainOctreeDetails() {
|
|||
skyStage->setBackgroundMode(graphics::SunSkyStage::SKY_DEFAULT);
|
||||
|
||||
DependencyManager::get<AnimationCache>()->clearUnusedResources();
|
||||
DependencyManager::get<ModelCache>()->clearUnusedResources();
|
||||
DependencyManager::get<SoundCache>()->clearUnusedResources();
|
||||
MaterialCache::instance().clearUnusedResources();
|
||||
DependencyManager::get<ModelCache>()->clearUnusedResources();
|
||||
ShaderCache::instance().clearUnusedResources();
|
||||
DependencyManager::get<TextureCache>()->clearUnusedResources();
|
||||
DependencyManager::get<recording::ClipCache>()->clearUnusedResources();
|
||||
|
||||
getMyAvatar()->setAvatarEntityDataChanged(true);
|
||||
}
|
||||
|
@ -8463,6 +8477,16 @@ QUuid Application::getTabletFrameID() const {
|
|||
return HMD->getCurrentTabletFrameID();
|
||||
}
|
||||
|
||||
QVector<QUuid> Application::getTabletIDs() const {
|
||||
// Most important overlays first.
|
||||
QVector<QUuid> result;
|
||||
auto HMD = DependencyManager::get<HMDScriptingInterface>();
|
||||
result << HMD->getCurrentTabletScreenID();
|
||||
result << HMD->getCurrentHomeButtonID();
|
||||
result << HMD->getCurrentTabletFrameID();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Application::setAvatarOverrideUrl(const QUrl& url, bool save) {
|
||||
_avatarOverrideUrl = url;
|
||||
_saveAvatarOverrideUrl = save;
|
||||
|
|
|
@ -298,6 +298,7 @@ public:
|
|||
OverlayID getTabletScreenID() const;
|
||||
OverlayID getTabletHomeButtonID() const;
|
||||
QUuid getTabletFrameID() const; // may be an entity or an overlay
|
||||
QVector<QUuid> getTabletIDs() const; // In order of most important IDs first.
|
||||
|
||||
void setAvatarOverrideUrl(const QUrl& url, bool save);
|
||||
void clearAvatarOverrideUrl() { _avatarOverrideUrl = QUrl(); _saveAvatarOverrideUrl = false; }
|
||||
|
@ -334,6 +335,8 @@ signals:
|
|||
|
||||
void uploadRequest(QString path);
|
||||
|
||||
void interstitialModeChanged(bool isInInterstitialMode);
|
||||
|
||||
void loginDialogPoppedUp();
|
||||
|
||||
public slots:
|
||||
|
|
|
@ -78,8 +78,10 @@ void addAvatarEntities(const QVariantList& avatarEntities) {
|
|||
}
|
||||
|
||||
entity->setLastBroadcast(usecTimestampNow());
|
||||
// since we're creating this object we will immediately volunteer to own its simulation
|
||||
entity->setScriptSimulationPriority(VOLUNTEER_SIMULATION_PRIORITY);
|
||||
if (entityProperties.getDynamic()) {
|
||||
// since we're creating a dynamic object we volunteer immediately to own its simulation
|
||||
entity->upgradeScriptSimulationPriority(VOLUNTEER_SIMULATION_PRIORITY);
|
||||
}
|
||||
entityProperties.setLastEdited(entity->getLastEdited());
|
||||
} else {
|
||||
qCDebug(entities) << "AvatarEntitiesBookmark failed to add new Entity to local Octree";
|
||||
|
@ -108,6 +110,9 @@ AvatarBookmarks::AvatarBookmarks() {
|
|||
|
||||
if (!QFile::copy(defaultBookmarksFilename, _bookmarksFilename)) {
|
||||
qDebug() << "failed to copy" << defaultBookmarksFilename << "to" << _bookmarksFilename;
|
||||
} else {
|
||||
QFile bookmarksFile(_bookmarksFilename);
|
||||
bookmarksFile.setPermissions(bookmarksFile.permissions() | QFile::WriteUser);
|
||||
}
|
||||
}
|
||||
readFromFile();
|
||||
|
|
|
@ -55,15 +55,7 @@ static const quint64 MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS = USECS_PER_SECOND /
|
|||
// We add _myAvatar into the hash with all the other AvatarData, and we use the default NULL QUid as the key.
|
||||
const QUuid MY_AVATAR_KEY; // NULL key
|
||||
|
||||
namespace {
|
||||
// For an unknown avatar-data packet, wait this long before requesting the identity.
|
||||
constexpr std::chrono::milliseconds REQUEST_UNKNOWN_IDENTITY_DELAY { 5 * 1000 };
|
||||
constexpr int REQUEST_UNKNOWN_IDENTITY_TRANSMITS = 3;
|
||||
}
|
||||
using std::chrono::steady_clock;
|
||||
|
||||
AvatarManager::AvatarManager(QObject* parent) :
|
||||
_avatarsToFade(),
|
||||
_myAvatar(new MyAvatar(qApp->thread()), [](MyAvatar* ptr) { ptr->deleteLater(); })
|
||||
{
|
||||
// register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
|
||||
|
@ -345,28 +337,6 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
|||
|
||||
simulateAvatarFades(deltaTime);
|
||||
|
||||
// Check on avatars with pending identities:
|
||||
steady_clock::time_point now = steady_clock::now();
|
||||
QWriteLocker writeLock(&_hashLock);
|
||||
for (auto pendingAvatar = _pendingAvatars.begin(); pendingAvatar != _pendingAvatars.end(); ++pendingAvatar) {
|
||||
if (now - pendingAvatar->creationTime >= REQUEST_UNKNOWN_IDENTITY_DELAY) {
|
||||
// Too long without an ID
|
||||
sendIdentityRequest(pendingAvatar->avatar->getID());
|
||||
if (++pendingAvatar->transmits >= REQUEST_UNKNOWN_IDENTITY_TRANSMITS) {
|
||||
qCDebug(avatars) << "Requesting identity for unknown avatar (final request)" <<
|
||||
pendingAvatar->avatar->getID().toString();
|
||||
|
||||
pendingAvatar = _pendingAvatars.erase(pendingAvatar);
|
||||
if (pendingAvatar == _pendingAvatars.end()) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
pendingAvatar->creationTime = now;
|
||||
qCDebug(avatars) << "Requesting identity for unknown avatar" << pendingAvatar->avatar->getID().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_avatarSimulationTime = (float)(usecTimestampNow() - startTime) / (float)USECS_PER_MSEC;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ using SortedAvatar = std::pair<float, std::shared_ptr<Avatar>>;
|
|||
* @borrows AvatarList.sessionUUIDChanged as sessionUUIDChanged
|
||||
* @borrows AvatarList.processAvatarDataPacket as processAvatarDataPacket
|
||||
* @borrows AvatarList.processAvatarIdentityPacket as processAvatarIdentityPacket
|
||||
* @borrows AvatarList.processBulkAvatarTraits as processBulkAvatarTraits
|
||||
* @borrows AvatarList.processKillAvatar as processKillAvatar
|
||||
*/
|
||||
|
||||
|
@ -152,6 +153,13 @@ public:
|
|||
const QVector<EntityItemID>& avatarsToInclude,
|
||||
const QVector<EntityItemID>& avatarsToDiscard);
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarManager.findParabolaIntersectionVector
|
||||
* @param {PickParabola} pick
|
||||
* @param {Uuid[]} avatarsToInclude
|
||||
* @param {Uuid[]} avatarsToDiscard
|
||||
* @returns {ParabolaToAvatarIntersectionResult}
|
||||
*/
|
||||
Q_INVOKABLE ParabolaToAvatarIntersectionResult findParabolaIntersectionVector(const PickParabola& pick,
|
||||
const QVector<EntityItemID>& avatarsToInclude,
|
||||
const QVector<EntityItemID>& avatarsToDiscard);
|
||||
|
@ -176,7 +184,7 @@ public:
|
|||
* than iterating over each avatar and obtaining data about them in JavaScript, as that method
|
||||
* locks and unlocks each avatar's data structure potentially hundreds of times per update tick.
|
||||
* @function AvatarManager.getPalData
|
||||
* @param {string[]} specificAvatarIdentifiers - A list of specific Avatar Identifiers about
|
||||
* @param {string[]} [specificAvatarIdentifiers] - A list of specific Avatar Identifiers about
|
||||
* which you want to get PAL data
|
||||
* @returns {object}
|
||||
*/
|
||||
|
|
|
@ -122,7 +122,6 @@ MyAvatar::MyAvatar(QThread* thread) :
|
|||
_goToOrientation(),
|
||||
_prevShouldDrawHead(true),
|
||||
_audioListenerMode(FROM_HEAD),
|
||||
_hmdAtRestDetector(glm::vec3(0), glm::quat()),
|
||||
_dominantHandSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "dominantHand", DOMINANT_RIGHT_HAND),
|
||||
_headPitchSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "", 0.0f),
|
||||
_scaleSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "scale", _targetScale),
|
||||
|
@ -702,6 +701,46 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
// before we perform rig animations and IK.
|
||||
updateSensorToWorldMatrix();
|
||||
|
||||
// if we detect the hand controller is at rest, i.e. lying on the table, or the hand is too far away from the hmd
|
||||
// disable the associated hand controller input.
|
||||
{
|
||||
// NOTE: all poses are in sensor space.
|
||||
auto leftHandIter = _controllerPoseMap.find(controller::Action::LEFT_HAND);
|
||||
if (leftHandIter != _controllerPoseMap.end() && leftHandIter->second.isValid()) {
|
||||
_leftHandAtRestDetector.update(leftHandIter->second.getTranslation(), leftHandIter->second.getRotation());
|
||||
if (_leftHandAtRestDetector.isAtRest()) {
|
||||
leftHandIter->second.valid = false;
|
||||
}
|
||||
} else {
|
||||
_leftHandAtRestDetector.invalidate();
|
||||
}
|
||||
|
||||
auto rightHandIter = _controllerPoseMap.find(controller::Action::RIGHT_HAND);
|
||||
if (rightHandIter != _controllerPoseMap.end() && rightHandIter->second.isValid()) {
|
||||
_rightHandAtRestDetector.update(rightHandIter->second.getTranslation(), rightHandIter->second.getRotation());
|
||||
if (_rightHandAtRestDetector.isAtRest()) {
|
||||
rightHandIter->second.valid = false;
|
||||
}
|
||||
} else {
|
||||
_rightHandAtRestDetector.invalidate();
|
||||
}
|
||||
|
||||
auto headIter = _controllerPoseMap.find(controller::Action::HEAD);
|
||||
|
||||
// The 99th percentile man has a spine to fingertip to height ratio of 0.45. Lets increase that by about 10% to 0.5
|
||||
// then measure the distance the center of the eyes to the finger tips. To come up with this ratio.
|
||||
// From "The Measure of Man and Woman: Human Factors in Design, Revised Edition" by Alvin R. Tilley, Henry Dreyfuss Associates
|
||||
const float MAX_HEAD_TO_HAND_DISTANCE_RATIO = 0.52f;
|
||||
|
||||
float maxHeadHandDistance = getUserHeight() * MAX_HEAD_TO_HAND_DISTANCE_RATIO;
|
||||
if (glm::length(headIter->second.getTranslation() - leftHandIter->second.getTranslation()) > maxHeadHandDistance) {
|
||||
leftHandIter->second.valid = false;
|
||||
}
|
||||
if (glm::length(headIter->second.getTranslation() - rightHandIter->second.getTranslation()) > maxHeadHandDistance) {
|
||||
rightHandIter->second.valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("skeleton");
|
||||
|
||||
|
@ -1941,7 +1980,7 @@ void MyAvatar::updateMotors() {
|
|||
horizontalMotorTimescale = FLYING_MOTOR_TIMESCALE;
|
||||
verticalMotorTimescale = FLYING_MOTOR_TIMESCALE;
|
||||
} else {
|
||||
horizontalMotorTimescale = WALKING_MOTOR_TIMESCALE;
|
||||
horizontalMotorTimescale = WALKING_MOTOR_TIMESCALE * getSensorToWorldScale();
|
||||
verticalMotorTimescale = INVALID_MOTOR_TIMESCALE;
|
||||
}
|
||||
|
||||
|
|
|
@ -629,8 +629,6 @@ public:
|
|||
|
||||
const MyHead* getMyHead() const;
|
||||
|
||||
Q_INVOKABLE void toggleSmoothPoleVectors() { _skeletonModel->getRig().toggleSmoothPoleVectors(); };
|
||||
|
||||
/**jsdoc
|
||||
* Get the current position of the avatar's "Head" joint.
|
||||
* @function MyAvatar.getHeadPosition
|
||||
|
@ -951,50 +949,72 @@ public:
|
|||
void removeWearableAvatarEntities();
|
||||
|
||||
/**jsdoc
|
||||
* Check whether your avatar is flying or not.
|
||||
* @function MyAvatar.isFlying
|
||||
* @returns {boolean}
|
||||
* @returns {boolean} <code>true</code> if your avatar is flying and not taking off or falling, otherwise
|
||||
* <code>false</code>.
|
||||
*/
|
||||
Q_INVOKABLE bool isFlying();
|
||||
|
||||
/**jsdoc
|
||||
* Check whether your avatar is in the air or not.
|
||||
* @function MyAvatar.isInAir
|
||||
* @returns {boolean}
|
||||
* @returns {boolean} <code>true</code> if your avatar is taking off, flying, or falling, otherwise <code>false</code>
|
||||
* because your avatar is on the ground.
|
||||
*/
|
||||
Q_INVOKABLE bool isInAir();
|
||||
|
||||
/**jsdoc
|
||||
* Set your preference for flying in your current desktop or HMD display mode. Note that your ability to fly also depends
|
||||
* on whether the domain you're in allows you to fly.
|
||||
* @function MyAvatar.setFlyingEnabled
|
||||
* @param {boolean} enabled
|
||||
* @param {boolean} enabled - Set <code>true</code> if you want to enable flying in your current desktop or HMD display
|
||||
* mode, otherwise set <code>false</code>.
|
||||
*/
|
||||
Q_INVOKABLE void setFlyingEnabled(bool enabled);
|
||||
|
||||
/**jsdoc
|
||||
* Get your preference for flying in your current desktop or HMD display mode. Note that your ability to fly also depends
|
||||
* on whether the domain you're in allows you to fly.
|
||||
* @function MyAvatar.getFlyingEnabled
|
||||
* @returns {boolean}
|
||||
* @returns {boolean} <code>true</code> if your preference is to enable flying in your current desktop or HMD display mode,
|
||||
* otherwise <code>false</code>.
|
||||
*/
|
||||
Q_INVOKABLE bool getFlyingEnabled();
|
||||
|
||||
/**jsdoc
|
||||
* Set your preference for flying in desktop display mode. Note that your ability to fly also depends on whether the domain
|
||||
* you're in allows you to fly.
|
||||
* @function MyAvatar.setFlyingDesktopPref
|
||||
* @param {boolean} enabled
|
||||
* @param {boolean} enabled - Set <code>true</code> if you want to enable flying in desktop display mode, otherwise set
|
||||
* <code>false</code>.
|
||||
*/
|
||||
Q_INVOKABLE void setFlyingDesktopPref(bool enabled);
|
||||
|
||||
/**jsdoc
|
||||
* Get your preference for flying in desktop display mode. Note that your ability to fly also depends on whether the domain
|
||||
* you're in allows you to fly.
|
||||
* @function MyAvatar.getFlyingDesktopPref
|
||||
* @returns {boolean}
|
||||
* @returns {boolean} <code>true</code> if your preference is to enable flying in desktop display mode, otherwise
|
||||
* <code>false</code>.
|
||||
*/
|
||||
Q_INVOKABLE bool getFlyingDesktopPref();
|
||||
|
||||
/**jsdoc
|
||||
* @function MyAvatar.setFlyingDesktopPref
|
||||
* @param {boolean} enabled
|
||||
* Set your preference for flying in HMD display mode. Note that your ability to fly also depends on whether the domain
|
||||
* you're in allows you to fly.
|
||||
* @function MyAvatar.setFlyingHMDPref
|
||||
* @param {boolean} enabled - Set <code>true</code> if you want to enable flying in HMD display mode, otherwise set
|
||||
* <code>false</code>.
|
||||
*/
|
||||
Q_INVOKABLE void setFlyingHMDPref(bool enabled);
|
||||
|
||||
/**jsdoc
|
||||
* @function MyAvatar.getFlyingDesktopPref
|
||||
* @returns {boolean}
|
||||
* Get your preference for flying in HMD display mode. Note that your ability to fly also depends on whether the domain
|
||||
* you're in allows you to fly.
|
||||
* @function MyAvatar.getFlyingHMDPref
|
||||
* @returns {boolean} <code>true</code> if your preference is to enable flying in HMD display mode, otherwise
|
||||
* <code>false</code>.
|
||||
*/
|
||||
Q_INVOKABLE bool getFlyingHMDPref();
|
||||
|
||||
|
@ -1766,8 +1786,8 @@ private:
|
|||
glm::vec3 _customListenPosition;
|
||||
glm::quat _customListenOrientation;
|
||||
|
||||
AtRestDetector _hmdAtRestDetector;
|
||||
bool _lastIsMoving { false };
|
||||
AtRestDetector _leftHandAtRestDetector;
|
||||
AtRestDetector _rightHandAtRestDetector;
|
||||
|
||||
// all poses are in sensor-frame
|
||||
std::map<controller::Action, controller::Pose> _controllerPoseMap;
|
||||
|
|
|
@ -46,7 +46,7 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) {
|
|||
}
|
||||
|
||||
glm::mat4 hipsMat;
|
||||
if (myAvatar->getCenterOfGravityModelEnabled() && !isFlying && !(myAvatar->getIsInWalkingState())) {
|
||||
if (myAvatar->getCenterOfGravityModelEnabled() && !isFlying && !(myAvatar->getIsInWalkingState()) && myAvatar->getHMDLeanRecenterEnabled()) {
|
||||
// then we use center of gravity model
|
||||
hipsMat = myAvatar->deriveBodyUsingCgModel();
|
||||
} else {
|
||||
|
|
|
@ -11,12 +11,12 @@
|
|||
|
||||
#include "AvatarMotionState.h"
|
||||
|
||||
static xColor getLoadingOrbColor(Avatar::LoadingStatus loadingStatus) {
|
||||
static glm::u8vec3 getLoadingOrbColor(Avatar::LoadingStatus loadingStatus) {
|
||||
|
||||
const xColor NO_MODEL_COLOR(0xe3, 0xe3, 0xe3);
|
||||
const xColor LOAD_MODEL_COLOR(0xef, 0x93, 0xd1);
|
||||
const xColor LOAD_SUCCESS_COLOR(0x1f, 0xc6, 0xa6);
|
||||
const xColor LOAD_FAILURE_COLOR(0xc6, 0x21, 0x47);
|
||||
const glm::u8vec3 NO_MODEL_COLOR(0xe3, 0xe3, 0xe3);
|
||||
const glm::u8vec3 LOAD_MODEL_COLOR(0xef, 0x93, 0xd1);
|
||||
const glm::u8vec3 LOAD_SUCCESS_COLOR(0x1f, 0xc6, 0xa6);
|
||||
const glm::u8vec3 LOAD_FAILURE_COLOR(0xc6, 0x21, 0x47);
|
||||
switch (loadingStatus) {
|
||||
case Avatar::LoadingStatus::NoModel:
|
||||
return NO_MODEL_COLOR;
|
||||
|
|
|
@ -76,4 +76,4 @@ protected:
|
|||
bool _includeNormals;
|
||||
};
|
||||
|
||||
#endif // hifi_CollisionPick_h
|
||||
#endif // hifi_CollisionPick_h
|
||||
|
|
|
@ -52,8 +52,7 @@ void ParabolaPointer::editRenderStatePath(const std::string& state, const QVaria
|
|||
if (!pathMap.isEmpty()) {
|
||||
enabled = true;
|
||||
if (pathMap["color"].isValid()) {
|
||||
bool valid;
|
||||
color = toGlm(xColorFromVariant(pathMap["color"], valid));
|
||||
color = toGlm(u8vec3FromVariant(pathMap["color"]));
|
||||
}
|
||||
if (pathMap["alpha"].isValid()) {
|
||||
alpha = pathMap["alpha"].toFloat();
|
||||
|
@ -250,8 +249,7 @@ std::shared_ptr<StartEndRenderState> ParabolaPointer::buildRenderState(const QVa
|
|||
enabled = true;
|
||||
QVariantMap pathMap = propMap["path"].toMap();
|
||||
if (pathMap["color"].isValid()) {
|
||||
bool valid;
|
||||
color = toGlm(xColorFromVariant(pathMap["color"], valid));
|
||||
color = toGlm(u8vec3FromVariant(pathMap["color"]));
|
||||
}
|
||||
|
||||
if (pathMap["alpha"].isValid()) {
|
||||
|
|
|
@ -27,7 +27,7 @@ class StartEndRenderState {
|
|||
public:
|
||||
StartEndRenderState() {}
|
||||
StartEndRenderState(const OverlayID& startID, const OverlayID& endID);
|
||||
virtual ~StartEndRenderState() {}
|
||||
virtual ~StartEndRenderState() = default;
|
||||
|
||||
const OverlayID& getStartID() const { return _startID; }
|
||||
const OverlayID& getEndID() const { return _endID; }
|
||||
|
|
|
@ -421,7 +421,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
|
|||
auto colorVariant = properties["outlineUnoccludedColor"];
|
||||
if (colorVariant.isValid()) {
|
||||
bool isValid;
|
||||
auto color = xColorFromVariant(colorVariant, isValid);
|
||||
auto color = u8vec3FromVariant(colorVariant, isValid);
|
||||
if (isValid) {
|
||||
_style._outlineUnoccluded.color = toGlm(color);
|
||||
}
|
||||
|
@ -429,7 +429,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
|
|||
colorVariant = properties["outlineOccludedColor"];
|
||||
if (colorVariant.isValid()) {
|
||||
bool isValid;
|
||||
auto color = xColorFromVariant(colorVariant, isValid);
|
||||
auto color = u8vec3FromVariant(colorVariant, isValid);
|
||||
if (isValid) {
|
||||
_style._outlineOccluded.color = toGlm(color);
|
||||
}
|
||||
|
@ -437,7 +437,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
|
|||
colorVariant = properties["fillUnoccludedColor"];
|
||||
if (colorVariant.isValid()) {
|
||||
bool isValid;
|
||||
auto color = xColorFromVariant(colorVariant, isValid);
|
||||
auto color = u8vec3FromVariant(colorVariant, isValid);
|
||||
if (isValid) {
|
||||
_style._fillUnoccluded.color = toGlm(color);
|
||||
}
|
||||
|
@ -445,7 +445,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
|
|||
colorVariant = properties["fillOccludedColor"];
|
||||
if (colorVariant.isValid()) {
|
||||
bool isValid;
|
||||
auto color = xColorFromVariant(colorVariant, isValid);
|
||||
auto color = u8vec3FromVariant(colorVariant, isValid);
|
||||
if (isValid) {
|
||||
_style._fillOccluded.color = toGlm(color);
|
||||
}
|
||||
|
@ -497,10 +497,11 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
|
|||
QVariantMap SelectionHighlightStyle::toVariantMap() const {
|
||||
QVariantMap properties;
|
||||
|
||||
properties["outlineUnoccludedColor"] = xColorToVariant(xColorFromGlm(_style._outlineUnoccluded.color));
|
||||
properties["outlineOccludedColor"] = xColorToVariant(xColorFromGlm(_style._outlineOccluded.color));
|
||||
properties["fillUnoccludedColor"] = xColorToVariant(xColorFromGlm(_style._fillUnoccluded.color));
|
||||
properties["fillOccludedColor"] = xColorToVariant(xColorFromGlm(_style._fillOccluded.color));
|
||||
const float MAX_COLOR = 255.0f;
|
||||
properties["outlineUnoccludedColor"] = u8vec3ColortoVariant(_style._outlineUnoccluded.color * MAX_COLOR);
|
||||
properties["outlineOccludedColor"] = u8vec3ColortoVariant(_style._outlineOccluded.color * MAX_COLOR);
|
||||
properties["fillUnoccludedColor"] = u8vec3ColortoVariant(_style._fillUnoccluded.color * MAX_COLOR);
|
||||
properties["fillOccludedColor"] = u8vec3ColortoVariant(_style._fillOccluded.color * MAX_COLOR);
|
||||
|
||||
properties["outlineUnoccludedAlpha"] = _style._outlineUnoccluded.alpha;
|
||||
properties["outlineOccludedAlpha"] = _style._outlineOccluded.alpha;
|
||||
|
|
|
@ -54,6 +54,9 @@ WindowScriptingInterface::WindowScriptingInterface() {
|
|||
});
|
||||
|
||||
connect(qApp->getWindow(), &MainWindow::windowGeometryChanged, this, &WindowScriptingInterface::onWindowGeometryChanged);
|
||||
connect(qApp, &Application::interstitialModeChanged, [this] (bool interstitialMode) {
|
||||
emit interstitialModeChanged(interstitialMode);
|
||||
});
|
||||
}
|
||||
|
||||
WindowScriptingInterface::~WindowScriptingInterface() {
|
||||
|
|
|
@ -619,6 +619,14 @@ signals:
|
|||
*/
|
||||
void redirectErrorStateChanged(bool isInErrorState);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when interstitial mode changes.
|
||||
* @function Window.interstitialModeChanged
|
||||
* @param {bool} interstitialMode - The mode of the interstitial is changed to.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void interstitialModeChanged(bool interstitialMode);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a still snapshot has been taken by calling {@link Window.takeSnapshot|takeSnapshot} with
|
||||
* <code>includeAnimated = false</code> or {@link Window.takeSecondaryCameraSnapshot|takeSecondaryCameraSnapshot}.
|
||||
|
|
|
@ -267,8 +267,8 @@ void Stats::updateStats(bool force) {
|
|||
|
||||
auto loadingRequests = ResourceCache::getLoadingRequests();
|
||||
STAT_UPDATE(downloads, loadingRequests.size());
|
||||
STAT_UPDATE(downloadLimit, ResourceCache::getRequestLimit())
|
||||
STAT_UPDATE(downloadsPending, ResourceCache::getPendingRequestCount());
|
||||
STAT_UPDATE(downloadLimit, (int)ResourceCache::getRequestLimit())
|
||||
STAT_UPDATE(downloadsPending, (int)ResourceCache::getPendingRequestCount());
|
||||
STAT_UPDATE(processing, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
|
||||
STAT_UPDATE(processingPending, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
|
||||
|
||||
|
|
|
@ -191,8 +191,6 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) {
|
|||
|
||||
if (properties["parentID"].isValid()) {
|
||||
setParentID(QUuid(properties["parentID"].toString()));
|
||||
bool success;
|
||||
getParentPointer(success); // call this to hook-up the parent's back-pointers to its child overlays
|
||||
needRenderItemUpdate = true;
|
||||
}
|
||||
if (properties["parentJointIndex"].isValid()) {
|
||||
|
|
|
@ -75,7 +75,6 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
|||
const float FULL_CIRCLE = 360.0f;
|
||||
const float SLICES = 180.0f; // The amount of segment to create the circle
|
||||
const float SLICE_ANGLE_RADIANS = glm::radians(FULL_CIRCLE / SLICES);
|
||||
const float MAX_COLOR = 255.0f;
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
|
||||
|
@ -246,20 +245,15 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
|||
angle += tickMarkAngle;
|
||||
}
|
||||
}
|
||||
|
||||
xColor majorColorX = getMajorTickMarksColor();
|
||||
glm::vec4 majorColor(majorColorX.red / MAX_COLOR, majorColorX.green / MAX_COLOR, majorColorX.blue / MAX_COLOR, alpha);
|
||||
|
||||
|
||||
glm::vec4 majorColor(toGlm(getMajorTickMarksColor()), alpha);
|
||||
geometryCache->updateVertices(_majorTicksVerticesID, majorPoints, majorColor);
|
||||
|
||||
xColor minorColorX = getMinorTickMarksColor();
|
||||
glm::vec4 minorColor(minorColorX.red / MAX_COLOR, minorColorX.green / MAX_COLOR, minorColorX.blue / MAX_COLOR, alpha);
|
||||
|
||||
glm::vec4 minorColor(toGlm(getMinorTickMarksColor()), alpha);
|
||||
geometryCache->updateVertices(_minorTicksVerticesID, minorPoints, minorColor);
|
||||
}
|
||||
|
||||
|
||||
geometryCache->renderVertices(batch, gpu::LINES, _majorTicksVerticesID);
|
||||
|
||||
|
||||
geometryCache->renderVertices(batch, gpu::LINES, _minorTicksVerticesID);
|
||||
}
|
||||
}
|
||||
|
@ -280,8 +274,8 @@ template<typename T> T fromVariant(const QVariant& v, bool& valid) {
|
|||
return qvariant_cast<T>(v);
|
||||
}
|
||||
|
||||
template<> xColor fromVariant(const QVariant& v, bool& valid) {
|
||||
return xColorFromVariant(v, valid);
|
||||
template<> glm::u8vec3 fromVariant(const QVariant& v, bool& valid) {
|
||||
return u8vec3FromVariant(v, valid);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -344,11 +338,11 @@ void Circle3DOverlay::setProperties(const QVariantMap& properties) {
|
|||
_dirty |= updateIfValid(properties, "outerStartAlpha", _outerStartAlpha);
|
||||
_dirty |= updateIfValid(properties, "outerEndAlpha", _outerEndAlpha);
|
||||
|
||||
_dirty |= updateIfValid<xColor>(properties, "color", { _innerStartColor, _innerEndColor, _outerStartColor, _outerEndColor });
|
||||
_dirty |= updateIfValid<xColor>(properties, "startColor", { _innerStartColor, _outerStartColor } );
|
||||
_dirty |= updateIfValid<xColor>(properties, "endColor", { _innerEndColor, _outerEndColor } );
|
||||
_dirty |= updateIfValid<xColor>(properties, "innerColor", { _innerStartColor, _innerEndColor } );
|
||||
_dirty |= updateIfValid<xColor>(properties, "outerColor", { _outerStartColor, _outerEndColor } );
|
||||
_dirty |= updateIfValid<glm::u8vec3>(properties, "color", { _innerStartColor, _innerEndColor, _outerStartColor, _outerEndColor });
|
||||
_dirty |= updateIfValid<glm::u8vec3>(properties, "startColor", { _innerStartColor, _outerStartColor } );
|
||||
_dirty |= updateIfValid<glm::u8vec3>(properties, "endColor", { _innerEndColor, _outerEndColor } );
|
||||
_dirty |= updateIfValid<glm::u8vec3>(properties, "innerColor", { _innerStartColor, _innerEndColor } );
|
||||
_dirty |= updateIfValid<glm::u8vec3>(properties, "outerColor", { _outerStartColor, _outerEndColor } );
|
||||
_dirty |= updateIfValid(properties, "innerStartColor", _innerStartColor);
|
||||
_dirty |= updateIfValid(properties, "innerEndColor", _innerEndColor);
|
||||
_dirty |= updateIfValid(properties, "outerStartColor", _outerStartColor);
|
||||
|
@ -421,7 +415,7 @@ void Circle3DOverlay::setProperties(const QVariantMap& properties) {
|
|||
* @property {number} endAt=360 - The counter-clockwise angle from the overlay's x-axis that drawing ends at, in degrees.
|
||||
* @property {number} outerRadius=1 - The outer radius of the overlay, in meters. Synonym: <code>radius</code>.
|
||||
* @property {number} innerRadius=0 - The inner radius of the overlay, in meters.
|
||||
* @property {Color} color=255,255,255 - The color of the overlay. Setting this value also sets the values of
|
||||
* @property {Color} color=255,255,255 - The color of the overlay. Setting this value also sets the values of
|
||||
* <code>innerStartColor</code>, <code>innerEndColor</code>, <code>outerStartColor</code>, and <code>outerEndColor</code>.
|
||||
* @property {Color} startColor - Sets the values of <code>innerStartColor</code> and <code>outerStartColor</code>.
|
||||
* <em>Write-only.</em>
|
||||
|
@ -478,16 +472,16 @@ QVariant Circle3DOverlay::getProperty(const QString& property) {
|
|||
return _innerRadius;
|
||||
}
|
||||
if (property == "innerStartColor") {
|
||||
return xColorToVariant(_innerStartColor);
|
||||
return u8vec3ColortoVariant(_innerStartColor);
|
||||
}
|
||||
if (property == "innerEndColor") {
|
||||
return xColorToVariant(_innerEndColor);
|
||||
return u8vec3ColortoVariant(_innerEndColor);
|
||||
}
|
||||
if (property == "outerStartColor") {
|
||||
return xColorToVariant(_outerStartColor);
|
||||
return u8vec3ColortoVariant(_outerStartColor);
|
||||
}
|
||||
if (property == "outerEndColor") {
|
||||
return xColorToVariant(_outerEndColor);
|
||||
return u8vec3ColortoVariant(_outerEndColor);
|
||||
}
|
||||
if (property == "innerStartAlpha") {
|
||||
return _innerStartAlpha;
|
||||
|
@ -517,10 +511,10 @@ QVariant Circle3DOverlay::getProperty(const QString& property) {
|
|||
return _minorTickMarksLength;
|
||||
}
|
||||
if (property == "majorTickMarksColor") {
|
||||
return xColorToVariant(_majorTickMarksColor);
|
||||
return u8vec3ColortoVariant(_majorTickMarksColor);
|
||||
}
|
||||
if (property == "minorTickMarksColor") {
|
||||
return xColorToVariant(_minorTickMarksColor);
|
||||
return u8vec3ColortoVariant(_minorTickMarksColor);
|
||||
}
|
||||
|
||||
return Planar3DOverlay::getProperty(property);
|
||||
|
|
|
@ -39,8 +39,8 @@ public:
|
|||
float getMinorTickMarksAngle() const { return _minorTickMarksAngle; }
|
||||
float getMajorTickMarksLength() const { return _majorTickMarksLength; }
|
||||
float getMinorTickMarksLength() const { return _minorTickMarksLength; }
|
||||
xColor getMajorTickMarksColor() const { return _majorTickMarksColor; }
|
||||
xColor getMinorTickMarksColor() const { return _minorTickMarksColor; }
|
||||
glm::u8vec3 getMajorTickMarksColor() const { return _majorTickMarksColor; }
|
||||
glm::u8vec3 getMinorTickMarksColor() const { return _minorTickMarksColor; }
|
||||
|
||||
void setStartAt(float value) { _startAt = value; }
|
||||
void setEndAt(float value) { _endAt = value; }
|
||||
|
@ -51,8 +51,8 @@ public:
|
|||
void setMinorTickMarksAngle(float value) { _minorTickMarksAngle = value; }
|
||||
void setMajorTickMarksLength(float value) { _majorTickMarksLength = value; }
|
||||
void setMinorTickMarksLength(float value) { _minorTickMarksLength = value; }
|
||||
void setMajorTickMarksColor(const xColor& value) { _majorTickMarksColor = value; }
|
||||
void setMinorTickMarksColor(const xColor& value) { _minorTickMarksColor = value; }
|
||||
void setMajorTickMarksColor(const glm::u8vec3& value) { _majorTickMarksColor = value; }
|
||||
void setMinorTickMarksColor(const glm::u8vec3& value) { _minorTickMarksColor = value; }
|
||||
|
||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal, bool precisionPicking = false) override;
|
||||
|
@ -67,10 +67,10 @@ protected:
|
|||
float _outerRadius { 1 };
|
||||
float _innerRadius { 0 };
|
||||
|
||||
xColor _innerStartColor { DEFAULT_OVERLAY_COLOR };
|
||||
xColor _innerEndColor { DEFAULT_OVERLAY_COLOR };
|
||||
xColor _outerStartColor { DEFAULT_OVERLAY_COLOR };
|
||||
xColor _outerEndColor { DEFAULT_OVERLAY_COLOR };
|
||||
glm::u8vec3 _innerStartColor { DEFAULT_OVERLAY_COLOR };
|
||||
glm::u8vec3 _innerEndColor { DEFAULT_OVERLAY_COLOR };
|
||||
glm::u8vec3 _outerStartColor { DEFAULT_OVERLAY_COLOR };
|
||||
glm::u8vec3 _outerEndColor { DEFAULT_OVERLAY_COLOR };
|
||||
float _innerStartAlpha { DEFAULT_ALPHA };
|
||||
float _innerEndAlpha { DEFAULT_ALPHA };
|
||||
float _outerStartAlpha { DEFAULT_ALPHA };
|
||||
|
@ -81,8 +81,8 @@ protected:
|
|||
float _minorTickMarksAngle { 0 };
|
||||
float _majorTickMarksLength { 0 };
|
||||
float _minorTickMarksLength { 0 };
|
||||
xColor _majorTickMarksColor { DEFAULT_OVERLAY_COLOR };
|
||||
xColor _minorTickMarksColor { DEFAULT_OVERLAY_COLOR };
|
||||
glm::u8vec3 _majorTickMarksColor { DEFAULT_OVERLAY_COLOR };
|
||||
glm::u8vec3 _minorTickMarksColor { DEFAULT_OVERLAY_COLOR };
|
||||
gpu::Primitive _solidPrimitive { gpu::TRIANGLE_FAN };
|
||||
int _quadVerticesID { 0 };
|
||||
int _lineVerticesID { 0 };
|
||||
|
|
|
@ -83,7 +83,7 @@ ContextOverlayInterface::ContextOverlayInterface() {
|
|||
_challengeOwnershipTimeoutTimer.setSingleShot(true);
|
||||
}
|
||||
|
||||
static const xColor CONTEXT_OVERLAY_COLOR = { 255, 255, 255 };
|
||||
static const glm::u8vec3 CONTEXT_OVERLAY_COLOR = { 255, 255, 255 };
|
||||
static const float CONTEXT_OVERLAY_INSIDE_DISTANCE = 1.0f; // in meters
|
||||
static const float CONTEXT_OVERLAY_SIZE = 0.09f; // in meters, same x and y dims
|
||||
static const float CONTEXT_OVERLAY_OFFSET_DISTANCE = 0.1f;
|
||||
|
@ -142,14 +142,15 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID&
|
|||
glm::vec3 cameraPosition = qApp->getCamera().getPosition();
|
||||
glm::vec3 entityDimensions = entityProperties.getDimensions();
|
||||
glm::vec3 entityPosition = entityProperties.getPosition();
|
||||
glm::vec3 registrationPoint = entityProperties.getRegistrationPoint();
|
||||
glm::vec3 contextOverlayPosition = entityProperties.getPosition();
|
||||
glm::vec2 contextOverlayDimensions;
|
||||
|
||||
// Update the position of the overlay if the registration point of the entity
|
||||
// isn't default
|
||||
if (entityProperties.getRegistrationPoint() != glm::vec3(0.5f)) {
|
||||
glm::vec3 adjustPos = entityProperties.getRegistrationPoint() - glm::vec3(0.5f);
|
||||
entityPosition = entityPosition - (entityProperties.getRotation() * (adjustPos * entityProperties.getDimensions()));
|
||||
if (registrationPoint != glm::vec3(0.5f)) {
|
||||
glm::vec3 adjustPos = registrationPoint - glm::vec3(0.5f);
|
||||
entityPosition = entityPosition - (entityProperties.getRotation() * (adjustPos * entityDimensions));
|
||||
}
|
||||
|
||||
enableEntityHighlight(entityItemID);
|
||||
|
|
|
@ -49,11 +49,8 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
float alpha = getAlpha();
|
||||
xColor color = getColor();
|
||||
const float MAX_COLOR = 255.0f;
|
||||
glm::vec4 cubeColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
||||
|
||||
|
||||
glm::u8vec3 color = getColor();
|
||||
glm::vec4 cubeColor(toGlm(color), alpha);
|
||||
|
||||
auto batch = args->_batch;
|
||||
if (batch) {
|
||||
|
|
|
@ -57,11 +57,9 @@ void Grid3DOverlay::render(RenderArgs* args) {
|
|||
return; // do nothing if we're not visible
|
||||
}
|
||||
|
||||
const float MAX_COLOR = 255.0f;
|
||||
|
||||
float alpha = getAlpha();
|
||||
xColor color = getColor();
|
||||
glm::vec4 gridColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
||||
glm::u8vec3 color = getColor();
|
||||
glm::vec4 gridColor(toGlm(color), alpha);
|
||||
|
||||
auto batch = args->_batch;
|
||||
|
||||
|
|
|
@ -107,17 +107,16 @@ void Image3DOverlay::render(RenderArgs* args) {
|
|||
glm::vec2 texCoordBottomRight((fromImage.x() + fromImage.width() - 0.5f) / imageWidth,
|
||||
(fromImage.y() + fromImage.height() - 0.5f) / imageHeight);
|
||||
|
||||
const float MAX_COLOR = 255.0f;
|
||||
xColor color = getColor();
|
||||
float alpha = getAlpha();
|
||||
glm::u8vec3 color = getColor();
|
||||
glm::vec4 imageColor(toGlm(color), alpha);
|
||||
|
||||
batch->setModelTransform(getRenderTransform());
|
||||
batch->setResourceTexture(0, _texture->getGPUTexture());
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(
|
||||
*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
||||
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha),
|
||||
_geometryId
|
||||
imageColor, _geometryId
|
||||
);
|
||||
|
||||
batch->setResourceTexture(0, nullptr); // restore default white color after me
|
||||
|
|
|
@ -128,9 +128,8 @@ void Line3DOverlay::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
float alpha = getAlpha();
|
||||
xColor color = getColor();
|
||||
const float MAX_COLOR = 255.0f;
|
||||
glm::vec4 colorv4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
||||
glm::u8vec3 color = getColor();
|
||||
glm::vec4 colorv4(toGlm(color), alpha);
|
||||
auto batch = args->_batch;
|
||||
if (batch) {
|
||||
batch->setModelTransform(Transform());
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include "Application.h"
|
||||
|
||||
const xColor Overlay::DEFAULT_OVERLAY_COLOR = { 255, 255, 255 };
|
||||
const glm::u8vec3 Overlay::DEFAULT_OVERLAY_COLOR = { 255, 255, 255 };
|
||||
const float Overlay::DEFAULT_ALPHA = 0.7f;
|
||||
|
||||
Overlay::Overlay() :
|
||||
|
@ -57,7 +57,7 @@ Overlay::~Overlay() {
|
|||
|
||||
void Overlay::setProperties(const QVariantMap& properties) {
|
||||
bool valid;
|
||||
auto color = xColorFromVariant(properties["color"], valid);
|
||||
auto color = u8vec3FromVariant(properties["color"], valid);
|
||||
if (valid) {
|
||||
_color = color;
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ QVariant Overlay::getProperty(const QString& property) {
|
|||
return QVariant(getType());
|
||||
}
|
||||
if (property == "color") {
|
||||
return xColorToVariant(_color);
|
||||
return u8vec3ColortoVariant(_color);
|
||||
}
|
||||
if (property == "alpha") {
|
||||
return _alpha;
|
||||
|
@ -143,21 +143,21 @@ QVariant Overlay::getProperty(const QString& property) {
|
|||
return QVariant();
|
||||
}
|
||||
|
||||
xColor Overlay::getColor() {
|
||||
glm::u8vec3 Overlay::getColor() {
|
||||
if (_colorPulse == 0.0f) {
|
||||
return _color;
|
||||
}
|
||||
|
||||
float pulseLevel = updatePulse();
|
||||
xColor result = _color;
|
||||
glm::u8vec3 result = _color;
|
||||
if (_colorPulse < 0.0f) {
|
||||
result.red *= (1.0f - pulseLevel);
|
||||
result.green *= (1.0f - pulseLevel);
|
||||
result.blue *= (1.0f - pulseLevel);
|
||||
result.x *= (1.0f - pulseLevel);
|
||||
result.y *= (1.0f - pulseLevel);
|
||||
result.z *= (1.0f - pulseLevel);
|
||||
} else {
|
||||
result.red *= pulseLevel;
|
||||
result.green *= pulseLevel;
|
||||
result.blue *= pulseLevel;
|
||||
result.x *= pulseLevel;
|
||||
result.y *= pulseLevel;
|
||||
result.z *= pulseLevel;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
#ifndef hifi_Overlay_h
|
||||
#define hifi_Overlay_h
|
||||
|
||||
// include this before QGLWidget, which includes an earlier version of OpenGL
|
||||
#include <SharedUtil.h> // for xColor
|
||||
#include <render/Scene.h>
|
||||
|
||||
class OverlayID : public QUuid {
|
||||
|
@ -59,7 +57,7 @@ public:
|
|||
virtual bool isTransparent() { return getAlphaPulse() != 0.0f || getAlpha() != 1.0f; };
|
||||
virtual bool getIsVisibleInSecondaryCamera() const { return false; }
|
||||
|
||||
xColor getColor();
|
||||
glm::u8vec3 getColor();
|
||||
float getAlpha();
|
||||
|
||||
float getPulseMax() const { return _pulseMax; }
|
||||
|
@ -73,7 +71,7 @@ public:
|
|||
// setters
|
||||
virtual void setVisible(bool visible) { _visible = visible; }
|
||||
void setDrawHUDLayer(bool drawHUDLayer);
|
||||
void setColor(const xColor& color) { _color = color; }
|
||||
void setColor(const glm::u8vec3& color) { _color = color; }
|
||||
void setAlpha(float alpha) { _alpha = alpha; }
|
||||
|
||||
void setPulseMax(float value) { _pulseMax = value; }
|
||||
|
@ -115,12 +113,12 @@ protected:
|
|||
float _alphaPulse; // ratio of the pulse to the alpha
|
||||
float _colorPulse; // ratio of the pulse to the color
|
||||
|
||||
xColor _color;
|
||||
glm::u8vec3 _color;
|
||||
bool _visible; // should the overlay be drawn at all
|
||||
|
||||
unsigned int _stackOrder { 0 };
|
||||
|
||||
static const xColor DEFAULT_OVERLAY_COLOR;
|
||||
static const glm::u8vec3 DEFAULT_OVERLAY_COLOR;
|
||||
static const float DEFAULT_ALPHA;
|
||||
|
||||
std::unordered_map<std::string, graphics::MultiMaterial> _materials;
|
||||
|
|
|
@ -532,6 +532,8 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionVector(const PickRay
|
|||
bool visibleOnly, bool collidableOnly) {
|
||||
float bestDistance = std::numeric_limits<float>::max();
|
||||
bool bestIsFront = false;
|
||||
bool bestIsTablet = false;
|
||||
auto tabletIDs = qApp->getTabletIDs();
|
||||
|
||||
QMutexLocker locker(&_mutex);
|
||||
RayToOverlayIntersectionResult result;
|
||||
|
@ -554,10 +556,11 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionVector(const PickRay
|
|||
if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance,
|
||||
thisFace, thisSurfaceNormal, thisExtraInfo, precisionPicking)) {
|
||||
bool isDrawInFront = thisOverlay->getDrawInFront();
|
||||
if ((bestIsFront && isDrawInFront && thisDistance < bestDistance)
|
||||
|| (!bestIsFront && (isDrawInFront || thisDistance < bestDistance))) {
|
||||
|
||||
bool isTablet = tabletIDs.contains(thisID);
|
||||
if ((isDrawInFront && !bestIsFront && !bestIsTablet)
|
||||
|| ((isTablet || isDrawInFront || !bestIsFront) && thisDistance < bestDistance)) {
|
||||
bestIsFront = isDrawInFront;
|
||||
bestIsTablet = isTablet;
|
||||
bestDistance = thisDistance;
|
||||
result.intersects = true;
|
||||
result.distance = thisDistance;
|
||||
|
@ -629,9 +632,9 @@ QScriptValue RayToOverlayIntersectionResultToScriptValue(QScriptEngine* engine,
|
|||
obj.setProperty("distance", value.distance);
|
||||
obj.setProperty("face", boxFaceToString(value.face));
|
||||
|
||||
QScriptValue intersection = vec3toScriptValue(engine, value.intersection);
|
||||
QScriptValue intersection = vec3ToScriptValue(engine, value.intersection);
|
||||
obj.setProperty("intersection", intersection);
|
||||
QScriptValue surfaceNormal = vec3toScriptValue(engine, value.surfaceNormal);
|
||||
QScriptValue surfaceNormal = vec3ToScriptValue(engine, value.surfaceNormal);
|
||||
obj.setProperty("surfaceNormal", surfaceNormal);
|
||||
obj.setProperty("extraInfo", engine->toScriptValue(value.extraInfo));
|
||||
return obj;
|
||||
|
@ -828,40 +831,12 @@ PointerEvent Overlays::calculateOverlayPointerEvent(OverlayID overlayID, PickRay
|
|||
}
|
||||
|
||||
|
||||
RayToOverlayIntersectionResult Overlays::findRayIntersectionForMouseEvent(PickRay ray) {
|
||||
QVector<OverlayID> overlaysToInclude;
|
||||
QVector<OverlayID> overlaysToDiscard;
|
||||
RayToOverlayIntersectionResult rayPickResult;
|
||||
|
||||
// first priority is tablet screen
|
||||
overlaysToInclude << qApp->getTabletScreenID();
|
||||
rayPickResult = findRayIntersectionVector(ray, true, overlaysToInclude, overlaysToDiscard);
|
||||
if (rayPickResult.intersects) {
|
||||
return rayPickResult;
|
||||
}
|
||||
// then tablet home button
|
||||
overlaysToInclude.clear();
|
||||
overlaysToInclude << qApp->getTabletHomeButtonID();
|
||||
rayPickResult = findRayIntersectionVector(ray, true, overlaysToInclude, overlaysToDiscard);
|
||||
if (rayPickResult.intersects) {
|
||||
return rayPickResult;
|
||||
}
|
||||
// then tablet frame
|
||||
overlaysToInclude.clear();
|
||||
overlaysToInclude << OverlayID(qApp->getTabletFrameID());
|
||||
rayPickResult = findRayIntersectionVector(ray, true, overlaysToInclude, overlaysToDiscard);
|
||||
if (rayPickResult.intersects) {
|
||||
return rayPickResult;
|
||||
}
|
||||
// then whatever
|
||||
return findRayIntersection(ray);
|
||||
}
|
||||
|
||||
bool Overlays::mousePressEvent(QMouseEvent* event) {
|
||||
PerformanceTimer perfTimer("Overlays::mousePressEvent");
|
||||
|
||||
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray);
|
||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(),
|
||||
QVector<OverlayID>());
|
||||
if (rayPickResult.intersects) {
|
||||
_currentClickingOnOverlayID = rayPickResult.overlayID;
|
||||
|
||||
|
@ -901,7 +876,8 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) {
|
|||
PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent");
|
||||
|
||||
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray);
|
||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(),
|
||||
QVector<OverlayID>());
|
||||
if (rayPickResult.intersects) {
|
||||
_currentClickingOnOverlayID = rayPickResult.overlayID;
|
||||
|
||||
|
@ -964,7 +940,8 @@ bool Overlays::mouseReleaseEvent(QMouseEvent* event) {
|
|||
PerformanceTimer perfTimer("Overlays::mouseReleaseEvent");
|
||||
|
||||
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray);
|
||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(),
|
||||
QVector<OverlayID>());
|
||||
if (rayPickResult.intersects) {
|
||||
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release);
|
||||
mouseReleasePointerEvent(rayPickResult.overlayID, pointerEvent);
|
||||
|
@ -993,7 +970,8 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) {
|
|||
PerformanceTimer perfTimer("Overlays::mouseMoveEvent");
|
||||
|
||||
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray);
|
||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(),
|
||||
QVector<OverlayID>());
|
||||
if (rayPickResult.intersects) {
|
||||
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move);
|
||||
mouseMovePointerEvent(rayPickResult.overlayID, pointerEvent);
|
||||
|
|
|
@ -44,8 +44,7 @@ void OverlayPropertyResultFromScriptValue(const QScriptValue& object, OverlayPro
|
|||
const OverlayID UNKNOWN_OVERLAY_ID = OverlayID();
|
||||
|
||||
/**jsdoc
|
||||
* The result of a {@link PickRay} search using {@link Overlays.findRayIntersection|findRayIntersection} or
|
||||
* {@link Overlays.findRayIntersectionVector|findRayIntersectionVector}.
|
||||
* The result of a {@link PickRay} search using {@link Overlays.findRayIntersection|findRayIntersection}.
|
||||
* @typedef {object} Overlays.RayToOverlayIntersectionResult
|
||||
* @property {boolean} intersects - <code>true</code> if the {@link PickRay} intersected with a 3D overlay, otherwise
|
||||
* <code>false</code>.
|
||||
|
@ -383,7 +382,11 @@ public slots:
|
|||
OverlayPropertyResult getOverlaysProperties(const QVariant& overlaysProperties);
|
||||
|
||||
/**jsdoc
|
||||
* Find the closest 3D overlay intersected by a {@link PickRay}.
|
||||
* Find the closest 3D overlay intersected by a {@link PickRay}. Overlays with their <code>drawInFront</code> property set
|
||||
* to <code>true</code> have priority over overlays that don't, except that tablet overlays have priority over any
|
||||
* <code>drawInFront</code> overlays behind them. I.e., if a <code>drawInFront</code> overlay is behind one that isn't
|
||||
* <code>drawInFront</code>, the <code>drawInFront</code> overlay is returned, but if a tablet overlay is in front of a
|
||||
* <code>drawInFront</code> overlay, the tablet overlay is returned.
|
||||
* @function Overlays.findRayIntersection
|
||||
* @param {PickRay} pickRay - The PickRay to use for finding overlays.
|
||||
* @param {boolean} [precisionPicking=false] - <em>Unused</em>; exists to match Entity API.
|
||||
|
@ -750,8 +753,6 @@ private:
|
|||
OverlayID _currentClickingOnOverlayID { UNKNOWN_OVERLAY_ID };
|
||||
OverlayID _currentHoverOverOverlayID { UNKNOWN_OVERLAY_ID };
|
||||
|
||||
RayToOverlayIntersectionResult findRayIntersectionForMouseEvent(PickRay ray);
|
||||
|
||||
private slots:
|
||||
void mousePressPointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||
void mouseMovePointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||
|
|
|
@ -64,7 +64,7 @@ void Planar3DOverlay::setProperties(const QVariantMap& properties) {
|
|||
*/
|
||||
QVariant Planar3DOverlay::getProperty(const QString& property) {
|
||||
if (property == "dimensions" || property == "scale" || property == "size") {
|
||||
return vec2toVariant(getDimensions());
|
||||
return vec2ToVariant(getDimensions());
|
||||
}
|
||||
|
||||
return Base3DOverlay::getProperty(property);
|
||||
|
|
|
@ -51,9 +51,8 @@ void Rectangle3DOverlay::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
float alpha = getAlpha();
|
||||
xColor color = getColor();
|
||||
const float MAX_COLOR = 255.0f;
|
||||
glm::vec4 rectangleColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
||||
glm::u8vec3 color = getColor();
|
||||
glm::vec4 rectangleColor(toGlm(color), alpha);
|
||||
|
||||
auto batch = args->_batch;
|
||||
if (batch) {
|
||||
|
|
|
@ -30,9 +30,8 @@ void Shape3DOverlay::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
float alpha = getAlpha();
|
||||
xColor color = getColor();
|
||||
const float MAX_COLOR = 255.0f;
|
||||
glm::vec4 cubeColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
||||
glm::u8vec3 color = getColor();
|
||||
glm::vec4 shapeColor(toGlm(color), alpha);
|
||||
|
||||
auto batch = args->_batch;
|
||||
if (batch) {
|
||||
|
@ -44,9 +43,9 @@ void Shape3DOverlay::render(RenderArgs* args) {
|
|||
|
||||
batch->setModelTransform(getRenderTransform());
|
||||
if (_isSolid) {
|
||||
geometryCache->renderSolidShapeInstance(args, *batch, _shape, cubeColor, shapePipeline);
|
||||
geometryCache->renderSolidShapeInstance(args, *batch, _shape, shapeColor, shapePipeline);
|
||||
} else {
|
||||
geometryCache->renderWireShapeInstance(args, *batch, _shape, cubeColor, shapePipeline);
|
||||
geometryCache->renderWireShapeInstance(args, *batch, _shape, shapeColor, shapePipeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,9 +77,8 @@ void Sphere3DOverlay::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
float alpha = getAlpha();
|
||||
xColor color = getColor();
|
||||
const float MAX_COLOR = 255.0f;
|
||||
glm::vec4 sphereColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
||||
glm::u8vec3 color = getColor();
|
||||
glm::vec4 sphereColor(toGlm(color), alpha);
|
||||
|
||||
auto batch = args->_batch;
|
||||
|
||||
|
|
|
@ -64,21 +64,21 @@ void Text3DOverlay::setText(const QString& text) {
|
|||
_text = text;
|
||||
}
|
||||
|
||||
xColor Text3DOverlay::getBackgroundColor() {
|
||||
glm::u8vec3 Text3DOverlay::getBackgroundColor() {
|
||||
if (_colorPulse == 0.0f) {
|
||||
return _backgroundColor;
|
||||
}
|
||||
|
||||
float pulseLevel = updatePulse();
|
||||
xColor result = _backgroundColor;
|
||||
glm::u8vec3 result = _backgroundColor;
|
||||
if (_colorPulse < 0.0f) {
|
||||
result.red *= (1.0f - pulseLevel);
|
||||
result.green *= (1.0f - pulseLevel);
|
||||
result.blue *= (1.0f - pulseLevel);
|
||||
result.x *= (1.0f - pulseLevel);
|
||||
result.y *= (1.0f - pulseLevel);
|
||||
result.z *= (1.0f - pulseLevel);
|
||||
} else {
|
||||
result.red *= pulseLevel;
|
||||
result.green *= pulseLevel;
|
||||
result.blue *= pulseLevel;
|
||||
result.x *= pulseLevel;
|
||||
result.y *= pulseLevel;
|
||||
result.z *= pulseLevel;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -94,10 +94,8 @@ void Text3DOverlay::render(RenderArgs* args) {
|
|||
auto transform = getRenderTransform();
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
const float MAX_COLOR = 255.0f;
|
||||
xColor backgroundColor = getBackgroundColor();
|
||||
glm::vec4 quadColor(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR,
|
||||
backgroundColor.blue / MAX_COLOR, getBackgroundAlpha());
|
||||
glm::u8vec3 backgroundColor = getBackgroundColor();
|
||||
glm::vec4 quadColor(toGlm(backgroundColor), getBackgroundAlpha());
|
||||
|
||||
glm::vec2 dimensions = getDimensions();
|
||||
glm::vec2 halfDimensions = dimensions * 0.5f;
|
||||
|
@ -122,8 +120,7 @@ void Text3DOverlay::render(RenderArgs* args) {
|
|||
transform.setScale(scaleFactor);
|
||||
batch.setModelTransform(transform);
|
||||
|
||||
glm::vec4 textColor = { _color.red / MAX_COLOR, _color.green / MAX_COLOR,
|
||||
_color.blue / MAX_COLOR, getTextAlpha() };
|
||||
glm::vec4 textColor = { toGlm(_color), getTextAlpha() };
|
||||
|
||||
// FIXME: Factor out textRenderer so that Text3DOverlay overlay parts can be grouped by pipeline for a gpu performance increase.
|
||||
_textRenderer->draw(batch, 0, 0, getText(), textColor, glm::vec2(-1.0f), true);
|
||||
|
@ -164,7 +161,7 @@ void Text3DOverlay::setProperties(const QVariantMap& properties) {
|
|||
bool valid;
|
||||
auto backgroundColor = properties["backgroundColor"];
|
||||
if (backgroundColor.isValid()) {
|
||||
auto color = xColorFromVariant(backgroundColor, valid);
|
||||
auto color = u8vec3FromVariant(backgroundColor, valid);
|
||||
if (valid) {
|
||||
_backgroundColor = color;
|
||||
}
|
||||
|
@ -260,7 +257,7 @@ QVariant Text3DOverlay::getProperty(const QString& property) {
|
|||
return _textAlpha;
|
||||
}
|
||||
if (property == "backgroundColor") {
|
||||
return xColorToVariant(_backgroundColor);
|
||||
return u8vec3ColortoVariant(_backgroundColor);
|
||||
}
|
||||
if (property == "backgroundAlpha") {
|
||||
return Billboard3DOverlay::getProperty("alpha");
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
float getTopMargin() const { return _topMargin; }
|
||||
float getRightMargin() const { return _rightMargin; }
|
||||
float getBottomMargin() const { return _bottomMargin; }
|
||||
xColor getBackgroundColor();
|
||||
glm::u8vec3 getBackgroundColor();
|
||||
float getTextAlpha() { return _textAlpha; }
|
||||
float getBackgroundAlpha() { return getAlpha(); }
|
||||
bool isTransparent() override { return Overlay::isTransparent() || _textAlpha < 1.0f; }
|
||||
|
@ -65,7 +65,7 @@ private:
|
|||
|
||||
QString _text;
|
||||
mutable QMutex _mutex; // used to make get/setText threadsafe, mutable so can be used in const functions
|
||||
xColor _backgroundColor = xColor { 0, 0, 0 };
|
||||
glm::u8vec3 _backgroundColor { 0, 0, 0 };
|
||||
float _textAlpha { 1.0f };
|
||||
float _lineHeight { 1.0f };
|
||||
float _leftMargin { 0.1f };
|
||||
|
|
|
@ -40,7 +40,7 @@ QScriptValue AnimVariantMap::animVariantMapToScriptValue(QScriptEngine* engine,
|
|||
target.setProperty(name, value.getString());
|
||||
break;
|
||||
case AnimVariant::Type::Vec3:
|
||||
target.setProperty(name, vec3toScriptValue(engine, value.getVec3()));
|
||||
target.setProperty(name, vec3ToScriptValue(engine, value.getVec3()));
|
||||
break;
|
||||
case AnimVariant::Type::Quat:
|
||||
target.setProperty(name, quatToScriptValue(engine, value.getQuat()));
|
||||
|
@ -169,7 +169,8 @@ std::map<QString, QString> AnimVariantMap::toDebugMap() const {
|
|||
break;
|
||||
*/
|
||||
default:
|
||||
assert(("invalid AnimVariant::Type", false));
|
||||
// invalid AnimVariant::Type
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -32,12 +32,6 @@ AnimationCache::AnimationCache(QObject* parent) :
|
|||
}
|
||||
|
||||
AnimationPointer AnimationCache::getAnimation(const QUrl& url) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
AnimationPointer result;
|
||||
BLOCKING_INVOKE_METHOD(this, "getAnimation",
|
||||
Q_RETURN_ARG(AnimationPointer, result), Q_ARG(const QUrl&, url));
|
||||
return result;
|
||||
}
|
||||
return getResource(url).staticCast<Animation>();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
class Animation;
|
||||
|
||||
typedef QSharedPointer<Animation> AnimationPointer;
|
||||
using AnimationPointer = QSharedPointer<Animation>;
|
||||
|
||||
class AnimationCache : public ResourceCache, public Dependency {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -1345,7 +1345,6 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab
|
|||
const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix) {
|
||||
|
||||
const bool ENABLE_POLE_VECTORS = true;
|
||||
const float ELBOW_POLE_VECTOR_BLEND_FACTOR = 0.95f;
|
||||
|
||||
if (leftHandEnabled) {
|
||||
|
||||
|
@ -1371,33 +1370,16 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab
|
|||
bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector);
|
||||
if (usePoleVector) {
|
||||
glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector);
|
||||
|
||||
if (_smoothPoleVectors) {
|
||||
// smooth toward desired pole vector from previous pole vector... to reduce jitter
|
||||
if (!_prevLeftHandPoleVectorValid) {
|
||||
_prevLeftHandPoleVectorValid = true;
|
||||
_prevLeftHandPoleVector = sensorPoleVector;
|
||||
}
|
||||
glm::quat deltaRot = rotationBetween(_prevLeftHandPoleVector, sensorPoleVector);
|
||||
glm::quat smoothDeltaRot = safeMix(deltaRot, Quaternions::IDENTITY, ELBOW_POLE_VECTOR_BLEND_FACTOR);
|
||||
_prevLeftHandPoleVector = smoothDeltaRot * _prevLeftHandPoleVector;
|
||||
} else {
|
||||
_prevLeftHandPoleVector = sensorPoleVector;
|
||||
}
|
||||
_animVars.set("leftHandPoleVectorEnabled", true);
|
||||
_animVars.set("leftHandPoleReferenceVector", Vectors::UNIT_X);
|
||||
_animVars.set("leftHandPoleVector", transformVectorFast(sensorToRigMatrix, _prevLeftHandPoleVector));
|
||||
_animVars.set("leftHandPoleVector", transformVectorFast(sensorToRigMatrix, sensorPoleVector));
|
||||
} else {
|
||||
_prevLeftHandPoleVectorValid = false;
|
||||
_animVars.set("leftHandPoleVectorEnabled", false);
|
||||
}
|
||||
|
||||
} else {
|
||||
_prevLeftHandPoleVectorValid = false;
|
||||
_animVars.set("leftHandPoleVectorEnabled", false);
|
||||
}
|
||||
} else {
|
||||
_prevLeftHandPoleVectorValid = false;
|
||||
_animVars.set("leftHandPoleVectorEnabled", false);
|
||||
|
||||
_animVars.unset("leftHandPosition");
|
||||
|
@ -1436,33 +1418,16 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab
|
|||
bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector);
|
||||
if (usePoleVector) {
|
||||
glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector);
|
||||
|
||||
if (_smoothPoleVectors) {
|
||||
// smooth toward desired pole vector from previous pole vector... to reduce jitter
|
||||
if (!_prevRightHandPoleVectorValid) {
|
||||
_prevRightHandPoleVectorValid = true;
|
||||
_prevRightHandPoleVector = sensorPoleVector;
|
||||
}
|
||||
glm::quat deltaRot = rotationBetween(_prevRightHandPoleVector, sensorPoleVector);
|
||||
glm::quat smoothDeltaRot = safeMix(deltaRot, Quaternions::IDENTITY, ELBOW_POLE_VECTOR_BLEND_FACTOR);
|
||||
_prevRightHandPoleVector = smoothDeltaRot * _prevRightHandPoleVector;
|
||||
} else {
|
||||
_prevRightHandPoleVector = sensorPoleVector;
|
||||
}
|
||||
|
||||
_animVars.set("rightHandPoleVectorEnabled", true);
|
||||
_animVars.set("rightHandPoleReferenceVector", -Vectors::UNIT_X);
|
||||
_animVars.set("rightHandPoleVector", transformVectorFast(sensorToRigMatrix, _prevRightHandPoleVector));
|
||||
_animVars.set("rightHandPoleVector", transformVectorFast(sensorToRigMatrix, sensorPoleVector));
|
||||
} else {
|
||||
_prevRightHandPoleVectorValid = false;
|
||||
_animVars.set("rightHandPoleVectorEnabled", false);
|
||||
}
|
||||
} else {
|
||||
_prevRightHandPoleVectorValid = false;
|
||||
_animVars.set("rightHandPoleVectorEnabled", false);
|
||||
}
|
||||
} else {
|
||||
_prevRightHandPoleVectorValid = false;
|
||||
_animVars.set("rightHandPoleVectorEnabled", false);
|
||||
|
||||
_animVars.unset("rightHandPosition");
|
||||
|
|
|
@ -230,7 +230,6 @@ public:
|
|||
const AnimVariantMap& getAnimVars() const { return _lastAnimVars; }
|
||||
const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); }
|
||||
|
||||
void toggleSmoothPoleVectors() { _smoothPoleVectors = !_smoothPoleVectors; };
|
||||
signals:
|
||||
void onLoadComplete();
|
||||
|
||||
|
@ -408,14 +407,6 @@ protected:
|
|||
glm::vec3 _prevLeftFootPoleVector { Vectors::UNIT_Z }; // sensor space
|
||||
bool _prevLeftFootPoleVectorValid { false };
|
||||
|
||||
glm::vec3 _prevRightHandPoleVector{ -Vectors::UNIT_Z }; // sensor space
|
||||
bool _prevRightHandPoleVectorValid{ false };
|
||||
|
||||
glm::vec3 _prevLeftHandPoleVector{ -Vectors::UNIT_Z }; // sensor space
|
||||
bool _prevLeftHandPoleVectorValid{ false };
|
||||
|
||||
bool _smoothPoleVectors { false };
|
||||
|
||||
int _rigId;
|
||||
bool _headEnabled { false };
|
||||
bool _sendNetworkNode { false };
|
||||
|
|
|
@ -34,7 +34,7 @@ AudioInjectorOptions::AudioInjectorOptions() :
|
|||
|
||||
QScriptValue injectorOptionsToScriptValue(QScriptEngine* engine, const AudioInjectorOptions& injectorOptions) {
|
||||
QScriptValue obj = engine->newObject();
|
||||
obj.setProperty("position", vec3toScriptValue(engine, injectorOptions.position));
|
||||
obj.setProperty("position", vec3ToScriptValue(engine, injectorOptions.position));
|
||||
obj.setProperty("volume", injectorOptions.volume);
|
||||
obj.setProperty("loop", injectorOptions.loop);
|
||||
obj.setProperty("orientation", quatToScriptValue(engine, injectorOptions.orientation));
|
||||
|
|
|
@ -30,12 +30,6 @@ SoundCache::SoundCache(QObject* parent) :
|
|||
}
|
||||
|
||||
SharedSoundPointer SoundCache::getSound(const QUrl& url) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
SharedSoundPointer result;
|
||||
BLOCKING_INVOKE_METHOD(this, "getSound",
|
||||
Q_RETURN_ARG(SharedSoundPointer, result), Q_ARG(const QUrl&, url));
|
||||
return result;
|
||||
}
|
||||
return getResource(url).staticCast<Sound>();
|
||||
}
|
||||
|
||||
|
|
|
@ -707,6 +707,19 @@ static TextRenderer3D* textRenderer(TextRendererType type) {
|
|||
return displayNameRenderer;
|
||||
}
|
||||
|
||||
void Avatar::metaBlendshapeOperator(int blendshapeNumber, const QVector<BlendshapeOffset>& blendshapeOffsets, const QVector<int>& blendedMeshSizes,
|
||||
const render::ItemIDs& subItemIDs) {
|
||||
render::Transaction transaction;
|
||||
transaction.updateItem<AvatarData>(_renderItemID, [blendshapeNumber, blendshapeOffsets, blendedMeshSizes,
|
||||
subItemIDs](AvatarData& avatar) {
|
||||
auto avatarPtr = dynamic_cast<Avatar*>(&avatar);
|
||||
if (avatarPtr) {
|
||||
avatarPtr->setBlendedVertices(blendshapeNumber, blendshapeOffsets, blendedMeshSizes, subItemIDs);
|
||||
}
|
||||
});
|
||||
AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction);
|
||||
}
|
||||
|
||||
void Avatar::addToScene(AvatarSharedPointer self, const render::ScenePointer& scene, render::Transaction& transaction) {
|
||||
auto avatarPayload = new render::Payload<AvatarData>(self);
|
||||
auto avatarPayloadPointer = std::shared_ptr<render::Payload<AvatarData>>(avatarPayload);
|
||||
|
@ -716,7 +729,8 @@ void Avatar::addToScene(AvatarSharedPointer self, const render::ScenePointer& sc
|
|||
// INitialize the _render bound as we are creating the avatar render item
|
||||
_renderBound = getBounds();
|
||||
transaction.resetItem(_renderItemID, avatarPayloadPointer);
|
||||
_skeletonModel->addToScene(scene, transaction);
|
||||
using namespace std::placeholders;
|
||||
_skeletonModel->addToScene(scene, transaction, std::bind(&Avatar::metaBlendshapeOperator, this, _1, _2, _3, _4));
|
||||
_skeletonModel->setTagMask(render::hifi::TAG_ALL_VIEWS);
|
||||
_skeletonModel->setGroupCulled(true);
|
||||
_skeletonModel->setCanCastShadow(true);
|
||||
|
@ -795,7 +809,7 @@ void Avatar::updateRenderItem(render::Transaction& transaction) {
|
|||
avatarPtr->_renderBound = renderBound;
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -939,7 +953,8 @@ void Avatar::fixupModelsInScene(const render::ScenePointer& scene) {
|
|||
render::Transaction transaction;
|
||||
if (_skeletonModel->isRenderable() && _skeletonModel->needsFixupInScene()) {
|
||||
_skeletonModel->removeFromScene(scene, transaction);
|
||||
_skeletonModel->addToScene(scene, transaction);
|
||||
using namespace std::placeholders;
|
||||
_skeletonModel->addToScene(scene, transaction, std::bind(&Avatar::metaBlendshapeOperator, this, _1, _2, _3, _4));
|
||||
|
||||
_skeletonModel->setTagMask(render::hifi::TAG_ALL_VIEWS);
|
||||
_skeletonModel->setGroupCulled(true);
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "Rig.h"
|
||||
#include <ThreadSafeValueCache.h>
|
||||
|
||||
#include "MetaModelPayload.h"
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar);
|
||||
template <> const Item::Bound payloadGetBound(const AvatarSharedPointer& avatar);
|
||||
|
@ -115,7 +117,7 @@ private:
|
|||
float _scale { 1.0f };
|
||||
};
|
||||
|
||||
class Avatar : public AvatarData, public scriptable::ModelProvider {
|
||||
class Avatar : public AvatarData, public scriptable::ModelProvider, public MetaModelPayload {
|
||||
Q_OBJECT
|
||||
|
||||
// This property has JSDoc in MyAvatar.h.
|
||||
|
@ -623,6 +625,9 @@ protected:
|
|||
static const float ATTACHMENT_LOADING_PRIORITY;
|
||||
|
||||
LoadingStatus _loadingStatus { LoadingStatus::NoModel };
|
||||
|
||||
void metaBlendshapeOperator(int blendshapeNumber, const QVector<BlendshapeOffset>& blendshapeOffsets, const QVector<int>& blendedMeshSizes,
|
||||
const render::ItemIDs& subItemIDs);
|
||||
};
|
||||
|
||||
#endif // hifi_Avatar_h
|
||||
|
|
|
@ -75,8 +75,11 @@ size_t AvatarDataPacket::maxJointDataSize(size_t numJoints, bool hasGrabJoints)
|
|||
totalSize += numJoints * sizeof(SixByteTrans); // Translations
|
||||
|
||||
size_t NUM_FAUX_JOINT = 2;
|
||||
size_t num_grab_joints = (hasGrabJoints ? 2 : 0);
|
||||
totalSize += (NUM_FAUX_JOINT + num_grab_joints) * (sizeof(SixByteQuat) + sizeof(SixByteTrans)); // faux joints
|
||||
totalSize += NUM_FAUX_JOINT * (sizeof(SixByteQuat) + sizeof(SixByteTrans)); // faux joints
|
||||
|
||||
if (hasGrabJoints) {
|
||||
totalSize += sizeof(AvatarDataPacket::FarGrabJoints);
|
||||
}
|
||||
|
||||
return totalSize;
|
||||
}
|
||||
|
@ -685,7 +688,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
|||
if (hasGrabJoints) {
|
||||
// the far-grab joints may range further than 3 meters, so we can't use packFloatVec3ToSignedTwoByteFixed etc
|
||||
auto startSection = destinationBuffer;
|
||||
auto data = reinterpret_cast<AvatarDataPacket::FarGrabJoints*>(destinationBuffer);
|
||||
|
||||
glm::vec3 leftFarGrabPosition = extractTranslation(leftFarGrabMatrix);
|
||||
glm::quat leftFarGrabRotation = extractRotation(leftFarGrabMatrix);
|
||||
glm::vec3 rightFarGrabPosition = extractTranslation(rightFarGrabMatrix);
|
||||
|
@ -693,28 +696,17 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
|||
glm::vec3 mouseFarGrabPosition = extractTranslation(mouseFarGrabMatrix);
|
||||
glm::quat mouseFarGrabRotation = extractRotation(mouseFarGrabMatrix);
|
||||
|
||||
AVATAR_MEMCPY(leftFarGrabPosition);
|
||||
// Can't do block copy as struct order is x, y, z, w.
|
||||
data->leftFarGrabRotation[0] = leftFarGrabRotation.w;
|
||||
data->leftFarGrabRotation[1] = leftFarGrabRotation.x;
|
||||
data->leftFarGrabRotation[2] = leftFarGrabRotation.y;
|
||||
data->leftFarGrabRotation[3] = leftFarGrabRotation.z;
|
||||
destinationBuffer += sizeof(data->leftFarGrabPosition);
|
||||
|
||||
AVATAR_MEMCPY(rightFarGrabPosition);
|
||||
data->rightFarGrabRotation[0] = rightFarGrabRotation.w;
|
||||
data->rightFarGrabRotation[1] = rightFarGrabRotation.x;
|
||||
data->rightFarGrabRotation[2] = rightFarGrabRotation.y;
|
||||
data->rightFarGrabRotation[3] = rightFarGrabRotation.z;
|
||||
destinationBuffer += sizeof(data->rightFarGrabRotation);
|
||||
|
||||
AVATAR_MEMCPY(mouseFarGrabPosition);
|
||||
data->mouseFarGrabRotation[0] = mouseFarGrabRotation.w;
|
||||
data->mouseFarGrabRotation[1] = mouseFarGrabRotation.x;
|
||||
data->mouseFarGrabRotation[2] = mouseFarGrabRotation.y;
|
||||
data->mouseFarGrabRotation[3] = mouseFarGrabRotation.z;
|
||||
destinationBuffer += sizeof(data->mouseFarGrabRotation);
|
||||
AvatarDataPacket::FarGrabJoints farGrabJoints = {
|
||||
{ leftFarGrabPosition.x, leftFarGrabPosition.y, leftFarGrabPosition.z },
|
||||
{ leftFarGrabRotation.w, leftFarGrabRotation.x, leftFarGrabRotation.y, leftFarGrabRotation.z },
|
||||
{ rightFarGrabPosition.x, rightFarGrabPosition.y, rightFarGrabPosition.z },
|
||||
{ rightFarGrabRotation.w, rightFarGrabRotation.x, rightFarGrabRotation.y, rightFarGrabRotation.z },
|
||||
{ mouseFarGrabPosition.x, mouseFarGrabPosition.y, mouseFarGrabPosition.z },
|
||||
{ mouseFarGrabRotation.w, mouseFarGrabRotation.x, mouseFarGrabRotation.y, mouseFarGrabRotation.z }
|
||||
};
|
||||
|
||||
memcpy(destinationBuffer, &farGrabJoints, sizeof(farGrabJoints));
|
||||
destinationBuffer += sizeof(AvatarDataPacket::FarGrabJoints);
|
||||
int numBytes = destinationBuffer - startSection;
|
||||
|
||||
if (outboundDataRateOut) {
|
||||
|
@ -1247,25 +1239,37 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
|
|||
auto startSection = sourceBuffer;
|
||||
|
||||
PACKET_READ_CHECK(FarGrabJoints, sizeof(AvatarDataPacket::FarGrabJoints));
|
||||
auto data = reinterpret_cast<const AvatarDataPacket::FarGrabJoints*>(sourceBuffer);
|
||||
glm::vec3 leftFarGrabPosition = glm::vec3(data->leftFarGrabPosition[0], data->leftFarGrabPosition[1],
|
||||
data->leftFarGrabPosition[2]);
|
||||
glm::quat leftFarGrabRotation = glm::quat(data->leftFarGrabRotation[0], data->leftFarGrabRotation[1],
|
||||
data->leftFarGrabRotation[2], data->leftFarGrabRotation[3]);
|
||||
glm::vec3 rightFarGrabPosition = glm::vec3(data->rightFarGrabPosition[0], data->rightFarGrabPosition[1],
|
||||
data->rightFarGrabPosition[2]);
|
||||
glm::quat rightFarGrabRotation = glm::quat(data->rightFarGrabRotation[0], data->rightFarGrabRotation[1],
|
||||
data->rightFarGrabRotation[2], data->rightFarGrabRotation[3]);
|
||||
glm::vec3 mouseFarGrabPosition = glm::vec3(data->mouseFarGrabPosition[0], data->mouseFarGrabPosition[1],
|
||||
data->mouseFarGrabPosition[2]);
|
||||
glm::quat mouseFarGrabRotation = glm::quat(data->mouseFarGrabRotation[0], data->mouseFarGrabRotation[1],
|
||||
data->mouseFarGrabRotation[2], data->mouseFarGrabRotation[3]);
|
||||
|
||||
AvatarDataPacket::FarGrabJoints farGrabJoints;
|
||||
memcpy(&farGrabJoints, sourceBuffer, sizeof(farGrabJoints)); // to avoid misaligned floats
|
||||
|
||||
glm::vec3 leftFarGrabPosition = glm::vec3(farGrabJoints.leftFarGrabPosition[0],
|
||||
farGrabJoints.leftFarGrabPosition[1],
|
||||
farGrabJoints.leftFarGrabPosition[2]);
|
||||
glm::quat leftFarGrabRotation = glm::quat(farGrabJoints.leftFarGrabRotation[0],
|
||||
farGrabJoints.leftFarGrabRotation[1],
|
||||
farGrabJoints.leftFarGrabRotation[2],
|
||||
farGrabJoints.leftFarGrabRotation[3]);
|
||||
glm::vec3 rightFarGrabPosition = glm::vec3(farGrabJoints.rightFarGrabPosition[0],
|
||||
farGrabJoints.rightFarGrabPosition[1],
|
||||
farGrabJoints.rightFarGrabPosition[2]);
|
||||
glm::quat rightFarGrabRotation = glm::quat(farGrabJoints.rightFarGrabRotation[0],
|
||||
farGrabJoints.rightFarGrabRotation[1],
|
||||
farGrabJoints.rightFarGrabRotation[2],
|
||||
farGrabJoints.rightFarGrabRotation[3]);
|
||||
glm::vec3 mouseFarGrabPosition = glm::vec3(farGrabJoints.mouseFarGrabPosition[0],
|
||||
farGrabJoints.mouseFarGrabPosition[1],
|
||||
farGrabJoints.mouseFarGrabPosition[2]);
|
||||
glm::quat mouseFarGrabRotation = glm::quat(farGrabJoints.mouseFarGrabRotation[0],
|
||||
farGrabJoints.mouseFarGrabRotation[1],
|
||||
farGrabJoints.mouseFarGrabRotation[2],
|
||||
farGrabJoints.mouseFarGrabRotation[3]);
|
||||
|
||||
_farGrabLeftMatrixCache.set(createMatFromQuatAndPos(leftFarGrabRotation, leftFarGrabPosition));
|
||||
_farGrabRightMatrixCache.set(createMatFromQuatAndPos(rightFarGrabRotation, rightFarGrabPosition));
|
||||
_farGrabMouseMatrixCache.set(createMatFromQuatAndPos(mouseFarGrabRotation, mouseFarGrabPosition));
|
||||
|
||||
sourceBuffer += sizeof(AvatarDataPacket::AvatarGlobalPosition);
|
||||
sourceBuffer += sizeof(AvatarDataPacket::FarGrabJoints);
|
||||
int numBytesRead = sourceBuffer - startSection;
|
||||
_farGrabJointRate.increment(numBytesRead);
|
||||
_farGrabJointUpdateRate.increment();
|
||||
|
@ -2821,10 +2825,10 @@ QScriptValue RayToAvatarIntersectionResultToScriptValue(QScriptEngine* engine, c
|
|||
obj.setProperty("avatarID", avatarIDValue);
|
||||
obj.setProperty("distance", value.distance);
|
||||
obj.setProperty("face", boxFaceToString(value.face));
|
||||
QScriptValue intersection = vec3ToScriptValue(engine, value.intersection);
|
||||
|
||||
QScriptValue intersection = vec3toScriptValue(engine, value.intersection);
|
||||
obj.setProperty("intersection", intersection);
|
||||
QScriptValue surfaceNormal = vec3toScriptValue(engine, value.surfaceNormal);
|
||||
QScriptValue surfaceNormal = vec3ToScriptValue(engine, value.surfaceNormal);
|
||||
obj.setProperty("surfaceNormal", surfaceNormal);
|
||||
obj.setProperty("extraInfo", engine->toScriptValue(value.extraInfo));
|
||||
return obj;
|
||||
|
|
|
@ -258,7 +258,6 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer<ReceivedMessag
|
|||
|
||||
if (isNewAvatar) {
|
||||
QWriteLocker locker(&_hashLock);
|
||||
_pendingAvatars.insert(sessionUUID, { std::chrono::steady_clock::now(), 0, avatar });
|
||||
avatar->setIsNewAvatar(true);
|
||||
auto replicaIDs = _replicas.getReplicaIDs(sessionUUID);
|
||||
for (auto replicaID : replicaIDs) {
|
||||
|
@ -300,7 +299,6 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage>
|
|||
|
||||
{
|
||||
QReadLocker locker(&_hashLock);
|
||||
_pendingAvatars.remove(identityUUID);
|
||||
auto me = _avatarHash.find(EMPTY);
|
||||
if ((me != _avatarHash.end()) && (identityUUID == me.value()->getSessionUUID())) {
|
||||
// We add MyAvatar to _avatarHash with an empty UUID. Code relies on this. In order to correctly handle an
|
||||
|
@ -419,7 +417,6 @@ void AvatarHashMap::removeAvatar(const QUuid& sessionUUID, KillAvatarReason remo
|
|||
}
|
||||
}
|
||||
|
||||
_pendingAvatars.remove(sessionUUID);
|
||||
auto removedAvatar = _avatarHash.take(sessionUUID);
|
||||
|
||||
if (removedAvatar) {
|
||||
|
|
|
@ -161,6 +161,11 @@ protected slots:
|
|||
*/
|
||||
void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarList.processBulkAvatarTraits
|
||||
* @param {} message
|
||||
* @param {} sendingNode
|
||||
*/
|
||||
void processBulkAvatarTraits(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
||||
|
||||
/**jsdoc
|
||||
|
@ -183,15 +188,8 @@ protected:
|
|||
|
||||
virtual void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason);
|
||||
|
||||
AvatarHash _avatarHash;
|
||||
struct PendingAvatar {
|
||||
std::chrono::steady_clock::time_point creationTime;
|
||||
int transmits;
|
||||
AvatarSharedPointer avatar;
|
||||
};
|
||||
using AvatarPendingHash = QHash<QUuid, PendingAvatar>;
|
||||
AvatarPendingHash _pendingAvatars;
|
||||
mutable QReadWriteLock _hashLock;
|
||||
AvatarHash _avatarHash;
|
||||
|
||||
std::unordered_map<QUuid, AvatarTraits::TraitVersions> _processedTraitVersions;
|
||||
AvatarReplicas _replicas;
|
||||
|
|
|
@ -98,7 +98,7 @@ enum Hand {
|
|||
class InputDevice {
|
||||
public:
|
||||
InputDevice(const QString& name) : _name(name) {}
|
||||
virtual ~InputDevice() {}
|
||||
virtual ~InputDevice() = default;
|
||||
|
||||
using Pointer = std::shared_ptr<InputDevice>;
|
||||
|
||||
|
|
|
@ -41,10 +41,10 @@ namespace controller {
|
|||
*/
|
||||
QScriptValue Pose::toScriptValue(QScriptEngine* engine, const Pose& pose) {
|
||||
QScriptValue obj = engine->newObject();
|
||||
obj.setProperty("translation", vec3toScriptValue(engine, pose.translation));
|
||||
obj.setProperty("translation", vec3ToScriptValue(engine, pose.translation));
|
||||
obj.setProperty("rotation", quatToScriptValue(engine, pose.rotation));
|
||||
obj.setProperty("velocity", vec3toScriptValue(engine, pose.velocity));
|
||||
obj.setProperty("angularVelocity", vec3toScriptValue(engine, pose.angularVelocity));
|
||||
obj.setProperty("velocity", vec3ToScriptValue(engine, pose.velocity));
|
||||
obj.setProperty("angularVelocity", vec3ToScriptValue(engine, pose.angularVelocity));
|
||||
obj.setProperty("valid", pose.valid);
|
||||
return obj;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@ namespace controller {
|
|||
using Factory = hifi::SimpleFactory<Conditional, QString>;
|
||||
using Lambda = std::function<bool()>;
|
||||
|
||||
virtual ~Conditional() = default;
|
||||
|
||||
virtual bool satisfied() = 0;
|
||||
virtual bool parseParameters(const QJsonValue& parameters) { return true; }
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@ namespace controller {
|
|||
using Lambda = std::function<float(float)>;
|
||||
using Factory = hifi::SimpleFactory<Filter, QString>;
|
||||
|
||||
virtual ~Filter() = default;
|
||||
|
||||
virtual float apply(float value) const = 0;
|
||||
virtual Pose apply(Pose value) const = 0;
|
||||
|
||||
|
|
|
@ -24,8 +24,6 @@ public:
|
|||
AndConditional(Conditional::Pointer& first, Conditional::Pointer& second)
|
||||
: _children({ first, second }) {}
|
||||
|
||||
virtual ~AndConditional() {}
|
||||
|
||||
virtual bool satisfied() override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -18,7 +18,6 @@ namespace controller {
|
|||
class EndpointConditional : public Conditional {
|
||||
public:
|
||||
EndpointConditional(Endpoint::Pointer endpoint) : _endpoint(endpoint) {}
|
||||
virtual ~EndpointConditional() {}
|
||||
virtual bool satisfied() override { return _endpoint && _endpoint->peek() != 0.0f; }
|
||||
private:
|
||||
Endpoint::Pointer _endpoint;
|
||||
|
|
|
@ -19,7 +19,6 @@ namespace controller {
|
|||
using Pointer = std::shared_ptr<NotConditional>;
|
||||
|
||||
NotConditional(Conditional::Pointer operand) : _operand(operand) { }
|
||||
virtual ~NotConditional() {}
|
||||
|
||||
virtual bool satisfied() override;
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ class ClampFilter : public Filter {
|
|||
REGISTER_FILTER_CLASS(ClampFilter);
|
||||
public:
|
||||
ClampFilter(float min = 0.0, float max = 1.0) : _min(min), _max(max) {};
|
||||
virtual ~ClampFilter() {}
|
||||
virtual float apply(float value) const override {
|
||||
return glm::clamp(value, _min, _max);
|
||||
}
|
||||
|
|
|
@ -17,16 +17,13 @@ namespace controller {
|
|||
class ConstrainToIntegerFilter : public Filter {
|
||||
REGISTER_FILTER_CLASS(ConstrainToIntegerFilter);
|
||||
public:
|
||||
ConstrainToIntegerFilter() {};
|
||||
virtual ~ConstrainToIntegerFilter() {}
|
||||
ConstrainToIntegerFilter() = default;
|
||||
|
||||
virtual float apply(float value) const override {
|
||||
return glm::sign(value);
|
||||
}
|
||||
|
||||
virtual Pose apply(Pose value) const override { return value; }
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -17,16 +17,13 @@ namespace controller {
|
|||
class ConstrainToPositiveIntegerFilter : public Filter {
|
||||
REGISTER_FILTER_CLASS(ConstrainToPositiveIntegerFilter);
|
||||
public:
|
||||
ConstrainToPositiveIntegerFilter() {};
|
||||
virtual ~ConstrainToPositiveIntegerFilter() {};
|
||||
ConstrainToPositiveIntegerFilter() = default;
|
||||
|
||||
virtual float apply(float value) const override {
|
||||
return (value <= 0.0f) ? 0.0f : 1.0f;
|
||||
}
|
||||
|
||||
virtual Pose apply(Pose value) const override { return value; }
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ class DeadZoneFilter : public Filter {
|
|||
REGISTER_FILTER_CLASS(DeadZoneFilter);
|
||||
public:
|
||||
DeadZoneFilter(float min = 0.0) : _min(min) {};
|
||||
virtual ~DeadZoneFilter() {}
|
||||
|
||||
virtual float apply(float value) const override;
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ namespace controller {
|
|||
ExponentialSmoothingFilter() {}
|
||||
ExponentialSmoothingFilter(float rotationConstant, float translationConstant) :
|
||||
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
|
||||
virtual ~ExponentialSmoothingFilter() {}
|
||||
|
||||
float apply(float value) const override { return value; }
|
||||
Pose apply(Pose value) const override;
|
||||
|
|
|
@ -18,7 +18,6 @@ class HysteresisFilter : public Filter {
|
|||
REGISTER_FILTER_CLASS(HysteresisFilter);
|
||||
public:
|
||||
HysteresisFilter(float min = 0.25, float max = 0.75);
|
||||
virtual ~HysteresisFilter() {}
|
||||
virtual float apply(float value) const override;
|
||||
|
||||
virtual Pose apply(Pose value) const override { return value; }
|
||||
|
|
|
@ -19,11 +19,8 @@ class InvertFilter : public ScaleFilter {
|
|||
public:
|
||||
using ScaleFilter::parseParameters;
|
||||
InvertFilter() : ScaleFilter(-1.0f) {}
|
||||
virtual ~InvertFilter() {}
|
||||
|
||||
virtual bool parseParameters(const QJsonArray& parameters) { return true; }
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -17,10 +17,9 @@ namespace controller {
|
|||
REGISTER_FILTER_CLASS(LowVelocityFilter);
|
||||
|
||||
public:
|
||||
LowVelocityFilter() {}
|
||||
LowVelocityFilter() = default;
|
||||
LowVelocityFilter(float rotationConstant, float translationConstant) :
|
||||
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
|
||||
virtual ~LowVelocityFilter() {}
|
||||
|
||||
float apply(float value) const override { return value; }
|
||||
Pose apply(Pose newPose) const override;
|
||||
|
|
|
@ -10,7 +10,6 @@ class NotFilter : public Filter {
|
|||
REGISTER_FILTER_CLASS(NotFilter);
|
||||
public:
|
||||
NotFilter();
|
||||
virtual ~NotFilter() {}
|
||||
|
||||
virtual float apply(float value) const override;
|
||||
virtual Pose apply(Pose value) const override { return value; }
|
||||
|
|
|
@ -19,9 +19,8 @@ namespace controller {
|
|||
class PostTransformFilter : public Filter {
|
||||
REGISTER_FILTER_CLASS(PostTransformFilter);
|
||||
public:
|
||||
PostTransformFilter() { }
|
||||
PostTransformFilter() = default;
|
||||
PostTransformFilter(glm::mat4 transform) : _transform(transform) {}
|
||||
virtual ~PostTransformFilter() {}
|
||||
virtual float apply(float value) const override { return value; }
|
||||
virtual Pose apply(Pose value) const override { return value.postTransform(_transform); }
|
||||
virtual bool parseParameters(const QJsonValue& parameters) override { return parseMat4Parameter(parameters, _transform); }
|
||||
|
|
|
@ -18,9 +18,8 @@ namespace controller {
|
|||
class PulseFilter : public Filter {
|
||||
REGISTER_FILTER_CLASS(PulseFilter);
|
||||
public:
|
||||
PulseFilter() {}
|
||||
PulseFilter() = default;
|
||||
PulseFilter(float interval) : _interval(interval) {}
|
||||
virtual ~PulseFilter() {}
|
||||
|
||||
virtual float apply(float value) const override;
|
||||
|
||||
|
|
|
@ -19,9 +19,8 @@ namespace controller {
|
|||
class RotateFilter : public Filter {
|
||||
REGISTER_FILTER_CLASS(RotateFilter);
|
||||
public:
|
||||
RotateFilter() { }
|
||||
RotateFilter() = default;
|
||||
RotateFilter(glm::quat rotation) : _rotation(rotation) {}
|
||||
virtual ~RotateFilter() {}
|
||||
|
||||
virtual float apply(float value) const override { return value; }
|
||||
|
||||
|
|
|
@ -19,9 +19,8 @@ namespace controller {
|
|||
class ScaleFilter : public Filter {
|
||||
REGISTER_FILTER_CLASS(ScaleFilter);
|
||||
public:
|
||||
ScaleFilter() {}
|
||||
ScaleFilter() = default;
|
||||
ScaleFilter(float scale) : _scale(scale) {}
|
||||
virtual ~ScaleFilter() {}
|
||||
|
||||
virtual float apply(float value) const override {
|
||||
return value * _scale;
|
||||
|
|
|
@ -19,9 +19,8 @@ namespace controller {
|
|||
class TransformFilter : public Filter {
|
||||
REGISTER_FILTER_CLASS(TransformFilter);
|
||||
public:
|
||||
TransformFilter() { }
|
||||
TransformFilter() = default;
|
||||
TransformFilter(glm::mat4 transform) : _transform(transform) {}
|
||||
virtual ~TransformFilter() {}
|
||||
|
||||
virtual float apply(float value) const override { return value; }
|
||||
virtual Pose apply(Pose value) const override { return value.transform(_transform); }
|
||||
|
|