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
|
// setup an Avatar for the script to use
|
||||||
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
||||||
|
|
||||||
scriptedAvatar->setID(getSessionUUID());
|
scriptedAvatar->setID(getSessionUUID());
|
||||||
|
|
||||||
connect(_scriptEngine.data(), SIGNAL(update(float)),
|
|
||||||
scriptedAvatar.data(), SLOT(update(float)), Qt::ConnectionType::QueuedConnection);
|
|
||||||
scriptedAvatar->setForceFaceTrackerConnected(true);
|
scriptedAvatar->setForceFaceTrackerConnected(true);
|
||||||
|
|
||||||
// call model URL setters with empty URLs so our avatar, if user, will have the default models
|
// 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());
|
DependencyManager::set<AssignmentParentFinder>(_entityViewer.getTree());
|
||||||
|
|
||||||
_avatarAudioTimer.start();
|
|
||||||
|
|
||||||
// Agents should run at 45hz
|
// Agents should run at 45hz
|
||||||
static const int AVATAR_DATA_HZ = 45;
|
static const int AVATAR_DATA_HZ = 45;
|
||||||
static const int AVATAR_DATA_IN_MSECS = MSECS_PER_SECOND / AVATAR_DATA_HZ;
|
static const int AVATAR_DATA_IN_MSECS = MSECS_PER_SECOND / AVATAR_DATA_HZ;
|
||||||
|
@ -530,7 +524,8 @@ void Agent::executeScript() {
|
||||||
}
|
}
|
||||||
|
|
||||||
avatarDataTimer->stop();
|
avatarDataTimer->stop();
|
||||||
_avatarAudioTimer.stop();
|
|
||||||
|
setIsAvatar(false); // will stop timers for sending identity packets
|
||||||
}
|
}
|
||||||
|
|
||||||
setFinished(true);
|
setFinished(true);
|
||||||
|
@ -582,7 +577,9 @@ void Agent::setIsAvatar(bool isAvatar) {
|
||||||
}
|
}
|
||||||
_isAvatar = isAvatar;
|
_isAvatar = isAvatar;
|
||||||
|
|
||||||
if (_isAvatar && !_avatarIdentityTimer) {
|
auto scriptableAvatar = DependencyManager::get<ScriptableAvatar>();
|
||||||
|
if (_isAvatar) {
|
||||||
|
if (!_avatarIdentityTimer) {
|
||||||
// set up the avatar timers
|
// set up the avatar timers
|
||||||
_avatarIdentityTimer = new QTimer(this);
|
_avatarIdentityTimer = new QTimer(this);
|
||||||
_avatarQueryTimer = new QTimer(this);
|
_avatarQueryTimer = new QTimer(this);
|
||||||
|
@ -598,12 +595,15 @@ void Agent::setIsAvatar(bool isAvatar) {
|
||||||
_avatarIdentityTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS); // FIXME - we shouldn't really need to constantly send identity packets
|
_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);
|
_avatarQueryTimer->start(AVATAR_VIEW_PACKET_SEND_INTERVAL_MSECS);
|
||||||
|
|
||||||
|
connect(_scriptEngine.data(), &ScriptEngine::update,
|
||||||
|
scriptableAvatar.data(), &ScriptableAvatar::update, Qt::QueuedConnection);
|
||||||
|
|
||||||
// tell the avatarAudioTimer to start ticking
|
// tell the avatarAudioTimer to start ticking
|
||||||
QMetaObject::invokeMethod(&_avatarAudioTimer, "start");
|
QMetaObject::invokeMethod(&_avatarAudioTimer, "start");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_isAvatar) {
|
_entityEditSender.setMyAvatar(scriptableAvatar.data());
|
||||||
|
} else {
|
||||||
if (_avatarIdentityTimer) {
|
if (_avatarIdentityTimer) {
|
||||||
_avatarIdentityTimer->stop();
|
_avatarIdentityTimer->stop();
|
||||||
delete _avatarIdentityTimer;
|
delete _avatarIdentityTimer;
|
||||||
|
@ -630,14 +630,14 @@ void Agent::setIsAvatar(bool isAvatar) {
|
||||||
packet->writePrimitive(KillAvatarReason::NoReason);
|
packet->writePrimitive(KillAvatarReason::NoReason);
|
||||||
nodeList->sendPacket(std::move(packet), *node);
|
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);
|
_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
|
// seek past the sequence number, will be packed when destination node is known
|
||||||
audioPacket->seek(sizeof(quint16));
|
audioPacket->seek(sizeof(quint16));
|
||||||
|
|
||||||
if (silentFrame) {
|
if (silentFrame && !_flushEncoder) {
|
||||||
|
|
||||||
if (!_isListeningToAudioStream) {
|
if (!_isListeningToAudioStream) {
|
||||||
// if we have a silent frame and we're not listening then just send nothing and break out of here
|
// 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
|
// no matter what, the loudness should be set to 0
|
||||||
computeLoudness(nullptr, scriptedAvatar);
|
computeLoudness(nullptr, scriptedAvatar);
|
||||||
} else if (nextSoundOutput) {
|
} else if (nextSoundOutput || _flushEncoder) {
|
||||||
|
|
||||||
// write the codec
|
// write the codec
|
||||||
audioPacket->writeString(_selectedCodecName);
|
audioPacket->writeString(_selectedCodecName);
|
||||||
|
@ -864,8 +864,6 @@ void Agent::processAgentAvatarAudio() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Agent::aboutToFinish() {
|
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
|
// our entity tree is going to go away so tell that to the EntityScriptingInterface
|
||||||
DependencyManager::get<EntityScriptingInterface>()->setEntityTree(nullptr);
|
DependencyManager::get<EntityScriptingInterface>()->setEntityTree(nullptr);
|
||||||
|
|
||||||
|
|
|
@ -497,7 +497,7 @@ void AudioMixerClientData::processStreamPacket(ReceivedMessage& message, Concurr
|
||||||
|
|
||||||
if (newStream) {
|
if (newStream) {
|
||||||
// whenever a stream is added, push it to the concurrent vector of streams added this frame
|
// 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) {
|
if (lastSeqToReceiver == lastSeqFromSender && lastSeqToReceiver != 0) {
|
||||||
++numAvatarsHeldBack;
|
++numAvatarsHeldBack;
|
||||||
shouldIgnore = true;
|
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) {
|
} 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
|
// this is a skip - we still send the packet but capture the presence of the skip so we see it happening
|
||||||
++numAvatarsWithSkippedFrames;
|
++numAvatarsWithSkippedFrames;
|
||||||
|
|
|
@ -164,7 +164,7 @@ public:
|
||||||
void setHasAudioEnabledFaceMovement(bool hasAudioEnabledFaceMovement);
|
void setHasAudioEnabledFaceMovement(bool hasAudioEnabledFaceMovement);
|
||||||
bool getHasAudioEnabledFaceMovement() const override { return _headData->getHasAudioEnabledFaceMovement(); }
|
bool getHasAudioEnabledFaceMovement() const override { return _headData->getHasAudioEnabledFaceMovement(); }
|
||||||
|
|
||||||
private slots:
|
public slots:
|
||||||
void update(float deltatime);
|
void update(float deltatime);
|
||||||
|
|
||||||
private:
|
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(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 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 the SDK path for the desired SDK
|
||||||
find_path(
|
find_path(
|
||||||
|
|
8
cmake/externals/quazip/CMakeLists.txt
vendored
|
@ -1,13 +1,11 @@
|
||||||
set(EXTERNAL_NAME quazip)
|
set(EXTERNAL_NAME quazip)
|
||||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||||
cmake_policy(SET CMP0046 OLD)
|
|
||||||
|
|
||||||
include(ExternalProject)
|
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)
|
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)
|
if (NOT APPLE)
|
||||||
else ()
|
|
||||||
set(QUAZIP_CMAKE_ARGS ${QUAZIP_CMAKE_ARGS} -DCMAKE_CXX_STANDARD=11)
|
set(QUAZIP_CMAKE_ARGS ${QUAZIP_CMAKE_ARGS} -DCMAKE_CXX_STANDARD=11)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
@ -22,7 +20,9 @@ ExternalProject_Add(
|
||||||
LOG_BUILD 1
|
LOG_BUILD 1
|
||||||
)
|
)
|
||||||
|
|
||||||
add_dependencies(quazip zlib)
|
if (WIN32)
|
||||||
|
add_dependencies(quazip zlib)
|
||||||
|
endif ()
|
||||||
|
|
||||||
# Hide this external target (for ide users)
|
# Hide this external target (for ide users)
|
||||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES
|
set_target_properties(${EXTERNAL_NAME} PROPERTIES
|
||||||
|
|
|
@ -3,11 +3,11 @@ if (WIN32)
|
||||||
endif (WIN32)
|
endif (WIN32)
|
||||||
|
|
||||||
if (POLICY CMP0043)
|
if (POLICY CMP0043)
|
||||||
cmake_policy(SET CMP0043 OLD)
|
cmake_policy(SET CMP0043 NEW)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (POLICY CMP0042)
|
if (POLICY CMP0042)
|
||||||
cmake_policy(SET CMP0042 OLD)
|
cmake_policy(SET CMP0042 NEW)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
|
@ -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
|
// 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)
|
// we cannot recursively take the write lock required by handleKillNode)
|
||||||
std::vector<SharedNodePointer> nodesToKill;
|
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()))
|
if ((direction == Upstream && NodeType::isUpstream(otherNode->getType()))
|
||||||
|| (direction == Downstream && NodeType::isDownstream(otherNode->getType()))) {
|
|| (direction == Downstream && NodeType::isDownstream(otherNode->getType()))) {
|
||||||
bool nodeInSettings = find(replicationNodesInSettings.cbegin(), replicationNodesInSettings.cend(),
|
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 string sendingPubliclyEffectImage;
|
||||||
property var http;
|
property var http;
|
||||||
property var listModelName;
|
property var listModelName;
|
||||||
|
property var keyboardContainer: nil;
|
||||||
|
|
||||||
// This object is always used in a popup or full-screen Wallet section.
|
// This object is always used in a popup or full-screen Wallet section.
|
||||||
// This MouseArea is used to prevent a user from being
|
// This MouseArea is used to prevent a user from being
|
||||||
|
@ -1125,8 +1126,7 @@ Item {
|
||||||
checked: Settings.getValue("sendAssetsNearbyPublicly", true);
|
checked: Settings.getValue("sendAssetsNearbyPublicly", true);
|
||||||
text: "Show Effect"
|
text: "Show Effect"
|
||||||
// Anchors
|
// Anchors
|
||||||
anchors.top: messageContainer.bottom;
|
anchors.verticalCenter: bottomBarContainer.verticalCenter;
|
||||||
anchors.topMargin: 16;
|
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.leftMargin: 20;
|
anchors.leftMargin: 20;
|
||||||
width: 130;
|
width: 130;
|
||||||
|
@ -1168,6 +1168,9 @@ Item {
|
||||||
lightboxPopup.visible = false;
|
lightboxPopup.visible = false;
|
||||||
}
|
}
|
||||||
lightboxPopup.visible = true;
|
lightboxPopup.visible = true;
|
||||||
|
if (keyboardContainer) {
|
||||||
|
keyboardContainer.keyboardRaised = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1178,8 +1181,8 @@ Item {
|
||||||
anchors.leftMargin: 20;
|
anchors.leftMargin: 20;
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
anchors.rightMargin: 20;
|
anchors.rightMargin: 20;
|
||||||
anchors.bottom: parent.bottom;
|
anchors.top: messageContainer.bottom;
|
||||||
anchors.bottomMargin: 20;
|
anchors.topMargin: 20;
|
||||||
height: 60;
|
height: 60;
|
||||||
|
|
||||||
// "CANCEL" button
|
// "CANCEL" button
|
||||||
|
@ -1187,11 +1190,11 @@ Item {
|
||||||
id: cancelButton_sendAssetStep;
|
id: cancelButton_sendAssetStep;
|
||||||
color: root.assetName === "" ? hifi.buttons.noneBorderlessWhite : hifi.buttons.noneBorderlessGray;
|
color: root.assetName === "" ? hifi.buttons.noneBorderlessWhite : hifi.buttons.noneBorderlessGray;
|
||||||
colorScheme: hifi.colorSchemes.dark;
|
colorScheme: hifi.colorSchemes.dark;
|
||||||
anchors.left: parent.left;
|
anchors.right: sendButton.left;
|
||||||
anchors.leftMargin: 24;
|
anchors.rightMargin: 24;
|
||||||
anchors.verticalCenter: parent.verticalCenter;
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
height: 40;
|
height: 40;
|
||||||
width: 150;
|
width: 100;
|
||||||
text: "CANCEL";
|
text: "CANCEL";
|
||||||
onClicked: {
|
onClicked: {
|
||||||
resetSendAssetData();
|
resetSendAssetData();
|
||||||
|
@ -1205,10 +1208,10 @@ Item {
|
||||||
color: hifi.buttons.blue;
|
color: hifi.buttons.blue;
|
||||||
colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
|
colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
anchors.rightMargin: 24;
|
anchors.rightMargin: 0;
|
||||||
anchors.verticalCenter: parent.verticalCenter;
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
height: 40;
|
height: 40;
|
||||||
width: 150;
|
width: 100;
|
||||||
text: "SUBMIT";
|
text: "SUBMIT";
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (root.assetName === "" && parseInt(amountTextField.text) > parseInt(balanceText.text)) {
|
if (root.assetName === "" && parseInt(amountTextField.text) > parseInt(balanceText.text)) {
|
||||||
|
|
|
@ -158,6 +158,7 @@ Rectangle {
|
||||||
listModelName: "Gift Connections";
|
listModelName: "Gift Connections";
|
||||||
z: 998;
|
z: 998;
|
||||||
visible: root.activeView === "giftAsset";
|
visible: root.activeView === "giftAsset";
|
||||||
|
keyboardContainer: root;
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
parentAppTitleBarHeight: 70;
|
parentAppTitleBarHeight: 70;
|
||||||
parentAppNavBarHeight: 0;
|
parentAppNavBarHeight: 0;
|
||||||
|
@ -585,7 +586,7 @@ Rectangle {
|
||||||
visible: purchasesModel.count !== 0;
|
visible: purchasesModel.count !== 0;
|
||||||
clip: true;
|
clip: true;
|
||||||
model: purchasesModel;
|
model: purchasesModel;
|
||||||
snapMode: ListView.SnapToItem;
|
snapMode: ListView.NoSnap;
|
||||||
// Anchors
|
// Anchors
|
||||||
anchors.top: separator.bottom;
|
anchors.top: separator.bottom;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
|
|
|
@ -354,6 +354,7 @@ Rectangle {
|
||||||
listModelName: "Send Money Connections";
|
listModelName: "Send Money Connections";
|
||||||
z: 997;
|
z: 997;
|
||||||
visible: root.activeView === "sendMoney";
|
visible: root.activeView === "sendMoney";
|
||||||
|
keyboardContainer: root;
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
parentAppTitleBarHeight: titleBarContainer.height;
|
parentAppTitleBarHeight: titleBarContainer.height;
|
||||||
parentAppNavBarHeight: tabButtonsContainer.height;
|
parentAppNavBarHeight: tabButtonsContainer.height;
|
||||||
|
|
|
@ -152,6 +152,8 @@
|
||||||
#include <avatars-renderer/ScriptAvatar.h>
|
#include <avatars-renderer/ScriptAvatar.h>
|
||||||
#include <RenderableEntityItem.h>
|
#include <RenderableEntityItem.h>
|
||||||
#include <procedural/ProceduralSkybox.h>
|
#include <procedural/ProceduralSkybox.h>
|
||||||
|
#include <model-networking/MaterialCache.h>
|
||||||
|
#include "recording/ClipCache.h"
|
||||||
|
|
||||||
#include "AudioClient.h"
|
#include "AudioClient.h"
|
||||||
#include "audio/AudioScope.h"
|
#include "audio/AudioScope.h"
|
||||||
|
@ -328,9 +330,9 @@ static bool DISABLE_DEFERRED = QProcessEnvironment::systemEnvironment().contains
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(Q_OS_ANDROID)
|
#if !defined(Q_OS_ANDROID)
|
||||||
static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16;
|
static const uint32_t MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16;
|
||||||
#else
|
#else
|
||||||
static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 4;
|
static const uint32_t MAX_CONCURRENT_RESOURCE_DOWNLOADS = 4;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// For processing on QThreadPool, we target a number of threads after reserving some
|
// 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");
|
QString concurrentDownloadsStr = getCmdOption(argc, constArgv, "--concurrent-downloads");
|
||||||
bool success;
|
bool success;
|
||||||
int concurrentDownloads = concurrentDownloadsStr.toInt(&success);
|
uint32_t concurrentDownloads = concurrentDownloadsStr.toUInt(&success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
concurrentDownloads = MAX_CONCURRENT_RESOURCE_DOWNLOADS;
|
concurrentDownloads = MAX_CONCURRENT_RESOURCE_DOWNLOADS;
|
||||||
}
|
}
|
||||||
|
@ -2054,7 +2056,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
}
|
}
|
||||||
|
|
||||||
properties["active_downloads"] = loadingRequests.size();
|
properties["active_downloads"] = loadingRequests.size();
|
||||||
properties["pending_downloads"] = ResourceCache::getPendingRequestCount();
|
properties["pending_downloads"] = (int)ResourceCache::getPendingRequestCount();
|
||||||
properties["active_downloads_details"] = loadingRequestsStats;
|
properties["active_downloads_details"] = loadingRequestsStats;
|
||||||
|
|
||||||
auto statTracker = DependencyManager::get<StatTracker>();
|
auto statTracker = DependencyManager::get<StatTracker>();
|
||||||
|
@ -3532,6 +3534,7 @@ void Application::setIsInterstitialMode(bool interstitialMode) {
|
||||||
if (enableInterstitial) {
|
if (enableInterstitial) {
|
||||||
if (_interstitialMode != interstitialMode) {
|
if (_interstitialMode != interstitialMode) {
|
||||||
_interstitialMode = interstitialMode;
|
_interstitialMode = interstitialMode;
|
||||||
|
emit interstitialModeChanged(_interstitialMode);
|
||||||
|
|
||||||
DependencyManager::get<AudioClient>()->setAudioPaused(_interstitialMode);
|
DependencyManager::get<AudioClient>()->setAudioPaused(_interstitialMode);
|
||||||
DependencyManager::get<AvatarManager>()->setMyAvatarDataPacketsPaused(_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, "present", float, displayPlugin->presentRate());
|
||||||
}
|
}
|
||||||
PROFILE_COUNTER_IF_CHANGED(app, "renderLoopRate", float, _renderLoopCounter.rate());
|
PROFILE_COUNTER_IF_CHANGED(app, "renderLoopRate", float, _renderLoopCounter.rate());
|
||||||
PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", int, ResourceCache::getLoadingRequests().length());
|
PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", uint32_t, ResourceCache::getLoadingRequestCount());
|
||||||
PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", int, ResourceCache::getPendingRequestCount());
|
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, "currentProcessing", int, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
|
||||||
PROFILE_COUNTER_IF_CHANGED(app, "pendingProcessing", int, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
|
PROFILE_COUNTER_IF_CHANGED(app, "pendingProcessing", int, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
|
||||||
auto renderConfig = _renderEngine->getConfiguration();
|
auto renderConfig = _renderEngine->getConfiguration();
|
||||||
|
@ -5399,13 +5402,21 @@ void Application::reloadResourceCaches() {
|
||||||
|
|
||||||
queryOctree(NodeType::EntityServer, PacketType::EntityQuery);
|
queryOctree(NodeType::EntityServer, PacketType::EntityQuery);
|
||||||
|
|
||||||
|
// Clear the entities and their renderables
|
||||||
|
getEntities()->clear();
|
||||||
|
|
||||||
DependencyManager::get<AssetClient>()->clearCache();
|
DependencyManager::get<AssetClient>()->clearCache();
|
||||||
DependencyManager::get<ScriptCache>()->clearCache();
|
DependencyManager::get<ScriptCache>()->clearCache();
|
||||||
|
|
||||||
|
// Clear all the resource caches
|
||||||
|
DependencyManager::get<ResourceCacheSharedItems>()->clear();
|
||||||
DependencyManager::get<AnimationCache>()->refreshAll();
|
DependencyManager::get<AnimationCache>()->refreshAll();
|
||||||
DependencyManager::get<ModelCache>()->refreshAll();
|
|
||||||
DependencyManager::get<SoundCache>()->refreshAll();
|
DependencyManager::get<SoundCache>()->refreshAll();
|
||||||
|
MaterialCache::instance().refreshAll();
|
||||||
|
DependencyManager::get<ModelCache>()->refreshAll();
|
||||||
|
ShaderCache::instance().refreshAll();
|
||||||
DependencyManager::get<TextureCache>()->refreshAll();
|
DependencyManager::get<TextureCache>()->refreshAll();
|
||||||
|
DependencyManager::get<recording::ClipCache>()->refreshAll();
|
||||||
|
|
||||||
DependencyManager::get<NodeList>()->reset(); // Force redownload of .fst models
|
DependencyManager::get<NodeList>()->reset(); // Force redownload of .fst models
|
||||||
|
|
||||||
|
@ -6470,9 +6481,12 @@ void Application::clearDomainOctreeDetails() {
|
||||||
skyStage->setBackgroundMode(graphics::SunSkyStage::SKY_DEFAULT);
|
skyStage->setBackgroundMode(graphics::SunSkyStage::SKY_DEFAULT);
|
||||||
|
|
||||||
DependencyManager::get<AnimationCache>()->clearUnusedResources();
|
DependencyManager::get<AnimationCache>()->clearUnusedResources();
|
||||||
DependencyManager::get<ModelCache>()->clearUnusedResources();
|
|
||||||
DependencyManager::get<SoundCache>()->clearUnusedResources();
|
DependencyManager::get<SoundCache>()->clearUnusedResources();
|
||||||
|
MaterialCache::instance().clearUnusedResources();
|
||||||
|
DependencyManager::get<ModelCache>()->clearUnusedResources();
|
||||||
|
ShaderCache::instance().clearUnusedResources();
|
||||||
DependencyManager::get<TextureCache>()->clearUnusedResources();
|
DependencyManager::get<TextureCache>()->clearUnusedResources();
|
||||||
|
DependencyManager::get<recording::ClipCache>()->clearUnusedResources();
|
||||||
|
|
||||||
getMyAvatar()->setAvatarEntityDataChanged(true);
|
getMyAvatar()->setAvatarEntityDataChanged(true);
|
||||||
}
|
}
|
||||||
|
@ -8463,6 +8477,16 @@ QUuid Application::getTabletFrameID() const {
|
||||||
return HMD->getCurrentTabletFrameID();
|
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) {
|
void Application::setAvatarOverrideUrl(const QUrl& url, bool save) {
|
||||||
_avatarOverrideUrl = url;
|
_avatarOverrideUrl = url;
|
||||||
_saveAvatarOverrideUrl = save;
|
_saveAvatarOverrideUrl = save;
|
||||||
|
|
|
@ -298,6 +298,7 @@ public:
|
||||||
OverlayID getTabletScreenID() const;
|
OverlayID getTabletScreenID() const;
|
||||||
OverlayID getTabletHomeButtonID() const;
|
OverlayID getTabletHomeButtonID() const;
|
||||||
QUuid getTabletFrameID() const; // may be an entity or an overlay
|
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 setAvatarOverrideUrl(const QUrl& url, bool save);
|
||||||
void clearAvatarOverrideUrl() { _avatarOverrideUrl = QUrl(); _saveAvatarOverrideUrl = false; }
|
void clearAvatarOverrideUrl() { _avatarOverrideUrl = QUrl(); _saveAvatarOverrideUrl = false; }
|
||||||
|
@ -334,6 +335,8 @@ signals:
|
||||||
|
|
||||||
void uploadRequest(QString path);
|
void uploadRequest(QString path);
|
||||||
|
|
||||||
|
void interstitialModeChanged(bool isInInterstitialMode);
|
||||||
|
|
||||||
void loginDialogPoppedUp();
|
void loginDialogPoppedUp();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
@ -78,8 +78,10 @@ void addAvatarEntities(const QVariantList& avatarEntities) {
|
||||||
}
|
}
|
||||||
|
|
||||||
entity->setLastBroadcast(usecTimestampNow());
|
entity->setLastBroadcast(usecTimestampNow());
|
||||||
// since we're creating this object we will immediately volunteer to own its simulation
|
if (entityProperties.getDynamic()) {
|
||||||
entity->setScriptSimulationPriority(VOLUNTEER_SIMULATION_PRIORITY);
|
// since we're creating a dynamic object we volunteer immediately to own its simulation
|
||||||
|
entity->upgradeScriptSimulationPriority(VOLUNTEER_SIMULATION_PRIORITY);
|
||||||
|
}
|
||||||
entityProperties.setLastEdited(entity->getLastEdited());
|
entityProperties.setLastEdited(entity->getLastEdited());
|
||||||
} else {
|
} else {
|
||||||
qCDebug(entities) << "AvatarEntitiesBookmark failed to add new Entity to local Octree";
|
qCDebug(entities) << "AvatarEntitiesBookmark failed to add new Entity to local Octree";
|
||||||
|
@ -108,6 +110,9 @@ AvatarBookmarks::AvatarBookmarks() {
|
||||||
|
|
||||||
if (!QFile::copy(defaultBookmarksFilename, _bookmarksFilename)) {
|
if (!QFile::copy(defaultBookmarksFilename, _bookmarksFilename)) {
|
||||||
qDebug() << "failed to copy" << defaultBookmarksFilename << "to" << _bookmarksFilename;
|
qDebug() << "failed to copy" << defaultBookmarksFilename << "to" << _bookmarksFilename;
|
||||||
|
} else {
|
||||||
|
QFile bookmarksFile(_bookmarksFilename);
|
||||||
|
bookmarksFile.setPermissions(bookmarksFile.permissions() | QFile::WriteUser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
readFromFile();
|
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.
|
// 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
|
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) :
|
AvatarManager::AvatarManager(QObject* parent) :
|
||||||
_avatarsToFade(),
|
|
||||||
_myAvatar(new MyAvatar(qApp->thread()), [](MyAvatar* ptr) { ptr->deleteLater(); })
|
_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
|
// 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);
|
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;
|
_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.sessionUUIDChanged as sessionUUIDChanged
|
||||||
* @borrows AvatarList.processAvatarDataPacket as processAvatarDataPacket
|
* @borrows AvatarList.processAvatarDataPacket as processAvatarDataPacket
|
||||||
* @borrows AvatarList.processAvatarIdentityPacket as processAvatarIdentityPacket
|
* @borrows AvatarList.processAvatarIdentityPacket as processAvatarIdentityPacket
|
||||||
|
* @borrows AvatarList.processBulkAvatarTraits as processBulkAvatarTraits
|
||||||
* @borrows AvatarList.processKillAvatar as processKillAvatar
|
* @borrows AvatarList.processKillAvatar as processKillAvatar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -152,6 +153,13 @@ public:
|
||||||
const QVector<EntityItemID>& avatarsToInclude,
|
const QVector<EntityItemID>& avatarsToInclude,
|
||||||
const QVector<EntityItemID>& avatarsToDiscard);
|
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,
|
Q_INVOKABLE ParabolaToAvatarIntersectionResult findParabolaIntersectionVector(const PickParabola& pick,
|
||||||
const QVector<EntityItemID>& avatarsToInclude,
|
const QVector<EntityItemID>& avatarsToInclude,
|
||||||
const QVector<EntityItemID>& avatarsToDiscard);
|
const QVector<EntityItemID>& avatarsToDiscard);
|
||||||
|
@ -176,7 +184,7 @@ public:
|
||||||
* than iterating over each avatar and obtaining data about them in JavaScript, as that method
|
* 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.
|
* locks and unlocks each avatar's data structure potentially hundreds of times per update tick.
|
||||||
* @function AvatarManager.getPalData
|
* @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
|
* which you want to get PAL data
|
||||||
* @returns {object}
|
* @returns {object}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -122,7 +122,6 @@ MyAvatar::MyAvatar(QThread* thread) :
|
||||||
_goToOrientation(),
|
_goToOrientation(),
|
||||||
_prevShouldDrawHead(true),
|
_prevShouldDrawHead(true),
|
||||||
_audioListenerMode(FROM_HEAD),
|
_audioListenerMode(FROM_HEAD),
|
||||||
_hmdAtRestDetector(glm::vec3(0), glm::quat()),
|
|
||||||
_dominantHandSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "dominantHand", DOMINANT_RIGHT_HAND),
|
_dominantHandSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "dominantHand", DOMINANT_RIGHT_HAND),
|
||||||
_headPitchSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "", 0.0f),
|
_headPitchSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "", 0.0f),
|
||||||
_scaleSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "scale", _targetScale),
|
_scaleSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "scale", _targetScale),
|
||||||
|
@ -702,6 +701,46 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
// before we perform rig animations and IK.
|
// before we perform rig animations and IK.
|
||||||
updateSensorToWorldMatrix();
|
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");
|
PerformanceTimer perfTimer("skeleton");
|
||||||
|
|
||||||
|
@ -1941,7 +1980,7 @@ void MyAvatar::updateMotors() {
|
||||||
horizontalMotorTimescale = FLYING_MOTOR_TIMESCALE;
|
horizontalMotorTimescale = FLYING_MOTOR_TIMESCALE;
|
||||||
verticalMotorTimescale = FLYING_MOTOR_TIMESCALE;
|
verticalMotorTimescale = FLYING_MOTOR_TIMESCALE;
|
||||||
} else {
|
} else {
|
||||||
horizontalMotorTimescale = WALKING_MOTOR_TIMESCALE;
|
horizontalMotorTimescale = WALKING_MOTOR_TIMESCALE * getSensorToWorldScale();
|
||||||
verticalMotorTimescale = INVALID_MOTOR_TIMESCALE;
|
verticalMotorTimescale = INVALID_MOTOR_TIMESCALE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -629,8 +629,6 @@ public:
|
||||||
|
|
||||||
const MyHead* getMyHead() const;
|
const MyHead* getMyHead() const;
|
||||||
|
|
||||||
Q_INVOKABLE void toggleSmoothPoleVectors() { _skeletonModel->getRig().toggleSmoothPoleVectors(); };
|
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Get the current position of the avatar's "Head" joint.
|
* Get the current position of the avatar's "Head" joint.
|
||||||
* @function MyAvatar.getHeadPosition
|
* @function MyAvatar.getHeadPosition
|
||||||
|
@ -951,50 +949,72 @@ public:
|
||||||
void removeWearableAvatarEntities();
|
void removeWearableAvatarEntities();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* Check whether your avatar is flying or not.
|
||||||
* @function MyAvatar.isFlying
|
* @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();
|
Q_INVOKABLE bool isFlying();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* Check whether your avatar is in the air or not.
|
||||||
* @function MyAvatar.isInAir
|
* @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();
|
Q_INVOKABLE bool isInAir();
|
||||||
|
|
||||||
/**jsdoc
|
/**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
|
* @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);
|
Q_INVOKABLE void setFlyingEnabled(bool enabled);
|
||||||
|
|
||||||
/**jsdoc
|
/**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
|
* @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();
|
Q_INVOKABLE bool getFlyingEnabled();
|
||||||
|
|
||||||
/**jsdoc
|
/**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
|
* @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);
|
Q_INVOKABLE void setFlyingDesktopPref(bool enabled);
|
||||||
|
|
||||||
/**jsdoc
|
/**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
|
* @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();
|
Q_INVOKABLE bool getFlyingDesktopPref();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function MyAvatar.setFlyingDesktopPref
|
* Set your preference for flying in HMD display mode. Note that your ability to fly also depends on whether the domain
|
||||||
* @param {boolean} enabled
|
* 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);
|
Q_INVOKABLE void setFlyingHMDPref(bool enabled);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function MyAvatar.getFlyingDesktopPref
|
* Get your preference for flying in HMD display mode. Note that your ability to fly also depends on whether the domain
|
||||||
* @returns {boolean}
|
* 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();
|
Q_INVOKABLE bool getFlyingHMDPref();
|
||||||
|
|
||||||
|
@ -1766,8 +1786,8 @@ private:
|
||||||
glm::vec3 _customListenPosition;
|
glm::vec3 _customListenPosition;
|
||||||
glm::quat _customListenOrientation;
|
glm::quat _customListenOrientation;
|
||||||
|
|
||||||
AtRestDetector _hmdAtRestDetector;
|
AtRestDetector _leftHandAtRestDetector;
|
||||||
bool _lastIsMoving { false };
|
AtRestDetector _rightHandAtRestDetector;
|
||||||
|
|
||||||
// all poses are in sensor-frame
|
// all poses are in sensor-frame
|
||||||
std::map<controller::Action, controller::Pose> _controllerPoseMap;
|
std::map<controller::Action, controller::Pose> _controllerPoseMap;
|
||||||
|
|
|
@ -46,7 +46,7 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) {
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 hipsMat;
|
glm::mat4 hipsMat;
|
||||||
if (myAvatar->getCenterOfGravityModelEnabled() && !isFlying && !(myAvatar->getIsInWalkingState())) {
|
if (myAvatar->getCenterOfGravityModelEnabled() && !isFlying && !(myAvatar->getIsInWalkingState()) && myAvatar->getHMDLeanRecenterEnabled()) {
|
||||||
// then we use center of gravity model
|
// then we use center of gravity model
|
||||||
hipsMat = myAvatar->deriveBodyUsingCgModel();
|
hipsMat = myAvatar->deriveBodyUsingCgModel();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -11,12 +11,12 @@
|
||||||
|
|
||||||
#include "AvatarMotionState.h"
|
#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 glm::u8vec3 NO_MODEL_COLOR(0xe3, 0xe3, 0xe3);
|
||||||
const xColor LOAD_MODEL_COLOR(0xef, 0x93, 0xd1);
|
const glm::u8vec3 LOAD_MODEL_COLOR(0xef, 0x93, 0xd1);
|
||||||
const xColor LOAD_SUCCESS_COLOR(0x1f, 0xc6, 0xa6);
|
const glm::u8vec3 LOAD_SUCCESS_COLOR(0x1f, 0xc6, 0xa6);
|
||||||
const xColor LOAD_FAILURE_COLOR(0xc6, 0x21, 0x47);
|
const glm::u8vec3 LOAD_FAILURE_COLOR(0xc6, 0x21, 0x47);
|
||||||
switch (loadingStatus) {
|
switch (loadingStatus) {
|
||||||
case Avatar::LoadingStatus::NoModel:
|
case Avatar::LoadingStatus::NoModel:
|
||||||
return NO_MODEL_COLOR;
|
return NO_MODEL_COLOR;
|
||||||
|
|
|
@ -52,8 +52,7 @@ void ParabolaPointer::editRenderStatePath(const std::string& state, const QVaria
|
||||||
if (!pathMap.isEmpty()) {
|
if (!pathMap.isEmpty()) {
|
||||||
enabled = true;
|
enabled = true;
|
||||||
if (pathMap["color"].isValid()) {
|
if (pathMap["color"].isValid()) {
|
||||||
bool valid;
|
color = toGlm(u8vec3FromVariant(pathMap["color"]));
|
||||||
color = toGlm(xColorFromVariant(pathMap["color"], valid));
|
|
||||||
}
|
}
|
||||||
if (pathMap["alpha"].isValid()) {
|
if (pathMap["alpha"].isValid()) {
|
||||||
alpha = pathMap["alpha"].toFloat();
|
alpha = pathMap["alpha"].toFloat();
|
||||||
|
@ -250,8 +249,7 @@ std::shared_ptr<StartEndRenderState> ParabolaPointer::buildRenderState(const QVa
|
||||||
enabled = true;
|
enabled = true;
|
||||||
QVariantMap pathMap = propMap["path"].toMap();
|
QVariantMap pathMap = propMap["path"].toMap();
|
||||||
if (pathMap["color"].isValid()) {
|
if (pathMap["color"].isValid()) {
|
||||||
bool valid;
|
color = toGlm(u8vec3FromVariant(pathMap["color"]));
|
||||||
color = toGlm(xColorFromVariant(pathMap["color"], valid));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pathMap["alpha"].isValid()) {
|
if (pathMap["alpha"].isValid()) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ class StartEndRenderState {
|
||||||
public:
|
public:
|
||||||
StartEndRenderState() {}
|
StartEndRenderState() {}
|
||||||
StartEndRenderState(const OverlayID& startID, const OverlayID& endID);
|
StartEndRenderState(const OverlayID& startID, const OverlayID& endID);
|
||||||
virtual ~StartEndRenderState() {}
|
virtual ~StartEndRenderState() = default;
|
||||||
|
|
||||||
const OverlayID& getStartID() const { return _startID; }
|
const OverlayID& getStartID() const { return _startID; }
|
||||||
const OverlayID& getEndID() const { return _endID; }
|
const OverlayID& getEndID() const { return _endID; }
|
||||||
|
|
|
@ -421,7 +421,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
|
||||||
auto colorVariant = properties["outlineUnoccludedColor"];
|
auto colorVariant = properties["outlineUnoccludedColor"];
|
||||||
if (colorVariant.isValid()) {
|
if (colorVariant.isValid()) {
|
||||||
bool isValid;
|
bool isValid;
|
||||||
auto color = xColorFromVariant(colorVariant, isValid);
|
auto color = u8vec3FromVariant(colorVariant, isValid);
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
_style._outlineUnoccluded.color = toGlm(color);
|
_style._outlineUnoccluded.color = toGlm(color);
|
||||||
}
|
}
|
||||||
|
@ -429,7 +429,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
|
||||||
colorVariant = properties["outlineOccludedColor"];
|
colorVariant = properties["outlineOccludedColor"];
|
||||||
if (colorVariant.isValid()) {
|
if (colorVariant.isValid()) {
|
||||||
bool isValid;
|
bool isValid;
|
||||||
auto color = xColorFromVariant(colorVariant, isValid);
|
auto color = u8vec3FromVariant(colorVariant, isValid);
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
_style._outlineOccluded.color = toGlm(color);
|
_style._outlineOccluded.color = toGlm(color);
|
||||||
}
|
}
|
||||||
|
@ -437,7 +437,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
|
||||||
colorVariant = properties["fillUnoccludedColor"];
|
colorVariant = properties["fillUnoccludedColor"];
|
||||||
if (colorVariant.isValid()) {
|
if (colorVariant.isValid()) {
|
||||||
bool isValid;
|
bool isValid;
|
||||||
auto color = xColorFromVariant(colorVariant, isValid);
|
auto color = u8vec3FromVariant(colorVariant, isValid);
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
_style._fillUnoccluded.color = toGlm(color);
|
_style._fillUnoccluded.color = toGlm(color);
|
||||||
}
|
}
|
||||||
|
@ -445,7 +445,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
|
||||||
colorVariant = properties["fillOccludedColor"];
|
colorVariant = properties["fillOccludedColor"];
|
||||||
if (colorVariant.isValid()) {
|
if (colorVariant.isValid()) {
|
||||||
bool isValid;
|
bool isValid;
|
||||||
auto color = xColorFromVariant(colorVariant, isValid);
|
auto color = u8vec3FromVariant(colorVariant, isValid);
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
_style._fillOccluded.color = toGlm(color);
|
_style._fillOccluded.color = toGlm(color);
|
||||||
}
|
}
|
||||||
|
@ -497,10 +497,11 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
|
||||||
QVariantMap SelectionHighlightStyle::toVariantMap() const {
|
QVariantMap SelectionHighlightStyle::toVariantMap() const {
|
||||||
QVariantMap properties;
|
QVariantMap properties;
|
||||||
|
|
||||||
properties["outlineUnoccludedColor"] = xColorToVariant(xColorFromGlm(_style._outlineUnoccluded.color));
|
const float MAX_COLOR = 255.0f;
|
||||||
properties["outlineOccludedColor"] = xColorToVariant(xColorFromGlm(_style._outlineOccluded.color));
|
properties["outlineUnoccludedColor"] = u8vec3ColortoVariant(_style._outlineUnoccluded.color * MAX_COLOR);
|
||||||
properties["fillUnoccludedColor"] = xColorToVariant(xColorFromGlm(_style._fillUnoccluded.color));
|
properties["outlineOccludedColor"] = u8vec3ColortoVariant(_style._outlineOccluded.color * MAX_COLOR);
|
||||||
properties["fillOccludedColor"] = xColorToVariant(xColorFromGlm(_style._fillOccluded.color));
|
properties["fillUnoccludedColor"] = u8vec3ColortoVariant(_style._fillUnoccluded.color * MAX_COLOR);
|
||||||
|
properties["fillOccludedColor"] = u8vec3ColortoVariant(_style._fillOccluded.color * MAX_COLOR);
|
||||||
|
|
||||||
properties["outlineUnoccludedAlpha"] = _style._outlineUnoccluded.alpha;
|
properties["outlineUnoccludedAlpha"] = _style._outlineUnoccluded.alpha;
|
||||||
properties["outlineOccludedAlpha"] = _style._outlineOccluded.alpha;
|
properties["outlineOccludedAlpha"] = _style._outlineOccluded.alpha;
|
||||||
|
|
|
@ -54,6 +54,9 @@ WindowScriptingInterface::WindowScriptingInterface() {
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(qApp->getWindow(), &MainWindow::windowGeometryChanged, this, &WindowScriptingInterface::onWindowGeometryChanged);
|
connect(qApp->getWindow(), &MainWindow::windowGeometryChanged, this, &WindowScriptingInterface::onWindowGeometryChanged);
|
||||||
|
connect(qApp, &Application::interstitialModeChanged, [this] (bool interstitialMode) {
|
||||||
|
emit interstitialModeChanged(interstitialMode);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowScriptingInterface::~WindowScriptingInterface() {
|
WindowScriptingInterface::~WindowScriptingInterface() {
|
||||||
|
|
|
@ -619,6 +619,14 @@ signals:
|
||||||
*/
|
*/
|
||||||
void redirectErrorStateChanged(bool isInErrorState);
|
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
|
/**jsdoc
|
||||||
* Triggered when a still snapshot has been taken by calling {@link Window.takeSnapshot|takeSnapshot} with
|
* Triggered when a still snapshot has been taken by calling {@link Window.takeSnapshot|takeSnapshot} with
|
||||||
* <code>includeAnimated = false</code> or {@link Window.takeSecondaryCameraSnapshot|takeSecondaryCameraSnapshot}.
|
* <code>includeAnimated = false</code> or {@link Window.takeSecondaryCameraSnapshot|takeSecondaryCameraSnapshot}.
|
||||||
|
|
|
@ -267,8 +267,8 @@ void Stats::updateStats(bool force) {
|
||||||
|
|
||||||
auto loadingRequests = ResourceCache::getLoadingRequests();
|
auto loadingRequests = ResourceCache::getLoadingRequests();
|
||||||
STAT_UPDATE(downloads, loadingRequests.size());
|
STAT_UPDATE(downloads, loadingRequests.size());
|
||||||
STAT_UPDATE(downloadLimit, ResourceCache::getRequestLimit())
|
STAT_UPDATE(downloadLimit, (int)ResourceCache::getRequestLimit())
|
||||||
STAT_UPDATE(downloadsPending, ResourceCache::getPendingRequestCount());
|
STAT_UPDATE(downloadsPending, (int)ResourceCache::getPendingRequestCount());
|
||||||
STAT_UPDATE(processing, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
|
STAT_UPDATE(processing, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
|
||||||
STAT_UPDATE(processingPending, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
|
STAT_UPDATE(processingPending, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
|
||||||
|
|
||||||
|
|
|
@ -191,8 +191,6 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) {
|
||||||
|
|
||||||
if (properties["parentID"].isValid()) {
|
if (properties["parentID"].isValid()) {
|
||||||
setParentID(QUuid(properties["parentID"].toString()));
|
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;
|
needRenderItemUpdate = true;
|
||||||
}
|
}
|
||||||
if (properties["parentJointIndex"].isValid()) {
|
if (properties["parentJointIndex"].isValid()) {
|
||||||
|
|
|
@ -75,7 +75,6 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
||||||
const float FULL_CIRCLE = 360.0f;
|
const float FULL_CIRCLE = 360.0f;
|
||||||
const float SLICES = 180.0f; // The amount of segment to create the circle
|
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 SLICE_ANGLE_RADIANS = glm::radians(FULL_CIRCLE / SLICES);
|
||||||
const float MAX_COLOR = 255.0f;
|
|
||||||
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
|
||||||
|
@ -247,14 +246,9 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xColor majorColorX = getMajorTickMarksColor();
|
glm::vec4 majorColor(toGlm(getMajorTickMarksColor()), alpha);
|
||||||
glm::vec4 majorColor(majorColorX.red / MAX_COLOR, majorColorX.green / MAX_COLOR, majorColorX.blue / MAX_COLOR, alpha);
|
|
||||||
|
|
||||||
geometryCache->updateVertices(_majorTicksVerticesID, majorPoints, majorColor);
|
geometryCache->updateVertices(_majorTicksVerticesID, majorPoints, majorColor);
|
||||||
|
glm::vec4 minorColor(toGlm(getMinorTickMarksColor()), alpha);
|
||||||
xColor minorColorX = getMinorTickMarksColor();
|
|
||||||
glm::vec4 minorColor(minorColorX.red / MAX_COLOR, minorColorX.green / MAX_COLOR, minorColorX.blue / MAX_COLOR, alpha);
|
|
||||||
|
|
||||||
geometryCache->updateVertices(_minorTicksVerticesID, minorPoints, minorColor);
|
geometryCache->updateVertices(_minorTicksVerticesID, minorPoints, minorColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,8 +274,8 @@ template<typename T> T fromVariant(const QVariant& v, bool& valid) {
|
||||||
return qvariant_cast<T>(v);
|
return qvariant_cast<T>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> xColor fromVariant(const QVariant& v, bool& valid) {
|
template<> glm::u8vec3 fromVariant(const QVariant& v, bool& valid) {
|
||||||
return xColorFromVariant(v, valid);
|
return u8vec3FromVariant(v, valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -344,11 +338,11 @@ void Circle3DOverlay::setProperties(const QVariantMap& properties) {
|
||||||
_dirty |= updateIfValid(properties, "outerStartAlpha", _outerStartAlpha);
|
_dirty |= updateIfValid(properties, "outerStartAlpha", _outerStartAlpha);
|
||||||
_dirty |= updateIfValid(properties, "outerEndAlpha", _outerEndAlpha);
|
_dirty |= updateIfValid(properties, "outerEndAlpha", _outerEndAlpha);
|
||||||
|
|
||||||
_dirty |= updateIfValid<xColor>(properties, "color", { _innerStartColor, _innerEndColor, _outerStartColor, _outerEndColor });
|
_dirty |= updateIfValid<glm::u8vec3>(properties, "color", { _innerStartColor, _innerEndColor, _outerStartColor, _outerEndColor });
|
||||||
_dirty |= updateIfValid<xColor>(properties, "startColor", { _innerStartColor, _outerStartColor } );
|
_dirty |= updateIfValid<glm::u8vec3>(properties, "startColor", { _innerStartColor, _outerStartColor } );
|
||||||
_dirty |= updateIfValid<xColor>(properties, "endColor", { _innerEndColor, _outerEndColor } );
|
_dirty |= updateIfValid<glm::u8vec3>(properties, "endColor", { _innerEndColor, _outerEndColor } );
|
||||||
_dirty |= updateIfValid<xColor>(properties, "innerColor", { _innerStartColor, _innerEndColor } );
|
_dirty |= updateIfValid<glm::u8vec3>(properties, "innerColor", { _innerStartColor, _innerEndColor } );
|
||||||
_dirty |= updateIfValid<xColor>(properties, "outerColor", { _outerStartColor, _outerEndColor } );
|
_dirty |= updateIfValid<glm::u8vec3>(properties, "outerColor", { _outerStartColor, _outerEndColor } );
|
||||||
_dirty |= updateIfValid(properties, "innerStartColor", _innerStartColor);
|
_dirty |= updateIfValid(properties, "innerStartColor", _innerStartColor);
|
||||||
_dirty |= updateIfValid(properties, "innerEndColor", _innerEndColor);
|
_dirty |= updateIfValid(properties, "innerEndColor", _innerEndColor);
|
||||||
_dirty |= updateIfValid(properties, "outerStartColor", _outerStartColor);
|
_dirty |= updateIfValid(properties, "outerStartColor", _outerStartColor);
|
||||||
|
@ -478,16 +472,16 @@ QVariant Circle3DOverlay::getProperty(const QString& property) {
|
||||||
return _innerRadius;
|
return _innerRadius;
|
||||||
}
|
}
|
||||||
if (property == "innerStartColor") {
|
if (property == "innerStartColor") {
|
||||||
return xColorToVariant(_innerStartColor);
|
return u8vec3ColortoVariant(_innerStartColor);
|
||||||
}
|
}
|
||||||
if (property == "innerEndColor") {
|
if (property == "innerEndColor") {
|
||||||
return xColorToVariant(_innerEndColor);
|
return u8vec3ColortoVariant(_innerEndColor);
|
||||||
}
|
}
|
||||||
if (property == "outerStartColor") {
|
if (property == "outerStartColor") {
|
||||||
return xColorToVariant(_outerStartColor);
|
return u8vec3ColortoVariant(_outerStartColor);
|
||||||
}
|
}
|
||||||
if (property == "outerEndColor") {
|
if (property == "outerEndColor") {
|
||||||
return xColorToVariant(_outerEndColor);
|
return u8vec3ColortoVariant(_outerEndColor);
|
||||||
}
|
}
|
||||||
if (property == "innerStartAlpha") {
|
if (property == "innerStartAlpha") {
|
||||||
return _innerStartAlpha;
|
return _innerStartAlpha;
|
||||||
|
@ -517,10 +511,10 @@ QVariant Circle3DOverlay::getProperty(const QString& property) {
|
||||||
return _minorTickMarksLength;
|
return _minorTickMarksLength;
|
||||||
}
|
}
|
||||||
if (property == "majorTickMarksColor") {
|
if (property == "majorTickMarksColor") {
|
||||||
return xColorToVariant(_majorTickMarksColor);
|
return u8vec3ColortoVariant(_majorTickMarksColor);
|
||||||
}
|
}
|
||||||
if (property == "minorTickMarksColor") {
|
if (property == "minorTickMarksColor") {
|
||||||
return xColorToVariant(_minorTickMarksColor);
|
return u8vec3ColortoVariant(_minorTickMarksColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Planar3DOverlay::getProperty(property);
|
return Planar3DOverlay::getProperty(property);
|
||||||
|
|
|
@ -39,8 +39,8 @@ public:
|
||||||
float getMinorTickMarksAngle() const { return _minorTickMarksAngle; }
|
float getMinorTickMarksAngle() const { return _minorTickMarksAngle; }
|
||||||
float getMajorTickMarksLength() const { return _majorTickMarksLength; }
|
float getMajorTickMarksLength() const { return _majorTickMarksLength; }
|
||||||
float getMinorTickMarksLength() const { return _minorTickMarksLength; }
|
float getMinorTickMarksLength() const { return _minorTickMarksLength; }
|
||||||
xColor getMajorTickMarksColor() const { return _majorTickMarksColor; }
|
glm::u8vec3 getMajorTickMarksColor() const { return _majorTickMarksColor; }
|
||||||
xColor getMinorTickMarksColor() const { return _minorTickMarksColor; }
|
glm::u8vec3 getMinorTickMarksColor() const { return _minorTickMarksColor; }
|
||||||
|
|
||||||
void setStartAt(float value) { _startAt = value; }
|
void setStartAt(float value) { _startAt = value; }
|
||||||
void setEndAt(float value) { _endAt = value; }
|
void setEndAt(float value) { _endAt = value; }
|
||||||
|
@ -51,8 +51,8 @@ public:
|
||||||
void setMinorTickMarksAngle(float value) { _minorTickMarksAngle = value; }
|
void setMinorTickMarksAngle(float value) { _minorTickMarksAngle = value; }
|
||||||
void setMajorTickMarksLength(float value) { _majorTickMarksLength = value; }
|
void setMajorTickMarksLength(float value) { _majorTickMarksLength = value; }
|
||||||
void setMinorTickMarksLength(float value) { _minorTickMarksLength = value; }
|
void setMinorTickMarksLength(float value) { _minorTickMarksLength = value; }
|
||||||
void setMajorTickMarksColor(const xColor& value) { _majorTickMarksColor = value; }
|
void setMajorTickMarksColor(const glm::u8vec3& value) { _majorTickMarksColor = value; }
|
||||||
void setMinorTickMarksColor(const xColor& value) { _minorTickMarksColor = value; }
|
void setMinorTickMarksColor(const glm::u8vec3& value) { _minorTickMarksColor = value; }
|
||||||
|
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal, bool precisionPicking = false) override;
|
BoxFace& face, glm::vec3& surfaceNormal, bool precisionPicking = false) override;
|
||||||
|
@ -67,10 +67,10 @@ protected:
|
||||||
float _outerRadius { 1 };
|
float _outerRadius { 1 };
|
||||||
float _innerRadius { 0 };
|
float _innerRadius { 0 };
|
||||||
|
|
||||||
xColor _innerStartColor { DEFAULT_OVERLAY_COLOR };
|
glm::u8vec3 _innerStartColor { DEFAULT_OVERLAY_COLOR };
|
||||||
xColor _innerEndColor { DEFAULT_OVERLAY_COLOR };
|
glm::u8vec3 _innerEndColor { DEFAULT_OVERLAY_COLOR };
|
||||||
xColor _outerStartColor { DEFAULT_OVERLAY_COLOR };
|
glm::u8vec3 _outerStartColor { DEFAULT_OVERLAY_COLOR };
|
||||||
xColor _outerEndColor { DEFAULT_OVERLAY_COLOR };
|
glm::u8vec3 _outerEndColor { DEFAULT_OVERLAY_COLOR };
|
||||||
float _innerStartAlpha { DEFAULT_ALPHA };
|
float _innerStartAlpha { DEFAULT_ALPHA };
|
||||||
float _innerEndAlpha { DEFAULT_ALPHA };
|
float _innerEndAlpha { DEFAULT_ALPHA };
|
||||||
float _outerStartAlpha { DEFAULT_ALPHA };
|
float _outerStartAlpha { DEFAULT_ALPHA };
|
||||||
|
@ -81,8 +81,8 @@ protected:
|
||||||
float _minorTickMarksAngle { 0 };
|
float _minorTickMarksAngle { 0 };
|
||||||
float _majorTickMarksLength { 0 };
|
float _majorTickMarksLength { 0 };
|
||||||
float _minorTickMarksLength { 0 };
|
float _minorTickMarksLength { 0 };
|
||||||
xColor _majorTickMarksColor { DEFAULT_OVERLAY_COLOR };
|
glm::u8vec3 _majorTickMarksColor { DEFAULT_OVERLAY_COLOR };
|
||||||
xColor _minorTickMarksColor { DEFAULT_OVERLAY_COLOR };
|
glm::u8vec3 _minorTickMarksColor { DEFAULT_OVERLAY_COLOR };
|
||||||
gpu::Primitive _solidPrimitive { gpu::TRIANGLE_FAN };
|
gpu::Primitive _solidPrimitive { gpu::TRIANGLE_FAN };
|
||||||
int _quadVerticesID { 0 };
|
int _quadVerticesID { 0 };
|
||||||
int _lineVerticesID { 0 };
|
int _lineVerticesID { 0 };
|
||||||
|
|
|
@ -83,7 +83,7 @@ ContextOverlayInterface::ContextOverlayInterface() {
|
||||||
_challengeOwnershipTimeoutTimer.setSingleShot(true);
|
_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_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_SIZE = 0.09f; // in meters, same x and y dims
|
||||||
static const float CONTEXT_OVERLAY_OFFSET_DISTANCE = 0.1f;
|
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 cameraPosition = qApp->getCamera().getPosition();
|
||||||
glm::vec3 entityDimensions = entityProperties.getDimensions();
|
glm::vec3 entityDimensions = entityProperties.getDimensions();
|
||||||
glm::vec3 entityPosition = entityProperties.getPosition();
|
glm::vec3 entityPosition = entityProperties.getPosition();
|
||||||
|
glm::vec3 registrationPoint = entityProperties.getRegistrationPoint();
|
||||||
glm::vec3 contextOverlayPosition = entityProperties.getPosition();
|
glm::vec3 contextOverlayPosition = entityProperties.getPosition();
|
||||||
glm::vec2 contextOverlayDimensions;
|
glm::vec2 contextOverlayDimensions;
|
||||||
|
|
||||||
// Update the position of the overlay if the registration point of the entity
|
// Update the position of the overlay if the registration point of the entity
|
||||||
// isn't default
|
// isn't default
|
||||||
if (entityProperties.getRegistrationPoint() != glm::vec3(0.5f)) {
|
if (registrationPoint != glm::vec3(0.5f)) {
|
||||||
glm::vec3 adjustPos = entityProperties.getRegistrationPoint() - glm::vec3(0.5f);
|
glm::vec3 adjustPos = registrationPoint - glm::vec3(0.5f);
|
||||||
entityPosition = entityPosition - (entityProperties.getRotation() * (adjustPos * entityProperties.getDimensions()));
|
entityPosition = entityPosition - (entityProperties.getRotation() * (adjustPos * entityDimensions));
|
||||||
}
|
}
|
||||||
|
|
||||||
enableEntityHighlight(entityItemID);
|
enableEntityHighlight(entityItemID);
|
||||||
|
|
|
@ -49,11 +49,8 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float alpha = getAlpha();
|
float alpha = getAlpha();
|
||||||
xColor color = getColor();
|
glm::u8vec3 color = getColor();
|
||||||
const float MAX_COLOR = 255.0f;
|
glm::vec4 cubeColor(toGlm(color), alpha);
|
||||||
glm::vec4 cubeColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
auto batch = args->_batch;
|
auto batch = args->_batch;
|
||||||
if (batch) {
|
if (batch) {
|
||||||
|
|
|
@ -57,11 +57,9 @@ void Grid3DOverlay::render(RenderArgs* args) {
|
||||||
return; // do nothing if we're not visible
|
return; // do nothing if we're not visible
|
||||||
}
|
}
|
||||||
|
|
||||||
const float MAX_COLOR = 255.0f;
|
|
||||||
|
|
||||||
float alpha = getAlpha();
|
float alpha = getAlpha();
|
||||||
xColor color = getColor();
|
glm::u8vec3 color = getColor();
|
||||||
glm::vec4 gridColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
glm::vec4 gridColor(toGlm(color), alpha);
|
||||||
|
|
||||||
auto batch = args->_batch;
|
auto batch = args->_batch;
|
||||||
|
|
||||||
|
|
|
@ -107,17 +107,16 @@ void Image3DOverlay::render(RenderArgs* args) {
|
||||||
glm::vec2 texCoordBottomRight((fromImage.x() + fromImage.width() - 0.5f) / imageWidth,
|
glm::vec2 texCoordBottomRight((fromImage.x() + fromImage.width() - 0.5f) / imageWidth,
|
||||||
(fromImage.y() + fromImage.height() - 0.5f) / imageHeight);
|
(fromImage.y() + fromImage.height() - 0.5f) / imageHeight);
|
||||||
|
|
||||||
const float MAX_COLOR = 255.0f;
|
|
||||||
xColor color = getColor();
|
|
||||||
float alpha = getAlpha();
|
float alpha = getAlpha();
|
||||||
|
glm::u8vec3 color = getColor();
|
||||||
|
glm::vec4 imageColor(toGlm(color), alpha);
|
||||||
|
|
||||||
batch->setModelTransform(getRenderTransform());
|
batch->setModelTransform(getRenderTransform());
|
||||||
batch->setResourceTexture(0, _texture->getGPUTexture());
|
batch->setResourceTexture(0, _texture->getGPUTexture());
|
||||||
|
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(
|
DependencyManager::get<GeometryCache>()->renderQuad(
|
||||||
*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
||||||
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha),
|
imageColor, _geometryId
|
||||||
_geometryId
|
|
||||||
);
|
);
|
||||||
|
|
||||||
batch->setResourceTexture(0, nullptr); // restore default white color after me
|
batch->setResourceTexture(0, nullptr); // restore default white color after me
|
||||||
|
|
|
@ -128,9 +128,8 @@ void Line3DOverlay::render(RenderArgs* args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float alpha = getAlpha();
|
float alpha = getAlpha();
|
||||||
xColor color = getColor();
|
glm::u8vec3 color = getColor();
|
||||||
const float MAX_COLOR = 255.0f;
|
glm::vec4 colorv4(toGlm(color), alpha);
|
||||||
glm::vec4 colorv4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
|
||||||
auto batch = args->_batch;
|
auto batch = args->_batch;
|
||||||
if (batch) {
|
if (batch) {
|
||||||
batch->setModelTransform(Transform());
|
batch->setModelTransform(Transform());
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
#include "Application.h"
|
#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;
|
const float Overlay::DEFAULT_ALPHA = 0.7f;
|
||||||
|
|
||||||
Overlay::Overlay() :
|
Overlay::Overlay() :
|
||||||
|
@ -57,7 +57,7 @@ Overlay::~Overlay() {
|
||||||
|
|
||||||
void Overlay::setProperties(const QVariantMap& properties) {
|
void Overlay::setProperties(const QVariantMap& properties) {
|
||||||
bool valid;
|
bool valid;
|
||||||
auto color = xColorFromVariant(properties["color"], valid);
|
auto color = u8vec3FromVariant(properties["color"], valid);
|
||||||
if (valid) {
|
if (valid) {
|
||||||
_color = color;
|
_color = color;
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ QVariant Overlay::getProperty(const QString& property) {
|
||||||
return QVariant(getType());
|
return QVariant(getType());
|
||||||
}
|
}
|
||||||
if (property == "color") {
|
if (property == "color") {
|
||||||
return xColorToVariant(_color);
|
return u8vec3ColortoVariant(_color);
|
||||||
}
|
}
|
||||||
if (property == "alpha") {
|
if (property == "alpha") {
|
||||||
return _alpha;
|
return _alpha;
|
||||||
|
@ -143,21 +143,21 @@ QVariant Overlay::getProperty(const QString& property) {
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
xColor Overlay::getColor() {
|
glm::u8vec3 Overlay::getColor() {
|
||||||
if (_colorPulse == 0.0f) {
|
if (_colorPulse == 0.0f) {
|
||||||
return _color;
|
return _color;
|
||||||
}
|
}
|
||||||
|
|
||||||
float pulseLevel = updatePulse();
|
float pulseLevel = updatePulse();
|
||||||
xColor result = _color;
|
glm::u8vec3 result = _color;
|
||||||
if (_colorPulse < 0.0f) {
|
if (_colorPulse < 0.0f) {
|
||||||
result.red *= (1.0f - pulseLevel);
|
result.x *= (1.0f - pulseLevel);
|
||||||
result.green *= (1.0f - pulseLevel);
|
result.y *= (1.0f - pulseLevel);
|
||||||
result.blue *= (1.0f - pulseLevel);
|
result.z *= (1.0f - pulseLevel);
|
||||||
} else {
|
} else {
|
||||||
result.red *= pulseLevel;
|
result.x *= pulseLevel;
|
||||||
result.green *= pulseLevel;
|
result.y *= pulseLevel;
|
||||||
result.blue *= pulseLevel;
|
result.z *= pulseLevel;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
#ifndef hifi_Overlay_h
|
#ifndef hifi_Overlay_h
|
||||||
#define 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>
|
#include <render/Scene.h>
|
||||||
|
|
||||||
class OverlayID : public QUuid {
|
class OverlayID : public QUuid {
|
||||||
|
@ -59,7 +57,7 @@ public:
|
||||||
virtual bool isTransparent() { return getAlphaPulse() != 0.0f || getAlpha() != 1.0f; };
|
virtual bool isTransparent() { return getAlphaPulse() != 0.0f || getAlpha() != 1.0f; };
|
||||||
virtual bool getIsVisibleInSecondaryCamera() const { return false; }
|
virtual bool getIsVisibleInSecondaryCamera() const { return false; }
|
||||||
|
|
||||||
xColor getColor();
|
glm::u8vec3 getColor();
|
||||||
float getAlpha();
|
float getAlpha();
|
||||||
|
|
||||||
float getPulseMax() const { return _pulseMax; }
|
float getPulseMax() const { return _pulseMax; }
|
||||||
|
@ -73,7 +71,7 @@ public:
|
||||||
// setters
|
// setters
|
||||||
virtual void setVisible(bool visible) { _visible = visible; }
|
virtual void setVisible(bool visible) { _visible = visible; }
|
||||||
void setDrawHUDLayer(bool drawHUDLayer);
|
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 setAlpha(float alpha) { _alpha = alpha; }
|
||||||
|
|
||||||
void setPulseMax(float value) { _pulseMax = value; }
|
void setPulseMax(float value) { _pulseMax = value; }
|
||||||
|
@ -115,12 +113,12 @@ protected:
|
||||||
float _alphaPulse; // ratio of the pulse to the alpha
|
float _alphaPulse; // ratio of the pulse to the alpha
|
||||||
float _colorPulse; // ratio of the pulse to the color
|
float _colorPulse; // ratio of the pulse to the color
|
||||||
|
|
||||||
xColor _color;
|
glm::u8vec3 _color;
|
||||||
bool _visible; // should the overlay be drawn at all
|
bool _visible; // should the overlay be drawn at all
|
||||||
|
|
||||||
unsigned int _stackOrder { 0 };
|
unsigned int _stackOrder { 0 };
|
||||||
|
|
||||||
static const xColor DEFAULT_OVERLAY_COLOR;
|
static const glm::u8vec3 DEFAULT_OVERLAY_COLOR;
|
||||||
static const float DEFAULT_ALPHA;
|
static const float DEFAULT_ALPHA;
|
||||||
|
|
||||||
std::unordered_map<std::string, graphics::MultiMaterial> _materials;
|
std::unordered_map<std::string, graphics::MultiMaterial> _materials;
|
||||||
|
|
|
@ -532,6 +532,8 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionVector(const PickRay
|
||||||
bool visibleOnly, bool collidableOnly) {
|
bool visibleOnly, bool collidableOnly) {
|
||||||
float bestDistance = std::numeric_limits<float>::max();
|
float bestDistance = std::numeric_limits<float>::max();
|
||||||
bool bestIsFront = false;
|
bool bestIsFront = false;
|
||||||
|
bool bestIsTablet = false;
|
||||||
|
auto tabletIDs = qApp->getTabletIDs();
|
||||||
|
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
RayToOverlayIntersectionResult result;
|
RayToOverlayIntersectionResult result;
|
||||||
|
@ -554,10 +556,11 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionVector(const PickRay
|
||||||
if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance,
|
if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance,
|
||||||
thisFace, thisSurfaceNormal, thisExtraInfo, precisionPicking)) {
|
thisFace, thisSurfaceNormal, thisExtraInfo, precisionPicking)) {
|
||||||
bool isDrawInFront = thisOverlay->getDrawInFront();
|
bool isDrawInFront = thisOverlay->getDrawInFront();
|
||||||
if ((bestIsFront && isDrawInFront && thisDistance < bestDistance)
|
bool isTablet = tabletIDs.contains(thisID);
|
||||||
|| (!bestIsFront && (isDrawInFront || thisDistance < bestDistance))) {
|
if ((isDrawInFront && !bestIsFront && !bestIsTablet)
|
||||||
|
|| ((isTablet || isDrawInFront || !bestIsFront) && thisDistance < bestDistance)) {
|
||||||
bestIsFront = isDrawInFront;
|
bestIsFront = isDrawInFront;
|
||||||
|
bestIsTablet = isTablet;
|
||||||
bestDistance = thisDistance;
|
bestDistance = thisDistance;
|
||||||
result.intersects = true;
|
result.intersects = true;
|
||||||
result.distance = thisDistance;
|
result.distance = thisDistance;
|
||||||
|
@ -629,9 +632,9 @@ QScriptValue RayToOverlayIntersectionResultToScriptValue(QScriptEngine* engine,
|
||||||
obj.setProperty("distance", value.distance);
|
obj.setProperty("distance", value.distance);
|
||||||
obj.setProperty("face", boxFaceToString(value.face));
|
obj.setProperty("face", boxFaceToString(value.face));
|
||||||
|
|
||||||
QScriptValue intersection = vec3toScriptValue(engine, value.intersection);
|
QScriptValue intersection = vec3ToScriptValue(engine, value.intersection);
|
||||||
obj.setProperty("intersection", intersection);
|
obj.setProperty("intersection", intersection);
|
||||||
QScriptValue surfaceNormal = vec3toScriptValue(engine, value.surfaceNormal);
|
QScriptValue surfaceNormal = vec3ToScriptValue(engine, value.surfaceNormal);
|
||||||
obj.setProperty("surfaceNormal", surfaceNormal);
|
obj.setProperty("surfaceNormal", surfaceNormal);
|
||||||
obj.setProperty("extraInfo", engine->toScriptValue(value.extraInfo));
|
obj.setProperty("extraInfo", engine->toScriptValue(value.extraInfo));
|
||||||
return obj;
|
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) {
|
bool Overlays::mousePressEvent(QMouseEvent* event) {
|
||||||
PerformanceTimer perfTimer("Overlays::mousePressEvent");
|
PerformanceTimer perfTimer("Overlays::mousePressEvent");
|
||||||
|
|
||||||
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
||||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray);
|
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(),
|
||||||
|
QVector<OverlayID>());
|
||||||
if (rayPickResult.intersects) {
|
if (rayPickResult.intersects) {
|
||||||
_currentClickingOnOverlayID = rayPickResult.overlayID;
|
_currentClickingOnOverlayID = rayPickResult.overlayID;
|
||||||
|
|
||||||
|
@ -901,7 +876,8 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) {
|
||||||
PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent");
|
PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent");
|
||||||
|
|
||||||
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
||||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray);
|
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(),
|
||||||
|
QVector<OverlayID>());
|
||||||
if (rayPickResult.intersects) {
|
if (rayPickResult.intersects) {
|
||||||
_currentClickingOnOverlayID = rayPickResult.overlayID;
|
_currentClickingOnOverlayID = rayPickResult.overlayID;
|
||||||
|
|
||||||
|
@ -964,7 +940,8 @@ bool Overlays::mouseReleaseEvent(QMouseEvent* event) {
|
||||||
PerformanceTimer perfTimer("Overlays::mouseReleaseEvent");
|
PerformanceTimer perfTimer("Overlays::mouseReleaseEvent");
|
||||||
|
|
||||||
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
||||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray);
|
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(),
|
||||||
|
QVector<OverlayID>());
|
||||||
if (rayPickResult.intersects) {
|
if (rayPickResult.intersects) {
|
||||||
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release);
|
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release);
|
||||||
mouseReleasePointerEvent(rayPickResult.overlayID, pointerEvent);
|
mouseReleasePointerEvent(rayPickResult.overlayID, pointerEvent);
|
||||||
|
@ -993,7 +970,8 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) {
|
||||||
PerformanceTimer perfTimer("Overlays::mouseMoveEvent");
|
PerformanceTimer perfTimer("Overlays::mouseMoveEvent");
|
||||||
|
|
||||||
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
PickRay ray = qApp->computePickRay(event->x(), event->y());
|
||||||
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray);
|
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(),
|
||||||
|
QVector<OverlayID>());
|
||||||
if (rayPickResult.intersects) {
|
if (rayPickResult.intersects) {
|
||||||
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move);
|
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move);
|
||||||
mouseMovePointerEvent(rayPickResult.overlayID, pointerEvent);
|
mouseMovePointerEvent(rayPickResult.overlayID, pointerEvent);
|
||||||
|
|
|
@ -44,8 +44,7 @@ void OverlayPropertyResultFromScriptValue(const QScriptValue& object, OverlayPro
|
||||||
const OverlayID UNKNOWN_OVERLAY_ID = OverlayID();
|
const OverlayID UNKNOWN_OVERLAY_ID = OverlayID();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* The result of a {@link PickRay} search using {@link Overlays.findRayIntersection|findRayIntersection} or
|
* The result of a {@link PickRay} search using {@link Overlays.findRayIntersection|findRayIntersection}.
|
||||||
* {@link Overlays.findRayIntersectionVector|findRayIntersectionVector}.
|
|
||||||
* @typedef {object} Overlays.RayToOverlayIntersectionResult
|
* @typedef {object} Overlays.RayToOverlayIntersectionResult
|
||||||
* @property {boolean} intersects - <code>true</code> if the {@link PickRay} intersected with a 3D overlay, otherwise
|
* @property {boolean} intersects - <code>true</code> if the {@link PickRay} intersected with a 3D overlay, otherwise
|
||||||
* <code>false</code>.
|
* <code>false</code>.
|
||||||
|
@ -383,7 +382,11 @@ public slots:
|
||||||
OverlayPropertyResult getOverlaysProperties(const QVariant& overlaysProperties);
|
OverlayPropertyResult getOverlaysProperties(const QVariant& overlaysProperties);
|
||||||
|
|
||||||
/**jsdoc
|
/**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
|
* @function Overlays.findRayIntersection
|
||||||
* @param {PickRay} pickRay - The PickRay to use for finding overlays.
|
* @param {PickRay} pickRay - The PickRay to use for finding overlays.
|
||||||
* @param {boolean} [precisionPicking=false] - <em>Unused</em>; exists to match Entity API.
|
* @param {boolean} [precisionPicking=false] - <em>Unused</em>; exists to match Entity API.
|
||||||
|
@ -750,8 +753,6 @@ private:
|
||||||
OverlayID _currentClickingOnOverlayID { UNKNOWN_OVERLAY_ID };
|
OverlayID _currentClickingOnOverlayID { UNKNOWN_OVERLAY_ID };
|
||||||
OverlayID _currentHoverOverOverlayID { UNKNOWN_OVERLAY_ID };
|
OverlayID _currentHoverOverOverlayID { UNKNOWN_OVERLAY_ID };
|
||||||
|
|
||||||
RayToOverlayIntersectionResult findRayIntersectionForMouseEvent(PickRay ray);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void mousePressPointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
void mousePressPointerEvent(const OverlayID& overlayID, const PointerEvent& event);
|
||||||
void mouseMovePointerEvent(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) {
|
QVariant Planar3DOverlay::getProperty(const QString& property) {
|
||||||
if (property == "dimensions" || property == "scale" || property == "size") {
|
if (property == "dimensions" || property == "scale" || property == "size") {
|
||||||
return vec2toVariant(getDimensions());
|
return vec2ToVariant(getDimensions());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Base3DOverlay::getProperty(property);
|
return Base3DOverlay::getProperty(property);
|
||||||
|
|
|
@ -51,9 +51,8 @@ void Rectangle3DOverlay::render(RenderArgs* args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float alpha = getAlpha();
|
float alpha = getAlpha();
|
||||||
xColor color = getColor();
|
glm::u8vec3 color = getColor();
|
||||||
const float MAX_COLOR = 255.0f;
|
glm::vec4 rectangleColor(toGlm(color), alpha);
|
||||||
glm::vec4 rectangleColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
|
||||||
|
|
||||||
auto batch = args->_batch;
|
auto batch = args->_batch;
|
||||||
if (batch) {
|
if (batch) {
|
||||||
|
|
|
@ -30,9 +30,8 @@ void Shape3DOverlay::render(RenderArgs* args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float alpha = getAlpha();
|
float alpha = getAlpha();
|
||||||
xColor color = getColor();
|
glm::u8vec3 color = getColor();
|
||||||
const float MAX_COLOR = 255.0f;
|
glm::vec4 shapeColor(toGlm(color), alpha);
|
||||||
glm::vec4 cubeColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
|
||||||
|
|
||||||
auto batch = args->_batch;
|
auto batch = args->_batch;
|
||||||
if (batch) {
|
if (batch) {
|
||||||
|
@ -44,9 +43,9 @@ void Shape3DOverlay::render(RenderArgs* args) {
|
||||||
|
|
||||||
batch->setModelTransform(getRenderTransform());
|
batch->setModelTransform(getRenderTransform());
|
||||||
if (_isSolid) {
|
if (_isSolid) {
|
||||||
geometryCache->renderSolidShapeInstance(args, *batch, _shape, cubeColor, shapePipeline);
|
geometryCache->renderSolidShapeInstance(args, *batch, _shape, shapeColor, shapePipeline);
|
||||||
} else {
|
} 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();
|
float alpha = getAlpha();
|
||||||
xColor color = getColor();
|
glm::u8vec3 color = getColor();
|
||||||
const float MAX_COLOR = 255.0f;
|
glm::vec4 sphereColor(toGlm(color), alpha);
|
||||||
glm::vec4 sphereColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
|
|
||||||
|
|
||||||
auto batch = args->_batch;
|
auto batch = args->_batch;
|
||||||
|
|
||||||
|
|
|
@ -64,21 +64,21 @@ void Text3DOverlay::setText(const QString& text) {
|
||||||
_text = text;
|
_text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
xColor Text3DOverlay::getBackgroundColor() {
|
glm::u8vec3 Text3DOverlay::getBackgroundColor() {
|
||||||
if (_colorPulse == 0.0f) {
|
if (_colorPulse == 0.0f) {
|
||||||
return _backgroundColor;
|
return _backgroundColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
float pulseLevel = updatePulse();
|
float pulseLevel = updatePulse();
|
||||||
xColor result = _backgroundColor;
|
glm::u8vec3 result = _backgroundColor;
|
||||||
if (_colorPulse < 0.0f) {
|
if (_colorPulse < 0.0f) {
|
||||||
result.red *= (1.0f - pulseLevel);
|
result.x *= (1.0f - pulseLevel);
|
||||||
result.green *= (1.0f - pulseLevel);
|
result.y *= (1.0f - pulseLevel);
|
||||||
result.blue *= (1.0f - pulseLevel);
|
result.z *= (1.0f - pulseLevel);
|
||||||
} else {
|
} else {
|
||||||
result.red *= pulseLevel;
|
result.x *= pulseLevel;
|
||||||
result.green *= pulseLevel;
|
result.y *= pulseLevel;
|
||||||
result.blue *= pulseLevel;
|
result.z *= pulseLevel;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -94,10 +94,8 @@ void Text3DOverlay::render(RenderArgs* args) {
|
||||||
auto transform = getRenderTransform();
|
auto transform = getRenderTransform();
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
const float MAX_COLOR = 255.0f;
|
glm::u8vec3 backgroundColor = getBackgroundColor();
|
||||||
xColor backgroundColor = getBackgroundColor();
|
glm::vec4 quadColor(toGlm(backgroundColor), getBackgroundAlpha());
|
||||||
glm::vec4 quadColor(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR,
|
|
||||||
backgroundColor.blue / MAX_COLOR, getBackgroundAlpha());
|
|
||||||
|
|
||||||
glm::vec2 dimensions = getDimensions();
|
glm::vec2 dimensions = getDimensions();
|
||||||
glm::vec2 halfDimensions = dimensions * 0.5f;
|
glm::vec2 halfDimensions = dimensions * 0.5f;
|
||||||
|
@ -122,8 +120,7 @@ void Text3DOverlay::render(RenderArgs* args) {
|
||||||
transform.setScale(scaleFactor);
|
transform.setScale(scaleFactor);
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
glm::vec4 textColor = { _color.red / MAX_COLOR, _color.green / MAX_COLOR,
|
glm::vec4 textColor = { toGlm(_color), getTextAlpha() };
|
||||||
_color.blue / MAX_COLOR, getTextAlpha() };
|
|
||||||
|
|
||||||
// FIXME: Factor out textRenderer so that Text3DOverlay overlay parts can be grouped by pipeline for a gpu performance increase.
|
// 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);
|
_textRenderer->draw(batch, 0, 0, getText(), textColor, glm::vec2(-1.0f), true);
|
||||||
|
@ -164,7 +161,7 @@ void Text3DOverlay::setProperties(const QVariantMap& properties) {
|
||||||
bool valid;
|
bool valid;
|
||||||
auto backgroundColor = properties["backgroundColor"];
|
auto backgroundColor = properties["backgroundColor"];
|
||||||
if (backgroundColor.isValid()) {
|
if (backgroundColor.isValid()) {
|
||||||
auto color = xColorFromVariant(backgroundColor, valid);
|
auto color = u8vec3FromVariant(backgroundColor, valid);
|
||||||
if (valid) {
|
if (valid) {
|
||||||
_backgroundColor = color;
|
_backgroundColor = color;
|
||||||
}
|
}
|
||||||
|
@ -260,7 +257,7 @@ QVariant Text3DOverlay::getProperty(const QString& property) {
|
||||||
return _textAlpha;
|
return _textAlpha;
|
||||||
}
|
}
|
||||||
if (property == "backgroundColor") {
|
if (property == "backgroundColor") {
|
||||||
return xColorToVariant(_backgroundColor);
|
return u8vec3ColortoVariant(_backgroundColor);
|
||||||
}
|
}
|
||||||
if (property == "backgroundAlpha") {
|
if (property == "backgroundAlpha") {
|
||||||
return Billboard3DOverlay::getProperty("alpha");
|
return Billboard3DOverlay::getProperty("alpha");
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
float getTopMargin() const { return _topMargin; }
|
float getTopMargin() const { return _topMargin; }
|
||||||
float getRightMargin() const { return _rightMargin; }
|
float getRightMargin() const { return _rightMargin; }
|
||||||
float getBottomMargin() const { return _bottomMargin; }
|
float getBottomMargin() const { return _bottomMargin; }
|
||||||
xColor getBackgroundColor();
|
glm::u8vec3 getBackgroundColor();
|
||||||
float getTextAlpha() { return _textAlpha; }
|
float getTextAlpha() { return _textAlpha; }
|
||||||
float getBackgroundAlpha() { return getAlpha(); }
|
float getBackgroundAlpha() { return getAlpha(); }
|
||||||
bool isTransparent() override { return Overlay::isTransparent() || _textAlpha < 1.0f; }
|
bool isTransparent() override { return Overlay::isTransparent() || _textAlpha < 1.0f; }
|
||||||
|
@ -65,7 +65,7 @@ private:
|
||||||
|
|
||||||
QString _text;
|
QString _text;
|
||||||
mutable QMutex _mutex; // used to make get/setText threadsafe, mutable so can be used in const functions
|
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 _textAlpha { 1.0f };
|
||||||
float _lineHeight { 1.0f };
|
float _lineHeight { 1.0f };
|
||||||
float _leftMargin { 0.1f };
|
float _leftMargin { 0.1f };
|
||||||
|
|
|
@ -40,7 +40,7 @@ QScriptValue AnimVariantMap::animVariantMapToScriptValue(QScriptEngine* engine,
|
||||||
target.setProperty(name, value.getString());
|
target.setProperty(name, value.getString());
|
||||||
break;
|
break;
|
||||||
case AnimVariant::Type::Vec3:
|
case AnimVariant::Type::Vec3:
|
||||||
target.setProperty(name, vec3toScriptValue(engine, value.getVec3()));
|
target.setProperty(name, vec3ToScriptValue(engine, value.getVec3()));
|
||||||
break;
|
break;
|
||||||
case AnimVariant::Type::Quat:
|
case AnimVariant::Type::Quat:
|
||||||
target.setProperty(name, quatToScriptValue(engine, value.getQuat()));
|
target.setProperty(name, quatToScriptValue(engine, value.getQuat()));
|
||||||
|
@ -169,7 +169,8 @@ std::map<QString, QString> AnimVariantMap::toDebugMap() const {
|
||||||
break;
|
break;
|
||||||
*/
|
*/
|
||||||
default:
|
default:
|
||||||
assert(("invalid AnimVariant::Type", false));
|
// invalid AnimVariant::Type
|
||||||
|
assert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -32,12 +32,6 @@ AnimationCache::AnimationCache(QObject* parent) :
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationPointer AnimationCache::getAnimation(const QUrl& url) {
|
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>();
|
return getResource(url).staticCast<Animation>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
class Animation;
|
class Animation;
|
||||||
|
|
||||||
typedef QSharedPointer<Animation> AnimationPointer;
|
using AnimationPointer = QSharedPointer<Animation>;
|
||||||
|
|
||||||
class AnimationCache : public ResourceCache, public Dependency {
|
class AnimationCache : public ResourceCache, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -1345,7 +1345,6 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab
|
||||||
const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix) {
|
const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix) {
|
||||||
|
|
||||||
const bool ENABLE_POLE_VECTORS = true;
|
const bool ENABLE_POLE_VECTORS = true;
|
||||||
const float ELBOW_POLE_VECTOR_BLEND_FACTOR = 0.95f;
|
|
||||||
|
|
||||||
if (leftHandEnabled) {
|
if (leftHandEnabled) {
|
||||||
|
|
||||||
|
@ -1371,33 +1370,16 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab
|
||||||
bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector);
|
bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector);
|
||||||
if (usePoleVector) {
|
if (usePoleVector) {
|
||||||
glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector);
|
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("leftHandPoleVectorEnabled", true);
|
||||||
_animVars.set("leftHandPoleReferenceVector", Vectors::UNIT_X);
|
_animVars.set("leftHandPoleReferenceVector", Vectors::UNIT_X);
|
||||||
_animVars.set("leftHandPoleVector", transformVectorFast(sensorToRigMatrix, _prevLeftHandPoleVector));
|
_animVars.set("leftHandPoleVector", transformVectorFast(sensorToRigMatrix, sensorPoleVector));
|
||||||
|
} else {
|
||||||
|
_animVars.set("leftHandPoleVectorEnabled", false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_prevLeftHandPoleVectorValid = false;
|
|
||||||
_animVars.set("leftHandPoleVectorEnabled", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
_prevLeftHandPoleVectorValid = false;
|
|
||||||
_animVars.set("leftHandPoleVectorEnabled", false);
|
_animVars.set("leftHandPoleVectorEnabled", false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_prevLeftHandPoleVectorValid = false;
|
|
||||||
_animVars.set("leftHandPoleVectorEnabled", false);
|
_animVars.set("leftHandPoleVectorEnabled", false);
|
||||||
|
|
||||||
_animVars.unset("leftHandPosition");
|
_animVars.unset("leftHandPosition");
|
||||||
|
@ -1436,33 +1418,16 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab
|
||||||
bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector);
|
bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector);
|
||||||
if (usePoleVector) {
|
if (usePoleVector) {
|
||||||
glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector);
|
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("rightHandPoleVectorEnabled", true);
|
||||||
_animVars.set("rightHandPoleReferenceVector", -Vectors::UNIT_X);
|
_animVars.set("rightHandPoleReferenceVector", -Vectors::UNIT_X);
|
||||||
_animVars.set("rightHandPoleVector", transformVectorFast(sensorToRigMatrix, _prevRightHandPoleVector));
|
_animVars.set("rightHandPoleVector", transformVectorFast(sensorToRigMatrix, sensorPoleVector));
|
||||||
} else {
|
} else {
|
||||||
_prevRightHandPoleVectorValid = false;
|
|
||||||
_animVars.set("rightHandPoleVectorEnabled", false);
|
_animVars.set("rightHandPoleVectorEnabled", false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_prevRightHandPoleVectorValid = false;
|
|
||||||
_animVars.set("rightHandPoleVectorEnabled", false);
|
_animVars.set("rightHandPoleVectorEnabled", false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_prevRightHandPoleVectorValid = false;
|
|
||||||
_animVars.set("rightHandPoleVectorEnabled", false);
|
_animVars.set("rightHandPoleVectorEnabled", false);
|
||||||
|
|
||||||
_animVars.unset("rightHandPosition");
|
_animVars.unset("rightHandPosition");
|
||||||
|
|
|
@ -230,7 +230,6 @@ public:
|
||||||
const AnimVariantMap& getAnimVars() const { return _lastAnimVars; }
|
const AnimVariantMap& getAnimVars() const { return _lastAnimVars; }
|
||||||
const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); }
|
const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); }
|
||||||
|
|
||||||
void toggleSmoothPoleVectors() { _smoothPoleVectors = !_smoothPoleVectors; };
|
|
||||||
signals:
|
signals:
|
||||||
void onLoadComplete();
|
void onLoadComplete();
|
||||||
|
|
||||||
|
@ -408,14 +407,6 @@ protected:
|
||||||
glm::vec3 _prevLeftFootPoleVector { Vectors::UNIT_Z }; // sensor space
|
glm::vec3 _prevLeftFootPoleVector { Vectors::UNIT_Z }; // sensor space
|
||||||
bool _prevLeftFootPoleVectorValid { false };
|
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;
|
int _rigId;
|
||||||
bool _headEnabled { false };
|
bool _headEnabled { false };
|
||||||
bool _sendNetworkNode { false };
|
bool _sendNetworkNode { false };
|
||||||
|
|
|
@ -34,7 +34,7 @@ AudioInjectorOptions::AudioInjectorOptions() :
|
||||||
|
|
||||||
QScriptValue injectorOptionsToScriptValue(QScriptEngine* engine, const AudioInjectorOptions& injectorOptions) {
|
QScriptValue injectorOptionsToScriptValue(QScriptEngine* engine, const AudioInjectorOptions& injectorOptions) {
|
||||||
QScriptValue obj = engine->newObject();
|
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("volume", injectorOptions.volume);
|
||||||
obj.setProperty("loop", injectorOptions.loop);
|
obj.setProperty("loop", injectorOptions.loop);
|
||||||
obj.setProperty("orientation", quatToScriptValue(engine, injectorOptions.orientation));
|
obj.setProperty("orientation", quatToScriptValue(engine, injectorOptions.orientation));
|
||||||
|
|
|
@ -30,12 +30,6 @@ SoundCache::SoundCache(QObject* parent) :
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedSoundPointer SoundCache::getSound(const QUrl& url) {
|
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>();
|
return getResource(url).staticCast<Sound>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -707,6 +707,19 @@ static TextRenderer3D* textRenderer(TextRendererType type) {
|
||||||
return displayNameRenderer;
|
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) {
|
void Avatar::addToScene(AvatarSharedPointer self, const render::ScenePointer& scene, render::Transaction& transaction) {
|
||||||
auto avatarPayload = new render::Payload<AvatarData>(self);
|
auto avatarPayload = new render::Payload<AvatarData>(self);
|
||||||
auto avatarPayloadPointer = std::shared_ptr<render::Payload<AvatarData>>(avatarPayload);
|
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
|
// INitialize the _render bound as we are creating the avatar render item
|
||||||
_renderBound = getBounds();
|
_renderBound = getBounds();
|
||||||
transaction.resetItem(_renderItemID, avatarPayloadPointer);
|
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->setTagMask(render::hifi::TAG_ALL_VIEWS);
|
||||||
_skeletonModel->setGroupCulled(true);
|
_skeletonModel->setGroupCulled(true);
|
||||||
_skeletonModel->setCanCastShadow(true);
|
_skeletonModel->setCanCastShadow(true);
|
||||||
|
@ -939,7 +953,8 @@ void Avatar::fixupModelsInScene(const render::ScenePointer& scene) {
|
||||||
render::Transaction transaction;
|
render::Transaction transaction;
|
||||||
if (_skeletonModel->isRenderable() && _skeletonModel->needsFixupInScene()) {
|
if (_skeletonModel->isRenderable() && _skeletonModel->needsFixupInScene()) {
|
||||||
_skeletonModel->removeFromScene(scene, transaction);
|
_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->setTagMask(render::hifi::TAG_ALL_VIEWS);
|
||||||
_skeletonModel->setGroupCulled(true);
|
_skeletonModel->setGroupCulled(true);
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include "Rig.h"
|
#include "Rig.h"
|
||||||
#include <ThreadSafeValueCache.h>
|
#include <ThreadSafeValueCache.h>
|
||||||
|
|
||||||
|
#include "MetaModelPayload.h"
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar);
|
template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar);
|
||||||
template <> const Item::Bound payloadGetBound(const AvatarSharedPointer& avatar);
|
template <> const Item::Bound payloadGetBound(const AvatarSharedPointer& avatar);
|
||||||
|
@ -115,7 +117,7 @@ private:
|
||||||
float _scale { 1.0f };
|
float _scale { 1.0f };
|
||||||
};
|
};
|
||||||
|
|
||||||
class Avatar : public AvatarData, public scriptable::ModelProvider {
|
class Avatar : public AvatarData, public scriptable::ModelProvider, public MetaModelPayload {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
// This property has JSDoc in MyAvatar.h.
|
// This property has JSDoc in MyAvatar.h.
|
||||||
|
@ -623,6 +625,9 @@ protected:
|
||||||
static const float ATTACHMENT_LOADING_PRIORITY;
|
static const float ATTACHMENT_LOADING_PRIORITY;
|
||||||
|
|
||||||
LoadingStatus _loadingStatus { LoadingStatus::NoModel };
|
LoadingStatus _loadingStatus { LoadingStatus::NoModel };
|
||||||
|
|
||||||
|
void metaBlendshapeOperator(int blendshapeNumber, const QVector<BlendshapeOffset>& blendshapeOffsets, const QVector<int>& blendedMeshSizes,
|
||||||
|
const render::ItemIDs& subItemIDs);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Avatar_h
|
#endif // hifi_Avatar_h
|
||||||
|
|
|
@ -75,8 +75,11 @@ size_t AvatarDataPacket::maxJointDataSize(size_t numJoints, bool hasGrabJoints)
|
||||||
totalSize += numJoints * sizeof(SixByteTrans); // Translations
|
totalSize += numJoints * sizeof(SixByteTrans); // Translations
|
||||||
|
|
||||||
size_t NUM_FAUX_JOINT = 2;
|
size_t NUM_FAUX_JOINT = 2;
|
||||||
size_t num_grab_joints = (hasGrabJoints ? 2 : 0);
|
totalSize += NUM_FAUX_JOINT * (sizeof(SixByteQuat) + sizeof(SixByteTrans)); // faux joints
|
||||||
totalSize += (NUM_FAUX_JOINT + num_grab_joints) * (sizeof(SixByteQuat) + sizeof(SixByteTrans)); // faux joints
|
|
||||||
|
if (hasGrabJoints) {
|
||||||
|
totalSize += sizeof(AvatarDataPacket::FarGrabJoints);
|
||||||
|
}
|
||||||
|
|
||||||
return totalSize;
|
return totalSize;
|
||||||
}
|
}
|
||||||
|
@ -685,7 +688,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
if (hasGrabJoints) {
|
if (hasGrabJoints) {
|
||||||
// the far-grab joints may range further than 3 meters, so we can't use packFloatVec3ToSignedTwoByteFixed etc
|
// the far-grab joints may range further than 3 meters, so we can't use packFloatVec3ToSignedTwoByteFixed etc
|
||||||
auto startSection = destinationBuffer;
|
auto startSection = destinationBuffer;
|
||||||
auto data = reinterpret_cast<AvatarDataPacket::FarGrabJoints*>(destinationBuffer);
|
|
||||||
glm::vec3 leftFarGrabPosition = extractTranslation(leftFarGrabMatrix);
|
glm::vec3 leftFarGrabPosition = extractTranslation(leftFarGrabMatrix);
|
||||||
glm::quat leftFarGrabRotation = extractRotation(leftFarGrabMatrix);
|
glm::quat leftFarGrabRotation = extractRotation(leftFarGrabMatrix);
|
||||||
glm::vec3 rightFarGrabPosition = extractTranslation(rightFarGrabMatrix);
|
glm::vec3 rightFarGrabPosition = extractTranslation(rightFarGrabMatrix);
|
||||||
|
@ -693,28 +696,17 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
glm::vec3 mouseFarGrabPosition = extractTranslation(mouseFarGrabMatrix);
|
glm::vec3 mouseFarGrabPosition = extractTranslation(mouseFarGrabMatrix);
|
||||||
glm::quat mouseFarGrabRotation = extractRotation(mouseFarGrabMatrix);
|
glm::quat mouseFarGrabRotation = extractRotation(mouseFarGrabMatrix);
|
||||||
|
|
||||||
AVATAR_MEMCPY(leftFarGrabPosition);
|
AvatarDataPacket::FarGrabJoints farGrabJoints = {
|
||||||
// Can't do block copy as struct order is x, y, z, w.
|
{ leftFarGrabPosition.x, leftFarGrabPosition.y, leftFarGrabPosition.z },
|
||||||
data->leftFarGrabRotation[0] = leftFarGrabRotation.w;
|
{ leftFarGrabRotation.w, leftFarGrabRotation.x, leftFarGrabRotation.y, leftFarGrabRotation.z },
|
||||||
data->leftFarGrabRotation[1] = leftFarGrabRotation.x;
|
{ rightFarGrabPosition.x, rightFarGrabPosition.y, rightFarGrabPosition.z },
|
||||||
data->leftFarGrabRotation[2] = leftFarGrabRotation.y;
|
{ rightFarGrabRotation.w, rightFarGrabRotation.x, rightFarGrabRotation.y, rightFarGrabRotation.z },
|
||||||
data->leftFarGrabRotation[3] = leftFarGrabRotation.z;
|
{ mouseFarGrabPosition.x, mouseFarGrabPosition.y, mouseFarGrabPosition.z },
|
||||||
destinationBuffer += sizeof(data->leftFarGrabPosition);
|
{ mouseFarGrabRotation.w, mouseFarGrabRotation.x, mouseFarGrabRotation.y, mouseFarGrabRotation.z }
|
||||||
|
};
|
||||||
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);
|
|
||||||
|
|
||||||
|
memcpy(destinationBuffer, &farGrabJoints, sizeof(farGrabJoints));
|
||||||
|
destinationBuffer += sizeof(AvatarDataPacket::FarGrabJoints);
|
||||||
int numBytes = destinationBuffer - startSection;
|
int numBytes = destinationBuffer - startSection;
|
||||||
|
|
||||||
if (outboundDataRateOut) {
|
if (outboundDataRateOut) {
|
||||||
|
@ -1247,25 +1239,37 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
|
||||||
auto startSection = sourceBuffer;
|
auto startSection = sourceBuffer;
|
||||||
|
|
||||||
PACKET_READ_CHECK(FarGrabJoints, sizeof(AvatarDataPacket::FarGrabJoints));
|
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],
|
AvatarDataPacket::FarGrabJoints farGrabJoints;
|
||||||
data->leftFarGrabPosition[2]);
|
memcpy(&farGrabJoints, sourceBuffer, sizeof(farGrabJoints)); // to avoid misaligned floats
|
||||||
glm::quat leftFarGrabRotation = glm::quat(data->leftFarGrabRotation[0], data->leftFarGrabRotation[1],
|
|
||||||
data->leftFarGrabRotation[2], data->leftFarGrabRotation[3]);
|
glm::vec3 leftFarGrabPosition = glm::vec3(farGrabJoints.leftFarGrabPosition[0],
|
||||||
glm::vec3 rightFarGrabPosition = glm::vec3(data->rightFarGrabPosition[0], data->rightFarGrabPosition[1],
|
farGrabJoints.leftFarGrabPosition[1],
|
||||||
data->rightFarGrabPosition[2]);
|
farGrabJoints.leftFarGrabPosition[2]);
|
||||||
glm::quat rightFarGrabRotation = glm::quat(data->rightFarGrabRotation[0], data->rightFarGrabRotation[1],
|
glm::quat leftFarGrabRotation = glm::quat(farGrabJoints.leftFarGrabRotation[0],
|
||||||
data->rightFarGrabRotation[2], data->rightFarGrabRotation[3]);
|
farGrabJoints.leftFarGrabRotation[1],
|
||||||
glm::vec3 mouseFarGrabPosition = glm::vec3(data->mouseFarGrabPosition[0], data->mouseFarGrabPosition[1],
|
farGrabJoints.leftFarGrabRotation[2],
|
||||||
data->mouseFarGrabPosition[2]);
|
farGrabJoints.leftFarGrabRotation[3]);
|
||||||
glm::quat mouseFarGrabRotation = glm::quat(data->mouseFarGrabRotation[0], data->mouseFarGrabRotation[1],
|
glm::vec3 rightFarGrabPosition = glm::vec3(farGrabJoints.rightFarGrabPosition[0],
|
||||||
data->mouseFarGrabRotation[2], data->mouseFarGrabRotation[3]);
|
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));
|
_farGrabLeftMatrixCache.set(createMatFromQuatAndPos(leftFarGrabRotation, leftFarGrabPosition));
|
||||||
_farGrabRightMatrixCache.set(createMatFromQuatAndPos(rightFarGrabRotation, rightFarGrabPosition));
|
_farGrabRightMatrixCache.set(createMatFromQuatAndPos(rightFarGrabRotation, rightFarGrabPosition));
|
||||||
_farGrabMouseMatrixCache.set(createMatFromQuatAndPos(mouseFarGrabRotation, mouseFarGrabPosition));
|
_farGrabMouseMatrixCache.set(createMatFromQuatAndPos(mouseFarGrabRotation, mouseFarGrabPosition));
|
||||||
|
|
||||||
sourceBuffer += sizeof(AvatarDataPacket::AvatarGlobalPosition);
|
sourceBuffer += sizeof(AvatarDataPacket::FarGrabJoints);
|
||||||
int numBytesRead = sourceBuffer - startSection;
|
int numBytesRead = sourceBuffer - startSection;
|
||||||
_farGrabJointRate.increment(numBytesRead);
|
_farGrabJointRate.increment(numBytesRead);
|
||||||
_farGrabJointUpdateRate.increment();
|
_farGrabJointUpdateRate.increment();
|
||||||
|
@ -2821,10 +2825,10 @@ QScriptValue RayToAvatarIntersectionResultToScriptValue(QScriptEngine* engine, c
|
||||||
obj.setProperty("avatarID", avatarIDValue);
|
obj.setProperty("avatarID", avatarIDValue);
|
||||||
obj.setProperty("distance", value.distance);
|
obj.setProperty("distance", value.distance);
|
||||||
obj.setProperty("face", boxFaceToString(value.face));
|
obj.setProperty("face", boxFaceToString(value.face));
|
||||||
|
QScriptValue intersection = vec3ToScriptValue(engine, value.intersection);
|
||||||
|
|
||||||
QScriptValue intersection = vec3toScriptValue(engine, value.intersection);
|
|
||||||
obj.setProperty("intersection", intersection);
|
obj.setProperty("intersection", intersection);
|
||||||
QScriptValue surfaceNormal = vec3toScriptValue(engine, value.surfaceNormal);
|
QScriptValue surfaceNormal = vec3ToScriptValue(engine, value.surfaceNormal);
|
||||||
obj.setProperty("surfaceNormal", surfaceNormal);
|
obj.setProperty("surfaceNormal", surfaceNormal);
|
||||||
obj.setProperty("extraInfo", engine->toScriptValue(value.extraInfo));
|
obj.setProperty("extraInfo", engine->toScriptValue(value.extraInfo));
|
||||||
return obj;
|
return obj;
|
||||||
|
|
|
@ -258,7 +258,6 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer<ReceivedMessag
|
||||||
|
|
||||||
if (isNewAvatar) {
|
if (isNewAvatar) {
|
||||||
QWriteLocker locker(&_hashLock);
|
QWriteLocker locker(&_hashLock);
|
||||||
_pendingAvatars.insert(sessionUUID, { std::chrono::steady_clock::now(), 0, avatar });
|
|
||||||
avatar->setIsNewAvatar(true);
|
avatar->setIsNewAvatar(true);
|
||||||
auto replicaIDs = _replicas.getReplicaIDs(sessionUUID);
|
auto replicaIDs = _replicas.getReplicaIDs(sessionUUID);
|
||||||
for (auto replicaID : replicaIDs) {
|
for (auto replicaID : replicaIDs) {
|
||||||
|
@ -300,7 +299,6 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage>
|
||||||
|
|
||||||
{
|
{
|
||||||
QReadLocker locker(&_hashLock);
|
QReadLocker locker(&_hashLock);
|
||||||
_pendingAvatars.remove(identityUUID);
|
|
||||||
auto me = _avatarHash.find(EMPTY);
|
auto me = _avatarHash.find(EMPTY);
|
||||||
if ((me != _avatarHash.end()) && (identityUUID == me.value()->getSessionUUID())) {
|
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
|
// 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);
|
auto removedAvatar = _avatarHash.take(sessionUUID);
|
||||||
|
|
||||||
if (removedAvatar) {
|
if (removedAvatar) {
|
||||||
|
|
|
@ -161,6 +161,11 @@ protected slots:
|
||||||
*/
|
*/
|
||||||
void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* @function AvatarList.processBulkAvatarTraits
|
||||||
|
* @param {} message
|
||||||
|
* @param {} sendingNode
|
||||||
|
*/
|
||||||
void processBulkAvatarTraits(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
void processBulkAvatarTraits(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
@ -183,15 +188,8 @@ protected:
|
||||||
|
|
||||||
virtual void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason);
|
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;
|
mutable QReadWriteLock _hashLock;
|
||||||
|
AvatarHash _avatarHash;
|
||||||
|
|
||||||
std::unordered_map<QUuid, AvatarTraits::TraitVersions> _processedTraitVersions;
|
std::unordered_map<QUuid, AvatarTraits::TraitVersions> _processedTraitVersions;
|
||||||
AvatarReplicas _replicas;
|
AvatarReplicas _replicas;
|
||||||
|
|
|
@ -98,7 +98,7 @@ enum Hand {
|
||||||
class InputDevice {
|
class InputDevice {
|
||||||
public:
|
public:
|
||||||
InputDevice(const QString& name) : _name(name) {}
|
InputDevice(const QString& name) : _name(name) {}
|
||||||
virtual ~InputDevice() {}
|
virtual ~InputDevice() = default;
|
||||||
|
|
||||||
using Pointer = std::shared_ptr<InputDevice>;
|
using Pointer = std::shared_ptr<InputDevice>;
|
||||||
|
|
||||||
|
|
|
@ -41,10 +41,10 @@ namespace controller {
|
||||||
*/
|
*/
|
||||||
QScriptValue Pose::toScriptValue(QScriptEngine* engine, const Pose& pose) {
|
QScriptValue Pose::toScriptValue(QScriptEngine* engine, const Pose& pose) {
|
||||||
QScriptValue obj = engine->newObject();
|
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("rotation", quatToScriptValue(engine, pose.rotation));
|
||||||
obj.setProperty("velocity", vec3toScriptValue(engine, pose.velocity));
|
obj.setProperty("velocity", vec3ToScriptValue(engine, pose.velocity));
|
||||||
obj.setProperty("angularVelocity", vec3toScriptValue(engine, pose.angularVelocity));
|
obj.setProperty("angularVelocity", vec3ToScriptValue(engine, pose.angularVelocity));
|
||||||
obj.setProperty("valid", pose.valid);
|
obj.setProperty("valid", pose.valid);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,8 @@ namespace controller {
|
||||||
using Factory = hifi::SimpleFactory<Conditional, QString>;
|
using Factory = hifi::SimpleFactory<Conditional, QString>;
|
||||||
using Lambda = std::function<bool()>;
|
using Lambda = std::function<bool()>;
|
||||||
|
|
||||||
|
virtual ~Conditional() = default;
|
||||||
|
|
||||||
virtual bool satisfied() = 0;
|
virtual bool satisfied() = 0;
|
||||||
virtual bool parseParameters(const QJsonValue& parameters) { return true; }
|
virtual bool parseParameters(const QJsonValue& parameters) { return true; }
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@ namespace controller {
|
||||||
using Lambda = std::function<float(float)>;
|
using Lambda = std::function<float(float)>;
|
||||||
using Factory = hifi::SimpleFactory<Filter, QString>;
|
using Factory = hifi::SimpleFactory<Filter, QString>;
|
||||||
|
|
||||||
|
virtual ~Filter() = default;
|
||||||
|
|
||||||
virtual float apply(float value) const = 0;
|
virtual float apply(float value) const = 0;
|
||||||
virtual Pose apply(Pose value) const = 0;
|
virtual Pose apply(Pose value) const = 0;
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,6 @@ public:
|
||||||
AndConditional(Conditional::Pointer& first, Conditional::Pointer& second)
|
AndConditional(Conditional::Pointer& first, Conditional::Pointer& second)
|
||||||
: _children({ first, second }) {}
|
: _children({ first, second }) {}
|
||||||
|
|
||||||
virtual ~AndConditional() {}
|
|
||||||
|
|
||||||
virtual bool satisfied() override;
|
virtual bool satisfied() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -18,7 +18,6 @@ namespace controller {
|
||||||
class EndpointConditional : public Conditional {
|
class EndpointConditional : public Conditional {
|
||||||
public:
|
public:
|
||||||
EndpointConditional(Endpoint::Pointer endpoint) : _endpoint(endpoint) {}
|
EndpointConditional(Endpoint::Pointer endpoint) : _endpoint(endpoint) {}
|
||||||
virtual ~EndpointConditional() {}
|
|
||||||
virtual bool satisfied() override { return _endpoint && _endpoint->peek() != 0.0f; }
|
virtual bool satisfied() override { return _endpoint && _endpoint->peek() != 0.0f; }
|
||||||
private:
|
private:
|
||||||
Endpoint::Pointer _endpoint;
|
Endpoint::Pointer _endpoint;
|
||||||
|
|
|
@ -19,7 +19,6 @@ namespace controller {
|
||||||
using Pointer = std::shared_ptr<NotConditional>;
|
using Pointer = std::shared_ptr<NotConditional>;
|
||||||
|
|
||||||
NotConditional(Conditional::Pointer operand) : _operand(operand) { }
|
NotConditional(Conditional::Pointer operand) : _operand(operand) { }
|
||||||
virtual ~NotConditional() {}
|
|
||||||
|
|
||||||
virtual bool satisfied() override;
|
virtual bool satisfied() override;
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ class ClampFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(ClampFilter);
|
REGISTER_FILTER_CLASS(ClampFilter);
|
||||||
public:
|
public:
|
||||||
ClampFilter(float min = 0.0, float max = 1.0) : _min(min), _max(max) {};
|
ClampFilter(float min = 0.0, float max = 1.0) : _min(min), _max(max) {};
|
||||||
virtual ~ClampFilter() {}
|
|
||||||
virtual float apply(float value) const override {
|
virtual float apply(float value) const override {
|
||||||
return glm::clamp(value, _min, _max);
|
return glm::clamp(value, _min, _max);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,16 +17,13 @@ namespace controller {
|
||||||
class ConstrainToIntegerFilter : public Filter {
|
class ConstrainToIntegerFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(ConstrainToIntegerFilter);
|
REGISTER_FILTER_CLASS(ConstrainToIntegerFilter);
|
||||||
public:
|
public:
|
||||||
ConstrainToIntegerFilter() {};
|
ConstrainToIntegerFilter() = default;
|
||||||
virtual ~ConstrainToIntegerFilter() {}
|
|
||||||
|
|
||||||
virtual float apply(float value) const override {
|
virtual float apply(float value) const override {
|
||||||
return glm::sign(value);
|
return glm::sign(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Pose apply(Pose value) const override { return value; }
|
virtual Pose apply(Pose value) const override { return value; }
|
||||||
|
|
||||||
protected:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,16 +17,13 @@ namespace controller {
|
||||||
class ConstrainToPositiveIntegerFilter : public Filter {
|
class ConstrainToPositiveIntegerFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(ConstrainToPositiveIntegerFilter);
|
REGISTER_FILTER_CLASS(ConstrainToPositiveIntegerFilter);
|
||||||
public:
|
public:
|
||||||
ConstrainToPositiveIntegerFilter() {};
|
ConstrainToPositiveIntegerFilter() = default;
|
||||||
virtual ~ConstrainToPositiveIntegerFilter() {};
|
|
||||||
|
|
||||||
virtual float apply(float value) const override {
|
virtual float apply(float value) const override {
|
||||||
return (value <= 0.0f) ? 0.0f : 1.0f;
|
return (value <= 0.0f) ? 0.0f : 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Pose apply(Pose value) const override { return value; }
|
virtual Pose apply(Pose value) const override { return value; }
|
||||||
|
|
||||||
protected:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ class DeadZoneFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(DeadZoneFilter);
|
REGISTER_FILTER_CLASS(DeadZoneFilter);
|
||||||
public:
|
public:
|
||||||
DeadZoneFilter(float min = 0.0) : _min(min) {};
|
DeadZoneFilter(float min = 0.0) : _min(min) {};
|
||||||
virtual ~DeadZoneFilter() {}
|
|
||||||
|
|
||||||
virtual float apply(float value) const override;
|
virtual float apply(float value) const override;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ namespace controller {
|
||||||
ExponentialSmoothingFilter() {}
|
ExponentialSmoothingFilter() {}
|
||||||
ExponentialSmoothingFilter(float rotationConstant, float translationConstant) :
|
ExponentialSmoothingFilter(float rotationConstant, float translationConstant) :
|
||||||
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
|
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
|
||||||
virtual ~ExponentialSmoothingFilter() {}
|
|
||||||
|
|
||||||
float apply(float value) const override { return value; }
|
float apply(float value) const override { return value; }
|
||||||
Pose apply(Pose value) const override;
|
Pose apply(Pose value) const override;
|
||||||
|
|
|
@ -18,7 +18,6 @@ class HysteresisFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(HysteresisFilter);
|
REGISTER_FILTER_CLASS(HysteresisFilter);
|
||||||
public:
|
public:
|
||||||
HysteresisFilter(float min = 0.25, float max = 0.75);
|
HysteresisFilter(float min = 0.25, float max = 0.75);
|
||||||
virtual ~HysteresisFilter() {}
|
|
||||||
virtual float apply(float value) const override;
|
virtual float apply(float value) const override;
|
||||||
|
|
||||||
virtual Pose apply(Pose value) const override { return value; }
|
virtual Pose apply(Pose value) const override { return value; }
|
||||||
|
|
|
@ -19,11 +19,8 @@ class InvertFilter : public ScaleFilter {
|
||||||
public:
|
public:
|
||||||
using ScaleFilter::parseParameters;
|
using ScaleFilter::parseParameters;
|
||||||
InvertFilter() : ScaleFilter(-1.0f) {}
|
InvertFilter() : ScaleFilter(-1.0f) {}
|
||||||
virtual ~InvertFilter() {}
|
|
||||||
|
|
||||||
virtual bool parseParameters(const QJsonArray& parameters) { return true; }
|
virtual bool parseParameters(const QJsonArray& parameters) { return true; }
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,9 @@ namespace controller {
|
||||||
REGISTER_FILTER_CLASS(LowVelocityFilter);
|
REGISTER_FILTER_CLASS(LowVelocityFilter);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LowVelocityFilter() {}
|
LowVelocityFilter() = default;
|
||||||
LowVelocityFilter(float rotationConstant, float translationConstant) :
|
LowVelocityFilter(float rotationConstant, float translationConstant) :
|
||||||
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
|
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
|
||||||
virtual ~LowVelocityFilter() {}
|
|
||||||
|
|
||||||
float apply(float value) const override { return value; }
|
float apply(float value) const override { return value; }
|
||||||
Pose apply(Pose newPose) const override;
|
Pose apply(Pose newPose) const override;
|
||||||
|
|
|
@ -10,7 +10,6 @@ class NotFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(NotFilter);
|
REGISTER_FILTER_CLASS(NotFilter);
|
||||||
public:
|
public:
|
||||||
NotFilter();
|
NotFilter();
|
||||||
virtual ~NotFilter() {}
|
|
||||||
|
|
||||||
virtual float apply(float value) const override;
|
virtual float apply(float value) const override;
|
||||||
virtual Pose apply(Pose value) const override { return value; }
|
virtual Pose apply(Pose value) const override { return value; }
|
||||||
|
|
|
@ -19,9 +19,8 @@ namespace controller {
|
||||||
class PostTransformFilter : public Filter {
|
class PostTransformFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(PostTransformFilter);
|
REGISTER_FILTER_CLASS(PostTransformFilter);
|
||||||
public:
|
public:
|
||||||
PostTransformFilter() { }
|
PostTransformFilter() = default;
|
||||||
PostTransformFilter(glm::mat4 transform) : _transform(transform) {}
|
PostTransformFilter(glm::mat4 transform) : _transform(transform) {}
|
||||||
virtual ~PostTransformFilter() {}
|
|
||||||
virtual float apply(float value) const override { return value; }
|
virtual float apply(float value) const override { return value; }
|
||||||
virtual Pose apply(Pose value) const override { return value.postTransform(_transform); }
|
virtual Pose apply(Pose value) const override { return value.postTransform(_transform); }
|
||||||
virtual bool parseParameters(const QJsonValue& parameters) override { return parseMat4Parameter(parameters, _transform); }
|
virtual bool parseParameters(const QJsonValue& parameters) override { return parseMat4Parameter(parameters, _transform); }
|
||||||
|
|
|
@ -18,9 +18,8 @@ namespace controller {
|
||||||
class PulseFilter : public Filter {
|
class PulseFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(PulseFilter);
|
REGISTER_FILTER_CLASS(PulseFilter);
|
||||||
public:
|
public:
|
||||||
PulseFilter() {}
|
PulseFilter() = default;
|
||||||
PulseFilter(float interval) : _interval(interval) {}
|
PulseFilter(float interval) : _interval(interval) {}
|
||||||
virtual ~PulseFilter() {}
|
|
||||||
|
|
||||||
virtual float apply(float value) const override;
|
virtual float apply(float value) const override;
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,8 @@ namespace controller {
|
||||||
class RotateFilter : public Filter {
|
class RotateFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(RotateFilter);
|
REGISTER_FILTER_CLASS(RotateFilter);
|
||||||
public:
|
public:
|
||||||
RotateFilter() { }
|
RotateFilter() = default;
|
||||||
RotateFilter(glm::quat rotation) : _rotation(rotation) {}
|
RotateFilter(glm::quat rotation) : _rotation(rotation) {}
|
||||||
virtual ~RotateFilter() {}
|
|
||||||
|
|
||||||
virtual float apply(float value) const override { return value; }
|
virtual float apply(float value) const override { return value; }
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,8 @@ namespace controller {
|
||||||
class ScaleFilter : public Filter {
|
class ScaleFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(ScaleFilter);
|
REGISTER_FILTER_CLASS(ScaleFilter);
|
||||||
public:
|
public:
|
||||||
ScaleFilter() {}
|
ScaleFilter() = default;
|
||||||
ScaleFilter(float scale) : _scale(scale) {}
|
ScaleFilter(float scale) : _scale(scale) {}
|
||||||
virtual ~ScaleFilter() {}
|
|
||||||
|
|
||||||
virtual float apply(float value) const override {
|
virtual float apply(float value) const override {
|
||||||
return value * _scale;
|
return value * _scale;
|
||||||
|
|
|
@ -19,9 +19,8 @@ namespace controller {
|
||||||
class TransformFilter : public Filter {
|
class TransformFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(TransformFilter);
|
REGISTER_FILTER_CLASS(TransformFilter);
|
||||||
public:
|
public:
|
||||||
TransformFilter() { }
|
TransformFilter() = default;
|
||||||
TransformFilter(glm::mat4 transform) : _transform(transform) {}
|
TransformFilter(glm::mat4 transform) : _transform(transform) {}
|
||||||
virtual ~TransformFilter() {}
|
|
||||||
|
|
||||||
virtual float apply(float value) const override { return value; }
|
virtual float apply(float value) const override { return value; }
|
||||||
virtual Pose apply(Pose value) const override { return value.transform(_transform); }
|
virtual Pose apply(Pose value) const override { return value.transform(_transform); }
|
||||||
|
|
|
@ -19,9 +19,8 @@ namespace controller {
|
||||||
class TranslateFilter : public Filter {
|
class TranslateFilter : public Filter {
|
||||||
REGISTER_FILTER_CLASS(TranslateFilter);
|
REGISTER_FILTER_CLASS(TranslateFilter);
|
||||||
public:
|
public:
|
||||||
TranslateFilter() { }
|
TranslateFilter() = default;
|
||||||
TranslateFilter(glm::vec3 translate) : _translate(translate) {}
|
TranslateFilter(glm::vec3 translate) : _translate(translate) {}
|
||||||
virtual ~TranslateFilter() {}
|
|
||||||
|
|
||||||
virtual float apply(float value) const override { return value; }
|
virtual float apply(float value) const override { return value; }
|
||||||
virtual Pose apply(Pose value) const override { return value.transform(glm::translate(_translate)); }
|
virtual Pose apply(Pose value) const override { return value.transform(glm::translate(_translate)); }
|
||||||
|
|
|
@ -494,7 +494,7 @@ glm::mat4 CompositorHelper::getPoint2DTransform(const glm::vec2& point, float si
|
||||||
|
|
||||||
|
|
||||||
QVariant ReticleInterface::getPosition() const {
|
QVariant ReticleInterface::getPosition() const {
|
||||||
return vec2toVariant(_compositor->getReticlePosition());
|
return vec2ToVariant(_compositor->getReticlePosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReticleInterface::setPosition(QVariant position) {
|
void ReticleInterface::setPosition(QVariant position) {
|
||||||
|
|