Merge branch 'master' into transitAddAnimation

This commit is contained in:
Luis Cuenca 2018-10-20 15:30:23 -07:00 committed by GitHub
commit e1c760b566
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
359 changed files with 8550 additions and 3957 deletions

View file

@ -0,0 +1 @@
org.gradle.jvmargs=-Xms2g -Xmx4g

View file

@ -368,11 +368,7 @@ void Agent::executeScript() {
// setup an Avatar for the script to use
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
scriptedAvatar->setID(getSessionUUID());
connect(_scriptEngine.data(), SIGNAL(update(float)),
scriptedAvatar.data(), SLOT(update(float)), Qt::ConnectionType::QueuedConnection);
scriptedAvatar->setForceFaceTrackerConnected(true);
// call model URL setters with empty URLs so our avatar, if user, will have the default models
@ -504,8 +500,6 @@ void Agent::executeScript() {
DependencyManager::set<AssignmentParentFinder>(_entityViewer.getTree());
_avatarAudioTimer.start();
// Agents should run at 45hz
static const int AVATAR_DATA_HZ = 45;
static const int AVATAR_DATA_IN_MSECS = MSECS_PER_SECOND / AVATAR_DATA_HZ;
@ -530,7 +524,8 @@ void Agent::executeScript() {
}
avatarDataTimer->stop();
_avatarAudioTimer.stop();
setIsAvatar(false); // will stop timers for sending identity packets
}
setFinished(true);
@ -582,28 +577,33 @@ void Agent::setIsAvatar(bool isAvatar) {
}
_isAvatar = isAvatar;
if (_isAvatar && !_avatarIdentityTimer) {
// set up the avatar timers
_avatarIdentityTimer = new QTimer(this);
_avatarQueryTimer = new QTimer(this);
auto scriptableAvatar = DependencyManager::get<ScriptableAvatar>();
if (_isAvatar) {
if (!_avatarIdentityTimer) {
// set up the avatar timers
_avatarIdentityTimer = new QTimer(this);
_avatarQueryTimer = new QTimer(this);
// connect our slot
connect(_avatarIdentityTimer, &QTimer::timeout, this, &Agent::sendAvatarIdentityPacket);
connect(_avatarQueryTimer, &QTimer::timeout, this, &Agent::queryAvatars);
// connect our slot
connect(_avatarIdentityTimer, &QTimer::timeout, this, &Agent::sendAvatarIdentityPacket);
connect(_avatarQueryTimer, &QTimer::timeout, this, &Agent::queryAvatars);
static const int AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS = 1000;
static const int AVATAR_VIEW_PACKET_SEND_INTERVAL_MSECS = 1000;
static const int AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS = 1000;
static const int AVATAR_VIEW_PACKET_SEND_INTERVAL_MSECS = 1000;
// start the timers
_avatarIdentityTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS); // FIXME - we shouldn't really need to constantly send identity packets
_avatarQueryTimer->start(AVATAR_VIEW_PACKET_SEND_INTERVAL_MSECS);
// start the timers
_avatarIdentityTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS); // FIXME - we shouldn't really need to constantly send identity packets
_avatarQueryTimer->start(AVATAR_VIEW_PACKET_SEND_INTERVAL_MSECS);
// tell the avatarAudioTimer to start ticking
QMetaObject::invokeMethod(&_avatarAudioTimer, "start");
}
connect(_scriptEngine.data(), &ScriptEngine::update,
scriptableAvatar.data(), &ScriptableAvatar::update, Qt::QueuedConnection);
if (!_isAvatar) {
// tell the avatarAudioTimer to start ticking
QMetaObject::invokeMethod(&_avatarAudioTimer, "start");
}
_entityEditSender.setMyAvatar(scriptableAvatar.data());
} else {
if (_avatarIdentityTimer) {
_avatarIdentityTimer->stop();
delete _avatarIdentityTimer;
@ -630,14 +630,14 @@ void Agent::setIsAvatar(bool isAvatar) {
packet->writePrimitive(KillAvatarReason::NoReason);
nodeList->sendPacket(std::move(packet), *node);
});
disconnect(_scriptEngine.data(), &ScriptEngine::update,
scriptableAvatar.data(), &ScriptableAvatar::update);
QMetaObject::invokeMethod(&_avatarAudioTimer, "stop");
}
QMetaObject::invokeMethod(&_avatarAudioTimer, "stop");
_entityEditSender.setMyAvatar(nullptr);
} else {
auto scriptableAvatar = DependencyManager::get<ScriptableAvatar>();
_entityEditSender.setMyAvatar(scriptableAvatar.data());
}
}
@ -788,7 +788,7 @@ void Agent::processAgentAvatarAudio() {
// seek past the sequence number, will be packed when destination node is known
audioPacket->seek(sizeof(quint16));
if (silentFrame) {
if (silentFrame && !_flushEncoder) {
if (!_isListeningToAudioStream) {
// if we have a silent frame and we're not listening then just send nothing and break out of here
@ -810,7 +810,7 @@ void Agent::processAgentAvatarAudio() {
// no matter what, the loudness should be set to 0
computeLoudness(nullptr, scriptedAvatar);
} else if (nextSoundOutput) {
} else if (nextSoundOutput || _flushEncoder) {
// write the codec
audioPacket->writeString(_selectedCodecName);
@ -864,8 +864,6 @@ void Agent::processAgentAvatarAudio() {
}
void Agent::aboutToFinish() {
setIsAvatar(false);// will stop timers for sending identity packets
// our entity tree is going to go away so tell that to the EntityScriptingInterface
DependencyManager::get<EntityScriptingInterface>()->setEntityTree(nullptr);

View file

@ -497,7 +497,7 @@ void AudioMixerClientData::processStreamPacket(ReceivedMessage& message, Concurr
if (newStream) {
// whenever a stream is added, push it to the concurrent vector of streams added this frame
addedStreams.emplace_back(getNodeID(), getNodeLocalID(), matchingStream->getStreamIdentifier(), matchingStream.get());
addedStreams.push_back(AddedStream(getNodeID(), getNodeLocalID(), matchingStream->getStreamIdentifier(), matchingStream.get()));
}
}

View file

@ -380,6 +380,11 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node)
if (lastSeqToReceiver == lastSeqFromSender && lastSeqToReceiver != 0) {
++numAvatarsHeldBack;
shouldIgnore = true;
} else if (lastSeqFromSender == 0) {
// We have have not yet recieved any data about this avatar. Ignore it for now
// This is important for Agent scripts that are not avatar
// so that they don't appear to be an avatar at the origin
shouldIgnore = true;
} else if (lastSeqFromSender - lastSeqToReceiver > 1) {
// this is a skip - we still send the packet but capture the presence of the skip so we see it happening
++numAvatarsWithSkippedFrames;

View file

@ -164,7 +164,7 @@ public:
void setHasAudioEnabledFaceMovement(bool hasAudioEnabledFaceMovement);
bool getHasAudioEnabledFaceMovement() const override { return _headData->getHasAudioEnabledFaceMovement(); }
private slots:
public slots:
void update(float deltatime);
private:

View file

@ -88,7 +88,7 @@ if (APPLE)
set(OSX_SDK "${OSX_VERSION}" CACHE String "OS X SDK version to look for inside Xcode bundle or at OSX_SDK_PATH")
# set our OS X deployment target
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9)
# find the SDK path for the desired SDK
find_path(

View file

@ -1,14 +1,12 @@
set(EXTERNAL_NAME quazip)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
cmake_policy(SET CMP0046 OLD)
include(ExternalProject)
set(QUAZIP_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_PREFIX_PATH=${QT_CMAKE_PREFIX_PATH} -DCMAKE_INSTALL_NAME_DIR:PATH=<INSTALL_DIR>/lib -DZLIB_ROOT=${ZLIB_ROOT} -DCMAKE_POSITION_INDEPENDENT_CODE=ON)
if (APPLE)
else ()
set(QUAZIP_CMAKE_ARGS ${QUAZIP_CMAKE_ARGS} -DCMAKE_CXX_STANDARD=11)
if (NOT APPLE)
set(QUAZIP_CMAKE_ARGS ${QUAZIP_CMAKE_ARGS} -DCMAKE_CXX_STANDARD=11)
endif ()
ExternalProject_Add(
@ -22,10 +20,12 @@ ExternalProject_Add(
LOG_BUILD 1
)
add_dependencies(quazip zlib)
if (WIN32)
add_dependencies(quazip zlib)
endif ()
# Hide this external target (for ide users)
set_target_properties(${EXTERNAL_NAME} PROPERTIES
set_target_properties(${EXTERNAL_NAME} PROPERTIES
FOLDER "hidden/externals"
INSTALL_NAME_DIR ${INSTALL_DIR}/lib
BUILD_WITH_INSTALL_RPATH True)
@ -54,4 +54,4 @@ select_library_configurations(${EXTERNAL_NAME_UPPER})
# Force selected libraries into the cache
set(${EXTERNAL_NAME_UPPER}_LIBRARY ${${EXTERNAL_NAME_UPPER}_LIBRARY} CACHE FILEPATH "Location of QuaZip libraries")
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE FILEPATH "Location of QuaZip libraries")
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE FILEPATH "Location of QuaZip libraries")

View file

@ -3,11 +3,11 @@ if (WIN32)
endif (WIN32)
if (POLICY CMP0043)
cmake_policy(SET CMP0043 OLD)
cmake_policy(SET CMP0043 NEW)
endif ()
if (POLICY CMP0042)
cmake_policy(SET CMP0042 OLD)
cmake_policy(SET CMP0042 NEW)
endif ()
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
@ -34,7 +34,7 @@ file(GLOB HIFI_CUSTOM_MACROS "cmake/macros/*.cmake")
foreach(CUSTOM_MACRO ${HIFI_CUSTOM_MACROS})
include(${CUSTOM_MACRO})
endforeach()
unset(HIFI_CUSTOM_MACROS)
unset(HIFI_CUSTOM_MACROS)
if (ANDROID)
set(BUILD_SHARED_LIBS ON)

View file

@ -1,10 +1,10 @@
#
#
# Copyright 2015 High Fidelity, Inc.
# Created by Bradley Austin Davis on 2015/10/10
#
# Distributed under the Apache License, Version 2.0.
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
#
#
macro(TARGET_ZLIB)
if (WIN32)

View file

@ -2906,7 +2906,7 @@ void DomainServer::updateReplicationNodes(ReplicationServerDirection direction)
// collect them in a vector to separately remove them with handleKillNode (since eachNode has a read lock and
// we cannot recursively take the write lock required by handleKillNode)
std::vector<SharedNodePointer> nodesToKill;
nodeList->eachNode([direction, replicationNodesInSettings, replicationDirection, &nodesToKill](const SharedNodePointer& otherNode) {
nodeList->eachNode([&direction, &replicationNodesInSettings, &replicationDirection, &nodesToKill](const SharedNodePointer& otherNode) {
if ((direction == Upstream && NodeType::isUpstream(otherNode->getType()))
|| (direction == Downstream && NodeType::isDownstream(otherNode->getType()))) {
bool nodeInSettings = find(replicationNodesInSettings.cbegin(), replicationNodesInSettings.cend(),

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 KiB

View file

@ -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"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 175 KiB

View file

@ -39,6 +39,7 @@ Item {
property string sendingPubliclyEffectImage;
property var http;
property var listModelName;
property var keyboardContainer: nil;
// This object is always used in a popup or full-screen Wallet section.
// This MouseArea is used to prevent a user from being
@ -1125,8 +1126,7 @@ Item {
checked: Settings.getValue("sendAssetsNearbyPublicly", true);
text: "Show Effect"
// Anchors
anchors.top: messageContainer.bottom;
anchors.topMargin: 16;
anchors.verticalCenter: bottomBarContainer.verticalCenter;
anchors.left: parent.left;
anchors.leftMargin: 20;
width: 130;
@ -1168,6 +1168,9 @@ Item {
lightboxPopup.visible = false;
}
lightboxPopup.visible = true;
if (keyboardContainer) {
keyboardContainer.keyboardRaised = false;
}
}
}
}
@ -1178,8 +1181,8 @@ Item {
anchors.leftMargin: 20;
anchors.right: parent.right;
anchors.rightMargin: 20;
anchors.bottom: parent.bottom;
anchors.bottomMargin: 20;
anchors.top: messageContainer.bottom;
anchors.topMargin: 20;
height: 60;
// "CANCEL" button
@ -1187,11 +1190,11 @@ Item {
id: cancelButton_sendAssetStep;
color: root.assetName === "" ? hifi.buttons.noneBorderlessWhite : hifi.buttons.noneBorderlessGray;
colorScheme: hifi.colorSchemes.dark;
anchors.left: parent.left;
anchors.leftMargin: 24;
anchors.right: sendButton.left;
anchors.rightMargin: 24;
anchors.verticalCenter: parent.verticalCenter;
height: 40;
width: 150;
width: 100;
text: "CANCEL";
onClicked: {
resetSendAssetData();
@ -1205,10 +1208,10 @@ Item {
color: hifi.buttons.blue;
colorScheme: root.assetName === "" ? hifi.colorSchemes.dark : hifi.colorSchemes.light;
anchors.right: parent.right;
anchors.rightMargin: 24;
anchors.rightMargin: 0;
anchors.verticalCenter: parent.verticalCenter;
height: 40;
width: 150;
width: 100;
text: "SUBMIT";
onClicked: {
if (root.assetName === "" && parseInt(amountTextField.text) > parseInt(balanceText.text)) {

View file

@ -158,6 +158,7 @@ Rectangle {
listModelName: "Gift Connections";
z: 998;
visible: root.activeView === "giftAsset";
keyboardContainer: root;
anchors.fill: parent;
parentAppTitleBarHeight: 70;
parentAppNavBarHeight: 0;
@ -585,7 +586,7 @@ Rectangle {
visible: purchasesModel.count !== 0;
clip: true;
model: purchasesModel;
snapMode: ListView.SnapToItem;
snapMode: ListView.NoSnap;
// Anchors
anchors.top: separator.bottom;
anchors.left: parent.left;

View file

@ -354,6 +354,7 @@ Rectangle {
listModelName: "Send Money Connections";
z: 997;
visible: root.activeView === "sendMoney";
keyboardContainer: root;
anchors.fill: parent;
parentAppTitleBarHeight: titleBarContainer.height;
parentAppNavBarHeight: tabButtonsContainer.height;

View file

@ -152,6 +152,8 @@
#include <avatars-renderer/ScriptAvatar.h>
#include <RenderableEntityItem.h>
#include <procedural/ProceduralSkybox.h>
#include <model-networking/MaterialCache.h>
#include "recording/ClipCache.h"
#include "AudioClient.h"
#include "audio/AudioScope.h"
@ -328,9 +330,9 @@ static bool DISABLE_DEFERRED = QProcessEnvironment::systemEnvironment().contains
#endif
#if !defined(Q_OS_ANDROID)
static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16;
static const uint32_t MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16;
#else
static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 4;
static const uint32_t MAX_CONCURRENT_RESOURCE_DOWNLOADS = 4;
#endif
// For processing on QThreadPool, we target a number of threads after reserving some
@ -1327,7 +1329,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
QString concurrentDownloadsStr = getCmdOption(argc, constArgv, "--concurrent-downloads");
bool success;
int concurrentDownloads = concurrentDownloadsStr.toInt(&success);
uint32_t concurrentDownloads = concurrentDownloadsStr.toUInt(&success);
if (!success) {
concurrentDownloads = MAX_CONCURRENT_RESOURCE_DOWNLOADS;
}
@ -2054,7 +2056,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
}
properties["active_downloads"] = loadingRequests.size();
properties["pending_downloads"] = ResourceCache::getPendingRequestCount();
properties["pending_downloads"] = (int)ResourceCache::getPendingRequestCount();
properties["active_downloads_details"] = loadingRequestsStats;
auto statTracker = DependencyManager::get<StatTracker>();
@ -3532,6 +3534,7 @@ void Application::setIsInterstitialMode(bool interstitialMode) {
if (enableInterstitial) {
if (_interstitialMode != interstitialMode) {
_interstitialMode = interstitialMode;
emit interstitialModeChanged(_interstitialMode);
DependencyManager::get<AudioClient>()->setAudioPaused(_interstitialMode);
DependencyManager::get<AvatarManager>()->setMyAvatarDataPacketsPaused(_interstitialMode);
@ -4653,8 +4656,8 @@ void Application::idle() {
PROFILE_COUNTER_IF_CHANGED(app, "present", float, displayPlugin->presentRate());
}
PROFILE_COUNTER_IF_CHANGED(app, "renderLoopRate", float, _renderLoopCounter.rate());
PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", int, ResourceCache::getLoadingRequests().length());
PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", int, ResourceCache::getPendingRequestCount());
PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", uint32_t, ResourceCache::getLoadingRequestCount());
PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", uint32_t, ResourceCache::getPendingRequestCount());
PROFILE_COUNTER_IF_CHANGED(app, "currentProcessing", int, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
PROFILE_COUNTER_IF_CHANGED(app, "pendingProcessing", int, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
auto renderConfig = _renderEngine->getConfiguration();
@ -5399,13 +5402,21 @@ void Application::reloadResourceCaches() {
queryOctree(NodeType::EntityServer, PacketType::EntityQuery);
// Clear the entities and their renderables
getEntities()->clear();
DependencyManager::get<AssetClient>()->clearCache();
DependencyManager::get<ScriptCache>()->clearCache();
// Clear all the resource caches
DependencyManager::get<ResourceCacheSharedItems>()->clear();
DependencyManager::get<AnimationCache>()->refreshAll();
DependencyManager::get<ModelCache>()->refreshAll();
DependencyManager::get<SoundCache>()->refreshAll();
MaterialCache::instance().refreshAll();
DependencyManager::get<ModelCache>()->refreshAll();
ShaderCache::instance().refreshAll();
DependencyManager::get<TextureCache>()->refreshAll();
DependencyManager::get<recording::ClipCache>()->refreshAll();
DependencyManager::get<NodeList>()->reset(); // Force redownload of .fst models
@ -6470,9 +6481,12 @@ void Application::clearDomainOctreeDetails() {
skyStage->setBackgroundMode(graphics::SunSkyStage::SKY_DEFAULT);
DependencyManager::get<AnimationCache>()->clearUnusedResources();
DependencyManager::get<ModelCache>()->clearUnusedResources();
DependencyManager::get<SoundCache>()->clearUnusedResources();
MaterialCache::instance().clearUnusedResources();
DependencyManager::get<ModelCache>()->clearUnusedResources();
ShaderCache::instance().clearUnusedResources();
DependencyManager::get<TextureCache>()->clearUnusedResources();
DependencyManager::get<recording::ClipCache>()->clearUnusedResources();
getMyAvatar()->setAvatarEntityDataChanged(true);
}
@ -8463,6 +8477,16 @@ QUuid Application::getTabletFrameID() const {
return HMD->getCurrentTabletFrameID();
}
QVector<QUuid> Application::getTabletIDs() const {
// Most important overlays first.
QVector<QUuid> result;
auto HMD = DependencyManager::get<HMDScriptingInterface>();
result << HMD->getCurrentTabletScreenID();
result << HMD->getCurrentHomeButtonID();
result << HMD->getCurrentTabletFrameID();
return result;
}
void Application::setAvatarOverrideUrl(const QUrl& url, bool save) {
_avatarOverrideUrl = url;
_saveAvatarOverrideUrl = save;

View file

@ -298,6 +298,7 @@ public:
OverlayID getTabletScreenID() const;
OverlayID getTabletHomeButtonID() const;
QUuid getTabletFrameID() const; // may be an entity or an overlay
QVector<QUuid> getTabletIDs() const; // In order of most important IDs first.
void setAvatarOverrideUrl(const QUrl& url, bool save);
void clearAvatarOverrideUrl() { _avatarOverrideUrl = QUrl(); _saveAvatarOverrideUrl = false; }
@ -334,6 +335,8 @@ signals:
void uploadRequest(QString path);
void interstitialModeChanged(bool isInInterstitialMode);
void loginDialogPoppedUp();
public slots:

View file

@ -78,8 +78,10 @@ void addAvatarEntities(const QVariantList& avatarEntities) {
}
entity->setLastBroadcast(usecTimestampNow());
// since we're creating this object we will immediately volunteer to own its simulation
entity->setScriptSimulationPriority(VOLUNTEER_SIMULATION_PRIORITY);
if (entityProperties.getDynamic()) {
// since we're creating a dynamic object we volunteer immediately to own its simulation
entity->upgradeScriptSimulationPriority(VOLUNTEER_SIMULATION_PRIORITY);
}
entityProperties.setLastEdited(entity->getLastEdited());
} else {
qCDebug(entities) << "AvatarEntitiesBookmark failed to add new Entity to local Octree";
@ -108,6 +110,9 @@ AvatarBookmarks::AvatarBookmarks() {
if (!QFile::copy(defaultBookmarksFilename, _bookmarksFilename)) {
qDebug() << "failed to copy" << defaultBookmarksFilename << "to" << _bookmarksFilename;
} else {
QFile bookmarksFile(_bookmarksFilename);
bookmarksFile.setPermissions(bookmarksFile.permissions() | QFile::WriteUser);
}
}
readFromFile();

View file

@ -55,15 +55,7 @@ static const quint64 MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS = USECS_PER_SECOND /
// We add _myAvatar into the hash with all the other AvatarData, and we use the default NULL QUid as the key.
const QUuid MY_AVATAR_KEY; // NULL key
namespace {
// For an unknown avatar-data packet, wait this long before requesting the identity.
constexpr std::chrono::milliseconds REQUEST_UNKNOWN_IDENTITY_DELAY { 5 * 1000 };
constexpr int REQUEST_UNKNOWN_IDENTITY_TRANSMITS = 3;
}
using std::chrono::steady_clock;
AvatarManager::AvatarManager(QObject* parent) :
_avatarsToFade(),
_myAvatar(new MyAvatar(qApp->thread()), [](MyAvatar* ptr) { ptr->deleteLater(); })
{
// register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
@ -345,28 +337,6 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
simulateAvatarFades(deltaTime);
// Check on avatars with pending identities:
steady_clock::time_point now = steady_clock::now();
QWriteLocker writeLock(&_hashLock);
for (auto pendingAvatar = _pendingAvatars.begin(); pendingAvatar != _pendingAvatars.end(); ++pendingAvatar) {
if (now - pendingAvatar->creationTime >= REQUEST_UNKNOWN_IDENTITY_DELAY) {
// Too long without an ID
sendIdentityRequest(pendingAvatar->avatar->getID());
if (++pendingAvatar->transmits >= REQUEST_UNKNOWN_IDENTITY_TRANSMITS) {
qCDebug(avatars) << "Requesting identity for unknown avatar (final request)" <<
pendingAvatar->avatar->getID().toString();
pendingAvatar = _pendingAvatars.erase(pendingAvatar);
if (pendingAvatar == _pendingAvatars.end()) {
break;
}
} else {
pendingAvatar->creationTime = now;
qCDebug(avatars) << "Requesting identity for unknown avatar" << pendingAvatar->avatar->getID().toString();
}
}
}
_avatarSimulationTime = (float)(usecTimestampNow() - startTime) / (float)USECS_PER_MSEC;
}

View file

@ -55,6 +55,7 @@ using SortedAvatar = std::pair<float, std::shared_ptr<Avatar>>;
* @borrows AvatarList.sessionUUIDChanged as sessionUUIDChanged
* @borrows AvatarList.processAvatarDataPacket as processAvatarDataPacket
* @borrows AvatarList.processAvatarIdentityPacket as processAvatarIdentityPacket
* @borrows AvatarList.processBulkAvatarTraits as processBulkAvatarTraits
* @borrows AvatarList.processKillAvatar as processKillAvatar
*/
@ -152,6 +153,13 @@ public:
const QVector<EntityItemID>& avatarsToInclude,
const QVector<EntityItemID>& avatarsToDiscard);
/**jsdoc
* @function AvatarManager.findParabolaIntersectionVector
* @param {PickParabola} pick
* @param {Uuid[]} avatarsToInclude
* @param {Uuid[]} avatarsToDiscard
* @returns {ParabolaToAvatarIntersectionResult}
*/
Q_INVOKABLE ParabolaToAvatarIntersectionResult findParabolaIntersectionVector(const PickParabola& pick,
const QVector<EntityItemID>& avatarsToInclude,
const QVector<EntityItemID>& avatarsToDiscard);
@ -176,7 +184,7 @@ public:
* than iterating over each avatar and obtaining data about them in JavaScript, as that method
* locks and unlocks each avatar's data structure potentially hundreds of times per update tick.
* @function AvatarManager.getPalData
* @param {string[]} specificAvatarIdentifiers - A list of specific Avatar Identifiers about
* @param {string[]} [specificAvatarIdentifiers] - A list of specific Avatar Identifiers about
* which you want to get PAL data
* @returns {object}
*/

View file

@ -122,7 +122,6 @@ MyAvatar::MyAvatar(QThread* thread) :
_goToOrientation(),
_prevShouldDrawHead(true),
_audioListenerMode(FROM_HEAD),
_hmdAtRestDetector(glm::vec3(0), glm::quat()),
_dominantHandSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "dominantHand", DOMINANT_RIGHT_HAND),
_headPitchSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "", 0.0f),
_scaleSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "scale", _targetScale),
@ -702,6 +701,46 @@ void MyAvatar::simulate(float deltaTime) {
// before we perform rig animations and IK.
updateSensorToWorldMatrix();
// if we detect the hand controller is at rest, i.e. lying on the table, or the hand is too far away from the hmd
// disable the associated hand controller input.
{
// NOTE: all poses are in sensor space.
auto leftHandIter = _controllerPoseMap.find(controller::Action::LEFT_HAND);
if (leftHandIter != _controllerPoseMap.end() && leftHandIter->second.isValid()) {
_leftHandAtRestDetector.update(leftHandIter->second.getTranslation(), leftHandIter->second.getRotation());
if (_leftHandAtRestDetector.isAtRest()) {
leftHandIter->second.valid = false;
}
} else {
_leftHandAtRestDetector.invalidate();
}
auto rightHandIter = _controllerPoseMap.find(controller::Action::RIGHT_HAND);
if (rightHandIter != _controllerPoseMap.end() && rightHandIter->second.isValid()) {
_rightHandAtRestDetector.update(rightHandIter->second.getTranslation(), rightHandIter->second.getRotation());
if (_rightHandAtRestDetector.isAtRest()) {
rightHandIter->second.valid = false;
}
} else {
_rightHandAtRestDetector.invalidate();
}
auto headIter = _controllerPoseMap.find(controller::Action::HEAD);
// The 99th percentile man has a spine to fingertip to height ratio of 0.45. Lets increase that by about 10% to 0.5
// then measure the distance the center of the eyes to the finger tips. To come up with this ratio.
// From "The Measure of Man and Woman: Human Factors in Design, Revised Edition" by Alvin R. Tilley, Henry Dreyfuss Associates
const float MAX_HEAD_TO_HAND_DISTANCE_RATIO = 0.52f;
float maxHeadHandDistance = getUserHeight() * MAX_HEAD_TO_HAND_DISTANCE_RATIO;
if (glm::length(headIter->second.getTranslation() - leftHandIter->second.getTranslation()) > maxHeadHandDistance) {
leftHandIter->second.valid = false;
}
if (glm::length(headIter->second.getTranslation() - rightHandIter->second.getTranslation()) > maxHeadHandDistance) {
rightHandIter->second.valid = false;
}
}
{
PerformanceTimer perfTimer("skeleton");
@ -1941,7 +1980,7 @@ void MyAvatar::updateMotors() {
horizontalMotorTimescale = FLYING_MOTOR_TIMESCALE;
verticalMotorTimescale = FLYING_MOTOR_TIMESCALE;
} else {
horizontalMotorTimescale = WALKING_MOTOR_TIMESCALE;
horizontalMotorTimescale = WALKING_MOTOR_TIMESCALE * getSensorToWorldScale();
verticalMotorTimescale = INVALID_MOTOR_TIMESCALE;
}

View file

@ -629,8 +629,6 @@ public:
const MyHead* getMyHead() const;
Q_INVOKABLE void toggleSmoothPoleVectors() { _skeletonModel->getRig().toggleSmoothPoleVectors(); };
/**jsdoc
* Get the current position of the avatar's "Head" joint.
* @function MyAvatar.getHeadPosition
@ -951,50 +949,72 @@ public:
void removeWearableAvatarEntities();
/**jsdoc
* Check whether your avatar is flying or not.
* @function MyAvatar.isFlying
* @returns {boolean}
* @returns {boolean} <code>true</code> if your avatar is flying and not taking off or falling, otherwise
* <code>false</code>.
*/
Q_INVOKABLE bool isFlying();
/**jsdoc
* Check whether your avatar is in the air or not.
* @function MyAvatar.isInAir
* @returns {boolean}
* @returns {boolean} <code>true</code> if your avatar is taking off, flying, or falling, otherwise <code>false</code>
* because your avatar is on the ground.
*/
Q_INVOKABLE bool isInAir();
/**jsdoc
* Set your preference for flying in your current desktop or HMD display mode. Note that your ability to fly also depends
* on whether the domain you're in allows you to fly.
* @function MyAvatar.setFlyingEnabled
* @param {boolean} enabled
* @param {boolean} enabled - Set <code>true</code> if you want to enable flying in your current desktop or HMD display
* mode, otherwise set <code>false</code>.
*/
Q_INVOKABLE void setFlyingEnabled(bool enabled);
/**jsdoc
* Get your preference for flying in your current desktop or HMD display mode. Note that your ability to fly also depends
* on whether the domain you're in allows you to fly.
* @function MyAvatar.getFlyingEnabled
* @returns {boolean}
* @returns {boolean} <code>true</code> if your preference is to enable flying in your current desktop or HMD display mode,
* otherwise <code>false</code>.
*/
Q_INVOKABLE bool getFlyingEnabled();
/**jsdoc
* Set your preference for flying in desktop display mode. Note that your ability to fly also depends on whether the domain
* you're in allows you to fly.
* @function MyAvatar.setFlyingDesktopPref
* @param {boolean} enabled
* @param {boolean} enabled - Set <code>true</code> if you want to enable flying in desktop display mode, otherwise set
* <code>false</code>.
*/
Q_INVOKABLE void setFlyingDesktopPref(bool enabled);
/**jsdoc
* Get your preference for flying in desktop display mode. Note that your ability to fly also depends on whether the domain
* you're in allows you to fly.
* @function MyAvatar.getFlyingDesktopPref
* @returns {boolean}
* @returns {boolean} <code>true</code> if your preference is to enable flying in desktop display mode, otherwise
* <code>false</code>.
*/
Q_INVOKABLE bool getFlyingDesktopPref();
/**jsdoc
* @function MyAvatar.setFlyingDesktopPref
* @param {boolean} enabled
* Set your preference for flying in HMD display mode. Note that your ability to fly also depends on whether the domain
* you're in allows you to fly.
* @function MyAvatar.setFlyingHMDPref
* @param {boolean} enabled - Set <code>true</code> if you want to enable flying in HMD display mode, otherwise set
* <code>false</code>.
*/
Q_INVOKABLE void setFlyingHMDPref(bool enabled);
/**jsdoc
* @function MyAvatar.getFlyingDesktopPref
* @returns {boolean}
* Get your preference for flying in HMD display mode. Note that your ability to fly also depends on whether the domain
* you're in allows you to fly.
* @function MyAvatar.getFlyingHMDPref
* @returns {boolean} <code>true</code> if your preference is to enable flying in HMD display mode, otherwise
* <code>false</code>.
*/
Q_INVOKABLE bool getFlyingHMDPref();
@ -1766,8 +1786,8 @@ private:
glm::vec3 _customListenPosition;
glm::quat _customListenOrientation;
AtRestDetector _hmdAtRestDetector;
bool _lastIsMoving { false };
AtRestDetector _leftHandAtRestDetector;
AtRestDetector _rightHandAtRestDetector;
// all poses are in sensor-frame
std::map<controller::Action, controller::Pose> _controllerPoseMap;

View file

@ -46,7 +46,7 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) {
}
glm::mat4 hipsMat;
if (myAvatar->getCenterOfGravityModelEnabled() && !isFlying && !(myAvatar->getIsInWalkingState())) {
if (myAvatar->getCenterOfGravityModelEnabled() && !isFlying && !(myAvatar->getIsInWalkingState()) && myAvatar->getHMDLeanRecenterEnabled()) {
// then we use center of gravity model
hipsMat = myAvatar->deriveBodyUsingCgModel();
} else {

View file

@ -11,12 +11,12 @@
#include "AvatarMotionState.h"
static xColor getLoadingOrbColor(Avatar::LoadingStatus loadingStatus) {
static glm::u8vec3 getLoadingOrbColor(Avatar::LoadingStatus loadingStatus) {
const xColor NO_MODEL_COLOR(0xe3, 0xe3, 0xe3);
const xColor LOAD_MODEL_COLOR(0xef, 0x93, 0xd1);
const xColor LOAD_SUCCESS_COLOR(0x1f, 0xc6, 0xa6);
const xColor LOAD_FAILURE_COLOR(0xc6, 0x21, 0x47);
const glm::u8vec3 NO_MODEL_COLOR(0xe3, 0xe3, 0xe3);
const glm::u8vec3 LOAD_MODEL_COLOR(0xef, 0x93, 0xd1);
const glm::u8vec3 LOAD_SUCCESS_COLOR(0x1f, 0xc6, 0xa6);
const glm::u8vec3 LOAD_FAILURE_COLOR(0xc6, 0x21, 0x47);
switch (loadingStatus) {
case Avatar::LoadingStatus::NoModel:
return NO_MODEL_COLOR;

View file

@ -76,4 +76,4 @@ protected:
bool _includeNormals;
};
#endif // hifi_CollisionPick_h
#endif // hifi_CollisionPick_h

View file

@ -52,8 +52,7 @@ void ParabolaPointer::editRenderStatePath(const std::string& state, const QVaria
if (!pathMap.isEmpty()) {
enabled = true;
if (pathMap["color"].isValid()) {
bool valid;
color = toGlm(xColorFromVariant(pathMap["color"], valid));
color = toGlm(u8vec3FromVariant(pathMap["color"]));
}
if (pathMap["alpha"].isValid()) {
alpha = pathMap["alpha"].toFloat();
@ -250,8 +249,7 @@ std::shared_ptr<StartEndRenderState> ParabolaPointer::buildRenderState(const QVa
enabled = true;
QVariantMap pathMap = propMap["path"].toMap();
if (pathMap["color"].isValid()) {
bool valid;
color = toGlm(xColorFromVariant(pathMap["color"], valid));
color = toGlm(u8vec3FromVariant(pathMap["color"]));
}
if (pathMap["alpha"].isValid()) {

View file

@ -27,7 +27,7 @@ class StartEndRenderState {
public:
StartEndRenderState() {}
StartEndRenderState(const OverlayID& startID, const OverlayID& endID);
virtual ~StartEndRenderState() {}
virtual ~StartEndRenderState() = default;
const OverlayID& getStartID() const { return _startID; }
const OverlayID& getEndID() const { return _endID; }

View file

@ -421,7 +421,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
auto colorVariant = properties["outlineUnoccludedColor"];
if (colorVariant.isValid()) {
bool isValid;
auto color = xColorFromVariant(colorVariant, isValid);
auto color = u8vec3FromVariant(colorVariant, isValid);
if (isValid) {
_style._outlineUnoccluded.color = toGlm(color);
}
@ -429,7 +429,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
colorVariant = properties["outlineOccludedColor"];
if (colorVariant.isValid()) {
bool isValid;
auto color = xColorFromVariant(colorVariant, isValid);
auto color = u8vec3FromVariant(colorVariant, isValid);
if (isValid) {
_style._outlineOccluded.color = toGlm(color);
}
@ -437,7 +437,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
colorVariant = properties["fillUnoccludedColor"];
if (colorVariant.isValid()) {
bool isValid;
auto color = xColorFromVariant(colorVariant, isValid);
auto color = u8vec3FromVariant(colorVariant, isValid);
if (isValid) {
_style._fillUnoccluded.color = toGlm(color);
}
@ -445,7 +445,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
colorVariant = properties["fillOccludedColor"];
if (colorVariant.isValid()) {
bool isValid;
auto color = xColorFromVariant(colorVariant, isValid);
auto color = u8vec3FromVariant(colorVariant, isValid);
if (isValid) {
_style._fillOccluded.color = toGlm(color);
}
@ -497,10 +497,11 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
QVariantMap SelectionHighlightStyle::toVariantMap() const {
QVariantMap properties;
properties["outlineUnoccludedColor"] = xColorToVariant(xColorFromGlm(_style._outlineUnoccluded.color));
properties["outlineOccludedColor"] = xColorToVariant(xColorFromGlm(_style._outlineOccluded.color));
properties["fillUnoccludedColor"] = xColorToVariant(xColorFromGlm(_style._fillUnoccluded.color));
properties["fillOccludedColor"] = xColorToVariant(xColorFromGlm(_style._fillOccluded.color));
const float MAX_COLOR = 255.0f;
properties["outlineUnoccludedColor"] = u8vec3ColortoVariant(_style._outlineUnoccluded.color * MAX_COLOR);
properties["outlineOccludedColor"] = u8vec3ColortoVariant(_style._outlineOccluded.color * MAX_COLOR);
properties["fillUnoccludedColor"] = u8vec3ColortoVariant(_style._fillUnoccluded.color * MAX_COLOR);
properties["fillOccludedColor"] = u8vec3ColortoVariant(_style._fillOccluded.color * MAX_COLOR);
properties["outlineUnoccludedAlpha"] = _style._outlineUnoccluded.alpha;
properties["outlineOccludedAlpha"] = _style._outlineOccluded.alpha;

View file

@ -54,6 +54,9 @@ WindowScriptingInterface::WindowScriptingInterface() {
});
connect(qApp->getWindow(), &MainWindow::windowGeometryChanged, this, &WindowScriptingInterface::onWindowGeometryChanged);
connect(qApp, &Application::interstitialModeChanged, [this] (bool interstitialMode) {
emit interstitialModeChanged(interstitialMode);
});
}
WindowScriptingInterface::~WindowScriptingInterface() {

View file

@ -619,6 +619,14 @@ signals:
*/
void redirectErrorStateChanged(bool isInErrorState);
/**jsdoc
* Triggered when interstitial mode changes.
* @function Window.interstitialModeChanged
* @param {bool} interstitialMode - The mode of the interstitial is changed to.
* @returns {Signal}
*/
void interstitialModeChanged(bool interstitialMode);
/**jsdoc
* Triggered when a still snapshot has been taken by calling {@link Window.takeSnapshot|takeSnapshot} with
* <code>includeAnimated = false</code> or {@link Window.takeSecondaryCameraSnapshot|takeSecondaryCameraSnapshot}.

View file

@ -267,8 +267,8 @@ void Stats::updateStats(bool force) {
auto loadingRequests = ResourceCache::getLoadingRequests();
STAT_UPDATE(downloads, loadingRequests.size());
STAT_UPDATE(downloadLimit, ResourceCache::getRequestLimit())
STAT_UPDATE(downloadsPending, ResourceCache::getPendingRequestCount());
STAT_UPDATE(downloadLimit, (int)ResourceCache::getRequestLimit())
STAT_UPDATE(downloadsPending, (int)ResourceCache::getPendingRequestCount());
STAT_UPDATE(processing, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
STAT_UPDATE(processingPending, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());

View file

@ -191,8 +191,6 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) {
if (properties["parentID"].isValid()) {
setParentID(QUuid(properties["parentID"].toString()));
bool success;
getParentPointer(success); // call this to hook-up the parent's back-pointers to its child overlays
needRenderItemUpdate = true;
}
if (properties["parentJointIndex"].isValid()) {

View file

@ -75,7 +75,6 @@ void Circle3DOverlay::render(RenderArgs* args) {
const float FULL_CIRCLE = 360.0f;
const float SLICES = 180.0f; // The amount of segment to create the circle
const float SLICE_ANGLE_RADIANS = glm::radians(FULL_CIRCLE / SLICES);
const float MAX_COLOR = 255.0f;
auto geometryCache = DependencyManager::get<GeometryCache>();
@ -246,20 +245,15 @@ void Circle3DOverlay::render(RenderArgs* args) {
angle += tickMarkAngle;
}
}
xColor majorColorX = getMajorTickMarksColor();
glm::vec4 majorColor(majorColorX.red / MAX_COLOR, majorColorX.green / MAX_COLOR, majorColorX.blue / MAX_COLOR, alpha);
glm::vec4 majorColor(toGlm(getMajorTickMarksColor()), alpha);
geometryCache->updateVertices(_majorTicksVerticesID, majorPoints, majorColor);
xColor minorColorX = getMinorTickMarksColor();
glm::vec4 minorColor(minorColorX.red / MAX_COLOR, minorColorX.green / MAX_COLOR, minorColorX.blue / MAX_COLOR, alpha);
glm::vec4 minorColor(toGlm(getMinorTickMarksColor()), alpha);
geometryCache->updateVertices(_minorTicksVerticesID, minorPoints, minorColor);
}
geometryCache->renderVertices(batch, gpu::LINES, _majorTicksVerticesID);
geometryCache->renderVertices(batch, gpu::LINES, _minorTicksVerticesID);
}
}
@ -280,8 +274,8 @@ template<typename T> T fromVariant(const QVariant& v, bool& valid) {
return qvariant_cast<T>(v);
}
template<> xColor fromVariant(const QVariant& v, bool& valid) {
return xColorFromVariant(v, valid);
template<> glm::u8vec3 fromVariant(const QVariant& v, bool& valid) {
return u8vec3FromVariant(v, valid);
}
template<typename T>
@ -344,11 +338,11 @@ void Circle3DOverlay::setProperties(const QVariantMap& properties) {
_dirty |= updateIfValid(properties, "outerStartAlpha", _outerStartAlpha);
_dirty |= updateIfValid(properties, "outerEndAlpha", _outerEndAlpha);
_dirty |= updateIfValid<xColor>(properties, "color", { _innerStartColor, _innerEndColor, _outerStartColor, _outerEndColor });
_dirty |= updateIfValid<xColor>(properties, "startColor", { _innerStartColor, _outerStartColor } );
_dirty |= updateIfValid<xColor>(properties, "endColor", { _innerEndColor, _outerEndColor } );
_dirty |= updateIfValid<xColor>(properties, "innerColor", { _innerStartColor, _innerEndColor } );
_dirty |= updateIfValid<xColor>(properties, "outerColor", { _outerStartColor, _outerEndColor } );
_dirty |= updateIfValid<glm::u8vec3>(properties, "color", { _innerStartColor, _innerEndColor, _outerStartColor, _outerEndColor });
_dirty |= updateIfValid<glm::u8vec3>(properties, "startColor", { _innerStartColor, _outerStartColor } );
_dirty |= updateIfValid<glm::u8vec3>(properties, "endColor", { _innerEndColor, _outerEndColor } );
_dirty |= updateIfValid<glm::u8vec3>(properties, "innerColor", { _innerStartColor, _innerEndColor } );
_dirty |= updateIfValid<glm::u8vec3>(properties, "outerColor", { _outerStartColor, _outerEndColor } );
_dirty |= updateIfValid(properties, "innerStartColor", _innerStartColor);
_dirty |= updateIfValid(properties, "innerEndColor", _innerEndColor);
_dirty |= updateIfValid(properties, "outerStartColor", _outerStartColor);
@ -421,7 +415,7 @@ void Circle3DOverlay::setProperties(const QVariantMap& properties) {
* @property {number} endAt=360 - The counter-clockwise angle from the overlay's x-axis that drawing ends at, in degrees.
* @property {number} outerRadius=1 - The outer radius of the overlay, in meters. Synonym: <code>radius</code>.
* @property {number} innerRadius=0 - The inner radius of the overlay, in meters.
* @property {Color} color=255,255,255 - The color of the overlay. Setting this value also sets the values of
* @property {Color} color=255,255,255 - The color of the overlay. Setting this value also sets the values of
* <code>innerStartColor</code>, <code>innerEndColor</code>, <code>outerStartColor</code>, and <code>outerEndColor</code>.
* @property {Color} startColor - Sets the values of <code>innerStartColor</code> and <code>outerStartColor</code>.
* <em>Write-only.</em>
@ -478,16 +472,16 @@ QVariant Circle3DOverlay::getProperty(const QString& property) {
return _innerRadius;
}
if (property == "innerStartColor") {
return xColorToVariant(_innerStartColor);
return u8vec3ColortoVariant(_innerStartColor);
}
if (property == "innerEndColor") {
return xColorToVariant(_innerEndColor);
return u8vec3ColortoVariant(_innerEndColor);
}
if (property == "outerStartColor") {
return xColorToVariant(_outerStartColor);
return u8vec3ColortoVariant(_outerStartColor);
}
if (property == "outerEndColor") {
return xColorToVariant(_outerEndColor);
return u8vec3ColortoVariant(_outerEndColor);
}
if (property == "innerStartAlpha") {
return _innerStartAlpha;
@ -517,10 +511,10 @@ QVariant Circle3DOverlay::getProperty(const QString& property) {
return _minorTickMarksLength;
}
if (property == "majorTickMarksColor") {
return xColorToVariant(_majorTickMarksColor);
return u8vec3ColortoVariant(_majorTickMarksColor);
}
if (property == "minorTickMarksColor") {
return xColorToVariant(_minorTickMarksColor);
return u8vec3ColortoVariant(_minorTickMarksColor);
}
return Planar3DOverlay::getProperty(property);

View file

@ -39,8 +39,8 @@ public:
float getMinorTickMarksAngle() const { return _minorTickMarksAngle; }
float getMajorTickMarksLength() const { return _majorTickMarksLength; }
float getMinorTickMarksLength() const { return _minorTickMarksLength; }
xColor getMajorTickMarksColor() const { return _majorTickMarksColor; }
xColor getMinorTickMarksColor() const { return _minorTickMarksColor; }
glm::u8vec3 getMajorTickMarksColor() const { return _majorTickMarksColor; }
glm::u8vec3 getMinorTickMarksColor() const { return _minorTickMarksColor; }
void setStartAt(float value) { _startAt = value; }
void setEndAt(float value) { _endAt = value; }
@ -51,8 +51,8 @@ public:
void setMinorTickMarksAngle(float value) { _minorTickMarksAngle = value; }
void setMajorTickMarksLength(float value) { _majorTickMarksLength = value; }
void setMinorTickMarksLength(float value) { _minorTickMarksLength = value; }
void setMajorTickMarksColor(const xColor& value) { _majorTickMarksColor = value; }
void setMinorTickMarksColor(const xColor& value) { _minorTickMarksColor = value; }
void setMajorTickMarksColor(const glm::u8vec3& value) { _majorTickMarksColor = value; }
void setMinorTickMarksColor(const glm::u8vec3& value) { _minorTickMarksColor = value; }
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, bool precisionPicking = false) override;
@ -67,10 +67,10 @@ protected:
float _outerRadius { 1 };
float _innerRadius { 0 };
xColor _innerStartColor { DEFAULT_OVERLAY_COLOR };
xColor _innerEndColor { DEFAULT_OVERLAY_COLOR };
xColor _outerStartColor { DEFAULT_OVERLAY_COLOR };
xColor _outerEndColor { DEFAULT_OVERLAY_COLOR };
glm::u8vec3 _innerStartColor { DEFAULT_OVERLAY_COLOR };
glm::u8vec3 _innerEndColor { DEFAULT_OVERLAY_COLOR };
glm::u8vec3 _outerStartColor { DEFAULT_OVERLAY_COLOR };
glm::u8vec3 _outerEndColor { DEFAULT_OVERLAY_COLOR };
float _innerStartAlpha { DEFAULT_ALPHA };
float _innerEndAlpha { DEFAULT_ALPHA };
float _outerStartAlpha { DEFAULT_ALPHA };
@ -81,8 +81,8 @@ protected:
float _minorTickMarksAngle { 0 };
float _majorTickMarksLength { 0 };
float _minorTickMarksLength { 0 };
xColor _majorTickMarksColor { DEFAULT_OVERLAY_COLOR };
xColor _minorTickMarksColor { DEFAULT_OVERLAY_COLOR };
glm::u8vec3 _majorTickMarksColor { DEFAULT_OVERLAY_COLOR };
glm::u8vec3 _minorTickMarksColor { DEFAULT_OVERLAY_COLOR };
gpu::Primitive _solidPrimitive { gpu::TRIANGLE_FAN };
int _quadVerticesID { 0 };
int _lineVerticesID { 0 };

View file

@ -83,7 +83,7 @@ ContextOverlayInterface::ContextOverlayInterface() {
_challengeOwnershipTimeoutTimer.setSingleShot(true);
}
static const xColor CONTEXT_OVERLAY_COLOR = { 255, 255, 255 };
static const glm::u8vec3 CONTEXT_OVERLAY_COLOR = { 255, 255, 255 };
static const float CONTEXT_OVERLAY_INSIDE_DISTANCE = 1.0f; // in meters
static const float CONTEXT_OVERLAY_SIZE = 0.09f; // in meters, same x and y dims
static const float CONTEXT_OVERLAY_OFFSET_DISTANCE = 0.1f;
@ -142,14 +142,15 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID&
glm::vec3 cameraPosition = qApp->getCamera().getPosition();
glm::vec3 entityDimensions = entityProperties.getDimensions();
glm::vec3 entityPosition = entityProperties.getPosition();
glm::vec3 registrationPoint = entityProperties.getRegistrationPoint();
glm::vec3 contextOverlayPosition = entityProperties.getPosition();
glm::vec2 contextOverlayDimensions;
// Update the position of the overlay if the registration point of the entity
// isn't default
if (entityProperties.getRegistrationPoint() != glm::vec3(0.5f)) {
glm::vec3 adjustPos = entityProperties.getRegistrationPoint() - glm::vec3(0.5f);
entityPosition = entityPosition - (entityProperties.getRotation() * (adjustPos * entityProperties.getDimensions()));
if (registrationPoint != glm::vec3(0.5f)) {
glm::vec3 adjustPos = registrationPoint - glm::vec3(0.5f);
entityPosition = entityPosition - (entityProperties.getRotation() * (adjustPos * entityDimensions));
}
enableEntityHighlight(entityItemID);

View file

@ -49,11 +49,8 @@ void Cube3DOverlay::render(RenderArgs* args) {
}
float alpha = getAlpha();
xColor color = getColor();
const float MAX_COLOR = 255.0f;
glm::vec4 cubeColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
glm::u8vec3 color = getColor();
glm::vec4 cubeColor(toGlm(color), alpha);
auto batch = args->_batch;
if (batch) {

View file

@ -57,11 +57,9 @@ void Grid3DOverlay::render(RenderArgs* args) {
return; // do nothing if we're not visible
}
const float MAX_COLOR = 255.0f;
float alpha = getAlpha();
xColor color = getColor();
glm::vec4 gridColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
glm::u8vec3 color = getColor();
glm::vec4 gridColor(toGlm(color), alpha);
auto batch = args->_batch;

View file

@ -107,17 +107,16 @@ void Image3DOverlay::render(RenderArgs* args) {
glm::vec2 texCoordBottomRight((fromImage.x() + fromImage.width() - 0.5f) / imageWidth,
(fromImage.y() + fromImage.height() - 0.5f) / imageHeight);
const float MAX_COLOR = 255.0f;
xColor color = getColor();
float alpha = getAlpha();
glm::u8vec3 color = getColor();
glm::vec4 imageColor(toGlm(color), alpha);
batch->setModelTransform(getRenderTransform());
batch->setResourceTexture(0, _texture->getGPUTexture());
DependencyManager::get<GeometryCache>()->renderQuad(
*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha),
_geometryId
imageColor, _geometryId
);
batch->setResourceTexture(0, nullptr); // restore default white color after me

View file

@ -128,9 +128,8 @@ void Line3DOverlay::render(RenderArgs* args) {
}
float alpha = getAlpha();
xColor color = getColor();
const float MAX_COLOR = 255.0f;
glm::vec4 colorv4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
glm::u8vec3 color = getColor();
glm::vec4 colorv4(toGlm(color), alpha);
auto batch = args->_batch;
if (batch) {
batch->setModelTransform(Transform());

View file

@ -15,7 +15,7 @@
#include "Application.h"
const xColor Overlay::DEFAULT_OVERLAY_COLOR = { 255, 255, 255 };
const glm::u8vec3 Overlay::DEFAULT_OVERLAY_COLOR = { 255, 255, 255 };
const float Overlay::DEFAULT_ALPHA = 0.7f;
Overlay::Overlay() :
@ -57,7 +57,7 @@ Overlay::~Overlay() {
void Overlay::setProperties(const QVariantMap& properties) {
bool valid;
auto color = xColorFromVariant(properties["color"], valid);
auto color = u8vec3FromVariant(properties["color"], valid);
if (valid) {
_color = color;
}
@ -116,7 +116,7 @@ QVariant Overlay::getProperty(const QString& property) {
return QVariant(getType());
}
if (property == "color") {
return xColorToVariant(_color);
return u8vec3ColortoVariant(_color);
}
if (property == "alpha") {
return _alpha;
@ -143,21 +143,21 @@ QVariant Overlay::getProperty(const QString& property) {
return QVariant();
}
xColor Overlay::getColor() {
glm::u8vec3 Overlay::getColor() {
if (_colorPulse == 0.0f) {
return _color;
}
float pulseLevel = updatePulse();
xColor result = _color;
glm::u8vec3 result = _color;
if (_colorPulse < 0.0f) {
result.red *= (1.0f - pulseLevel);
result.green *= (1.0f - pulseLevel);
result.blue *= (1.0f - pulseLevel);
result.x *= (1.0f - pulseLevel);
result.y *= (1.0f - pulseLevel);
result.z *= (1.0f - pulseLevel);
} else {
result.red *= pulseLevel;
result.green *= pulseLevel;
result.blue *= pulseLevel;
result.x *= pulseLevel;
result.y *= pulseLevel;
result.z *= pulseLevel;
}
return result;
}

View file

@ -11,8 +11,6 @@
#ifndef hifi_Overlay_h
#define hifi_Overlay_h
// include this before QGLWidget, which includes an earlier version of OpenGL
#include <SharedUtil.h> // for xColor
#include <render/Scene.h>
class OverlayID : public QUuid {
@ -59,7 +57,7 @@ public:
virtual bool isTransparent() { return getAlphaPulse() != 0.0f || getAlpha() != 1.0f; };
virtual bool getIsVisibleInSecondaryCamera() const { return false; }
xColor getColor();
glm::u8vec3 getColor();
float getAlpha();
float getPulseMax() const { return _pulseMax; }
@ -73,7 +71,7 @@ public:
// setters
virtual void setVisible(bool visible) { _visible = visible; }
void setDrawHUDLayer(bool drawHUDLayer);
void setColor(const xColor& color) { _color = color; }
void setColor(const glm::u8vec3& color) { _color = color; }
void setAlpha(float alpha) { _alpha = alpha; }
void setPulseMax(float value) { _pulseMax = value; }
@ -115,12 +113,12 @@ protected:
float _alphaPulse; // ratio of the pulse to the alpha
float _colorPulse; // ratio of the pulse to the color
xColor _color;
glm::u8vec3 _color;
bool _visible; // should the overlay be drawn at all
unsigned int _stackOrder { 0 };
static const xColor DEFAULT_OVERLAY_COLOR;
static const glm::u8vec3 DEFAULT_OVERLAY_COLOR;
static const float DEFAULT_ALPHA;
std::unordered_map<std::string, graphics::MultiMaterial> _materials;

View file

@ -532,6 +532,8 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionVector(const PickRay
bool visibleOnly, bool collidableOnly) {
float bestDistance = std::numeric_limits<float>::max();
bool bestIsFront = false;
bool bestIsTablet = false;
auto tabletIDs = qApp->getTabletIDs();
QMutexLocker locker(&_mutex);
RayToOverlayIntersectionResult result;
@ -554,10 +556,11 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionVector(const PickRay
if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance,
thisFace, thisSurfaceNormal, thisExtraInfo, precisionPicking)) {
bool isDrawInFront = thisOverlay->getDrawInFront();
if ((bestIsFront && isDrawInFront && thisDistance < bestDistance)
|| (!bestIsFront && (isDrawInFront || thisDistance < bestDistance))) {
bool isTablet = tabletIDs.contains(thisID);
if ((isDrawInFront && !bestIsFront && !bestIsTablet)
|| ((isTablet || isDrawInFront || !bestIsFront) && thisDistance < bestDistance)) {
bestIsFront = isDrawInFront;
bestIsTablet = isTablet;
bestDistance = thisDistance;
result.intersects = true;
result.distance = thisDistance;
@ -629,9 +632,9 @@ QScriptValue RayToOverlayIntersectionResultToScriptValue(QScriptEngine* engine,
obj.setProperty("distance", value.distance);
obj.setProperty("face", boxFaceToString(value.face));
QScriptValue intersection = vec3toScriptValue(engine, value.intersection);
QScriptValue intersection = vec3ToScriptValue(engine, value.intersection);
obj.setProperty("intersection", intersection);
QScriptValue surfaceNormal = vec3toScriptValue(engine, value.surfaceNormal);
QScriptValue surfaceNormal = vec3ToScriptValue(engine, value.surfaceNormal);
obj.setProperty("surfaceNormal", surfaceNormal);
obj.setProperty("extraInfo", engine->toScriptValue(value.extraInfo));
return obj;
@ -828,40 +831,12 @@ PointerEvent Overlays::calculateOverlayPointerEvent(OverlayID overlayID, PickRay
}
RayToOverlayIntersectionResult Overlays::findRayIntersectionForMouseEvent(PickRay ray) {
QVector<OverlayID> overlaysToInclude;
QVector<OverlayID> overlaysToDiscard;
RayToOverlayIntersectionResult rayPickResult;
// first priority is tablet screen
overlaysToInclude << qApp->getTabletScreenID();
rayPickResult = findRayIntersectionVector(ray, true, overlaysToInclude, overlaysToDiscard);
if (rayPickResult.intersects) {
return rayPickResult;
}
// then tablet home button
overlaysToInclude.clear();
overlaysToInclude << qApp->getTabletHomeButtonID();
rayPickResult = findRayIntersectionVector(ray, true, overlaysToInclude, overlaysToDiscard);
if (rayPickResult.intersects) {
return rayPickResult;
}
// then tablet frame
overlaysToInclude.clear();
overlaysToInclude << OverlayID(qApp->getTabletFrameID());
rayPickResult = findRayIntersectionVector(ray, true, overlaysToInclude, overlaysToDiscard);
if (rayPickResult.intersects) {
return rayPickResult;
}
// then whatever
return findRayIntersection(ray);
}
bool Overlays::mousePressEvent(QMouseEvent* event) {
PerformanceTimer perfTimer("Overlays::mousePressEvent");
PickRay ray = qApp->computePickRay(event->x(), event->y());
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray);
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(),
QVector<OverlayID>());
if (rayPickResult.intersects) {
_currentClickingOnOverlayID = rayPickResult.overlayID;
@ -901,7 +876,8 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) {
PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent");
PickRay ray = qApp->computePickRay(event->x(), event->y());
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray);
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(),
QVector<OverlayID>());
if (rayPickResult.intersects) {
_currentClickingOnOverlayID = rayPickResult.overlayID;
@ -964,7 +940,8 @@ bool Overlays::mouseReleaseEvent(QMouseEvent* event) {
PerformanceTimer perfTimer("Overlays::mouseReleaseEvent");
PickRay ray = qApp->computePickRay(event->x(), event->y());
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray);
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(),
QVector<OverlayID>());
if (rayPickResult.intersects) {
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release);
mouseReleasePointerEvent(rayPickResult.overlayID, pointerEvent);
@ -993,7 +970,8 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) {
PerformanceTimer perfTimer("Overlays::mouseMoveEvent");
PickRay ray = qApp->computePickRay(event->x(), event->y());
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray);
RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector<OverlayID>(),
QVector<OverlayID>());
if (rayPickResult.intersects) {
auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move);
mouseMovePointerEvent(rayPickResult.overlayID, pointerEvent);

View file

@ -44,8 +44,7 @@ void OverlayPropertyResultFromScriptValue(const QScriptValue& object, OverlayPro
const OverlayID UNKNOWN_OVERLAY_ID = OverlayID();
/**jsdoc
* The result of a {@link PickRay} search using {@link Overlays.findRayIntersection|findRayIntersection} or
* {@link Overlays.findRayIntersectionVector|findRayIntersectionVector}.
* The result of a {@link PickRay} search using {@link Overlays.findRayIntersection|findRayIntersection}.
* @typedef {object} Overlays.RayToOverlayIntersectionResult
* @property {boolean} intersects - <code>true</code> if the {@link PickRay} intersected with a 3D overlay, otherwise
* <code>false</code>.
@ -383,7 +382,11 @@ public slots:
OverlayPropertyResult getOverlaysProperties(const QVariant& overlaysProperties);
/**jsdoc
* Find the closest 3D overlay intersected by a {@link PickRay}.
* Find the closest 3D overlay intersected by a {@link PickRay}. Overlays with their <code>drawInFront</code> property set
* to <code>true</code> have priority over overlays that don't, except that tablet overlays have priority over any
* <code>drawInFront</code> overlays behind them. I.e., if a <code>drawInFront</code> overlay is behind one that isn't
* <code>drawInFront</code>, the <code>drawInFront</code> overlay is returned, but if a tablet overlay is in front of a
* <code>drawInFront</code> overlay, the tablet overlay is returned.
* @function Overlays.findRayIntersection
* @param {PickRay} pickRay - The PickRay to use for finding overlays.
* @param {boolean} [precisionPicking=false] - <em>Unused</em>; exists to match Entity API.
@ -750,8 +753,6 @@ private:
OverlayID _currentClickingOnOverlayID { UNKNOWN_OVERLAY_ID };
OverlayID _currentHoverOverOverlayID { UNKNOWN_OVERLAY_ID };
RayToOverlayIntersectionResult findRayIntersectionForMouseEvent(PickRay ray);
private slots:
void mousePressPointerEvent(const OverlayID& overlayID, const PointerEvent& event);
void mouseMovePointerEvent(const OverlayID& overlayID, const PointerEvent& event);

View file

@ -64,7 +64,7 @@ void Planar3DOverlay::setProperties(const QVariantMap& properties) {
*/
QVariant Planar3DOverlay::getProperty(const QString& property) {
if (property == "dimensions" || property == "scale" || property == "size") {
return vec2toVariant(getDimensions());
return vec2ToVariant(getDimensions());
}
return Base3DOverlay::getProperty(property);

View file

@ -51,9 +51,8 @@ void Rectangle3DOverlay::render(RenderArgs* args) {
}
float alpha = getAlpha();
xColor color = getColor();
const float MAX_COLOR = 255.0f;
glm::vec4 rectangleColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
glm::u8vec3 color = getColor();
glm::vec4 rectangleColor(toGlm(color), alpha);
auto batch = args->_batch;
if (batch) {

View file

@ -30,9 +30,8 @@ void Shape3DOverlay::render(RenderArgs* args) {
}
float alpha = getAlpha();
xColor color = getColor();
const float MAX_COLOR = 255.0f;
glm::vec4 cubeColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
glm::u8vec3 color = getColor();
glm::vec4 shapeColor(toGlm(color), alpha);
auto batch = args->_batch;
if (batch) {
@ -44,9 +43,9 @@ void Shape3DOverlay::render(RenderArgs* args) {
batch->setModelTransform(getRenderTransform());
if (_isSolid) {
geometryCache->renderSolidShapeInstance(args, *batch, _shape, cubeColor, shapePipeline);
geometryCache->renderSolidShapeInstance(args, *batch, _shape, shapeColor, shapePipeline);
} else {
geometryCache->renderWireShapeInstance(args, *batch, _shape, cubeColor, shapePipeline);
geometryCache->renderWireShapeInstance(args, *batch, _shape, shapeColor, shapePipeline);
}
}
}

View file

@ -77,9 +77,8 @@ void Sphere3DOverlay::render(RenderArgs* args) {
}
float alpha = getAlpha();
xColor color = getColor();
const float MAX_COLOR = 255.0f;
glm::vec4 sphereColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
glm::u8vec3 color = getColor();
glm::vec4 sphereColor(toGlm(color), alpha);
auto batch = args->_batch;

View file

@ -64,21 +64,21 @@ void Text3DOverlay::setText(const QString& text) {
_text = text;
}
xColor Text3DOverlay::getBackgroundColor() {
glm::u8vec3 Text3DOverlay::getBackgroundColor() {
if (_colorPulse == 0.0f) {
return _backgroundColor;
}
float pulseLevel = updatePulse();
xColor result = _backgroundColor;
glm::u8vec3 result = _backgroundColor;
if (_colorPulse < 0.0f) {
result.red *= (1.0f - pulseLevel);
result.green *= (1.0f - pulseLevel);
result.blue *= (1.0f - pulseLevel);
result.x *= (1.0f - pulseLevel);
result.y *= (1.0f - pulseLevel);
result.z *= (1.0f - pulseLevel);
} else {
result.red *= pulseLevel;
result.green *= pulseLevel;
result.blue *= pulseLevel;
result.x *= pulseLevel;
result.y *= pulseLevel;
result.z *= pulseLevel;
}
return result;
}
@ -94,10 +94,8 @@ void Text3DOverlay::render(RenderArgs* args) {
auto transform = getRenderTransform();
batch.setModelTransform(transform);
const float MAX_COLOR = 255.0f;
xColor backgroundColor = getBackgroundColor();
glm::vec4 quadColor(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR,
backgroundColor.blue / MAX_COLOR, getBackgroundAlpha());
glm::u8vec3 backgroundColor = getBackgroundColor();
glm::vec4 quadColor(toGlm(backgroundColor), getBackgroundAlpha());
glm::vec2 dimensions = getDimensions();
glm::vec2 halfDimensions = dimensions * 0.5f;
@ -122,8 +120,7 @@ void Text3DOverlay::render(RenderArgs* args) {
transform.setScale(scaleFactor);
batch.setModelTransform(transform);
glm::vec4 textColor = { _color.red / MAX_COLOR, _color.green / MAX_COLOR,
_color.blue / MAX_COLOR, getTextAlpha() };
glm::vec4 textColor = { toGlm(_color), getTextAlpha() };
// FIXME: Factor out textRenderer so that Text3DOverlay overlay parts can be grouped by pipeline for a gpu performance increase.
_textRenderer->draw(batch, 0, 0, getText(), textColor, glm::vec2(-1.0f), true);
@ -164,7 +161,7 @@ void Text3DOverlay::setProperties(const QVariantMap& properties) {
bool valid;
auto backgroundColor = properties["backgroundColor"];
if (backgroundColor.isValid()) {
auto color = xColorFromVariant(backgroundColor, valid);
auto color = u8vec3FromVariant(backgroundColor, valid);
if (valid) {
_backgroundColor = color;
}
@ -260,7 +257,7 @@ QVariant Text3DOverlay::getProperty(const QString& property) {
return _textAlpha;
}
if (property == "backgroundColor") {
return xColorToVariant(_backgroundColor);
return u8vec3ColortoVariant(_backgroundColor);
}
if (property == "backgroundAlpha") {
return Billboard3DOverlay::getProperty("alpha");

View file

@ -39,7 +39,7 @@ public:
float getTopMargin() const { return _topMargin; }
float getRightMargin() const { return _rightMargin; }
float getBottomMargin() const { return _bottomMargin; }
xColor getBackgroundColor();
glm::u8vec3 getBackgroundColor();
float getTextAlpha() { return _textAlpha; }
float getBackgroundAlpha() { return getAlpha(); }
bool isTransparent() override { return Overlay::isTransparent() || _textAlpha < 1.0f; }
@ -65,7 +65,7 @@ private:
QString _text;
mutable QMutex _mutex; // used to make get/setText threadsafe, mutable so can be used in const functions
xColor _backgroundColor = xColor { 0, 0, 0 };
glm::u8vec3 _backgroundColor { 0, 0, 0 };
float _textAlpha { 1.0f };
float _lineHeight { 1.0f };
float _leftMargin { 0.1f };

View file

@ -40,7 +40,7 @@ QScriptValue AnimVariantMap::animVariantMapToScriptValue(QScriptEngine* engine,
target.setProperty(name, value.getString());
break;
case AnimVariant::Type::Vec3:
target.setProperty(name, vec3toScriptValue(engine, value.getVec3()));
target.setProperty(name, vec3ToScriptValue(engine, value.getVec3()));
break;
case AnimVariant::Type::Quat:
target.setProperty(name, quatToScriptValue(engine, value.getQuat()));
@ -169,7 +169,8 @@ std::map<QString, QString> AnimVariantMap::toDebugMap() const {
break;
*/
default:
assert(("invalid AnimVariant::Type", false));
// invalid AnimVariant::Type
assert(false);
}
}
return result;

View file

@ -32,12 +32,6 @@ AnimationCache::AnimationCache(QObject* parent) :
}
AnimationPointer AnimationCache::getAnimation(const QUrl& url) {
if (QThread::currentThread() != thread()) {
AnimationPointer result;
BLOCKING_INVOKE_METHOD(this, "getAnimation",
Q_RETURN_ARG(AnimationPointer, result), Q_ARG(const QUrl&, url));
return result;
}
return getResource(url).staticCast<Animation>();
}

View file

@ -22,7 +22,7 @@
class Animation;
typedef QSharedPointer<Animation> AnimationPointer;
using AnimationPointer = QSharedPointer<Animation>;
class AnimationCache : public ResourceCache, public Dependency {
Q_OBJECT

View file

@ -1345,7 +1345,6 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab
const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix) {
const bool ENABLE_POLE_VECTORS = true;
const float ELBOW_POLE_VECTOR_BLEND_FACTOR = 0.95f;
if (leftHandEnabled) {
@ -1371,33 +1370,16 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab
bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector);
if (usePoleVector) {
glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector);
if (_smoothPoleVectors) {
// smooth toward desired pole vector from previous pole vector... to reduce jitter
if (!_prevLeftHandPoleVectorValid) {
_prevLeftHandPoleVectorValid = true;
_prevLeftHandPoleVector = sensorPoleVector;
}
glm::quat deltaRot = rotationBetween(_prevLeftHandPoleVector, sensorPoleVector);
glm::quat smoothDeltaRot = safeMix(deltaRot, Quaternions::IDENTITY, ELBOW_POLE_VECTOR_BLEND_FACTOR);
_prevLeftHandPoleVector = smoothDeltaRot * _prevLeftHandPoleVector;
} else {
_prevLeftHandPoleVector = sensorPoleVector;
}
_animVars.set("leftHandPoleVectorEnabled", true);
_animVars.set("leftHandPoleReferenceVector", Vectors::UNIT_X);
_animVars.set("leftHandPoleVector", transformVectorFast(sensorToRigMatrix, _prevLeftHandPoleVector));
_animVars.set("leftHandPoleVector", transformVectorFast(sensorToRigMatrix, sensorPoleVector));
} else {
_prevLeftHandPoleVectorValid = false;
_animVars.set("leftHandPoleVectorEnabled", false);
}
} else {
_prevLeftHandPoleVectorValid = false;
_animVars.set("leftHandPoleVectorEnabled", false);
}
} else {
_prevLeftHandPoleVectorValid = false;
_animVars.set("leftHandPoleVectorEnabled", false);
_animVars.unset("leftHandPosition");
@ -1436,33 +1418,16 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab
bool usePoleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, oppositeArmJointIndex, poleVector);
if (usePoleVector) {
glm::vec3 sensorPoleVector = transformVectorFast(rigToSensorMatrix, poleVector);
if (_smoothPoleVectors) {
// smooth toward desired pole vector from previous pole vector... to reduce jitter
if (!_prevRightHandPoleVectorValid) {
_prevRightHandPoleVectorValid = true;
_prevRightHandPoleVector = sensorPoleVector;
}
glm::quat deltaRot = rotationBetween(_prevRightHandPoleVector, sensorPoleVector);
glm::quat smoothDeltaRot = safeMix(deltaRot, Quaternions::IDENTITY, ELBOW_POLE_VECTOR_BLEND_FACTOR);
_prevRightHandPoleVector = smoothDeltaRot * _prevRightHandPoleVector;
} else {
_prevRightHandPoleVector = sensorPoleVector;
}
_animVars.set("rightHandPoleVectorEnabled", true);
_animVars.set("rightHandPoleReferenceVector", -Vectors::UNIT_X);
_animVars.set("rightHandPoleVector", transformVectorFast(sensorToRigMatrix, _prevRightHandPoleVector));
_animVars.set("rightHandPoleVector", transformVectorFast(sensorToRigMatrix, sensorPoleVector));
} else {
_prevRightHandPoleVectorValid = false;
_animVars.set("rightHandPoleVectorEnabled", false);
}
} else {
_prevRightHandPoleVectorValid = false;
_animVars.set("rightHandPoleVectorEnabled", false);
}
} else {
_prevRightHandPoleVectorValid = false;
_animVars.set("rightHandPoleVectorEnabled", false);
_animVars.unset("rightHandPosition");

View file

@ -230,7 +230,6 @@ public:
const AnimVariantMap& getAnimVars() const { return _lastAnimVars; }
const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); }
void toggleSmoothPoleVectors() { _smoothPoleVectors = !_smoothPoleVectors; };
signals:
void onLoadComplete();
@ -408,14 +407,6 @@ protected:
glm::vec3 _prevLeftFootPoleVector { Vectors::UNIT_Z }; // sensor space
bool _prevLeftFootPoleVectorValid { false };
glm::vec3 _prevRightHandPoleVector{ -Vectors::UNIT_Z }; // sensor space
bool _prevRightHandPoleVectorValid{ false };
glm::vec3 _prevLeftHandPoleVector{ -Vectors::UNIT_Z }; // sensor space
bool _prevLeftHandPoleVectorValid{ false };
bool _smoothPoleVectors { false };
int _rigId;
bool _headEnabled { false };
bool _sendNetworkNode { false };

View file

@ -34,7 +34,7 @@ AudioInjectorOptions::AudioInjectorOptions() :
QScriptValue injectorOptionsToScriptValue(QScriptEngine* engine, const AudioInjectorOptions& injectorOptions) {
QScriptValue obj = engine->newObject();
obj.setProperty("position", vec3toScriptValue(engine, injectorOptions.position));
obj.setProperty("position", vec3ToScriptValue(engine, injectorOptions.position));
obj.setProperty("volume", injectorOptions.volume);
obj.setProperty("loop", injectorOptions.loop);
obj.setProperty("orientation", quatToScriptValue(engine, injectorOptions.orientation));

View file

@ -30,12 +30,6 @@ SoundCache::SoundCache(QObject* parent) :
}
SharedSoundPointer SoundCache::getSound(const QUrl& url) {
if (QThread::currentThread() != thread()) {
SharedSoundPointer result;
BLOCKING_INVOKE_METHOD(this, "getSound",
Q_RETURN_ARG(SharedSoundPointer, result), Q_ARG(const QUrl&, url));
return result;
}
return getResource(url).staticCast<Sound>();
}

View file

@ -707,6 +707,19 @@ static TextRenderer3D* textRenderer(TextRendererType type) {
return displayNameRenderer;
}
void Avatar::metaBlendshapeOperator(int blendshapeNumber, const QVector<BlendshapeOffset>& blendshapeOffsets, const QVector<int>& blendedMeshSizes,
const render::ItemIDs& subItemIDs) {
render::Transaction transaction;
transaction.updateItem<AvatarData>(_renderItemID, [blendshapeNumber, blendshapeOffsets, blendedMeshSizes,
subItemIDs](AvatarData& avatar) {
auto avatarPtr = dynamic_cast<Avatar*>(&avatar);
if (avatarPtr) {
avatarPtr->setBlendedVertices(blendshapeNumber, blendshapeOffsets, blendedMeshSizes, subItemIDs);
}
});
AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction);
}
void Avatar::addToScene(AvatarSharedPointer self, const render::ScenePointer& scene, render::Transaction& transaction) {
auto avatarPayload = new render::Payload<AvatarData>(self);
auto avatarPayloadPointer = std::shared_ptr<render::Payload<AvatarData>>(avatarPayload);
@ -716,7 +729,8 @@ void Avatar::addToScene(AvatarSharedPointer self, const render::ScenePointer& sc
// INitialize the _render bound as we are creating the avatar render item
_renderBound = getBounds();
transaction.resetItem(_renderItemID, avatarPayloadPointer);
_skeletonModel->addToScene(scene, transaction);
using namespace std::placeholders;
_skeletonModel->addToScene(scene, transaction, std::bind(&Avatar::metaBlendshapeOperator, this, _1, _2, _3, _4));
_skeletonModel->setTagMask(render::hifi::TAG_ALL_VIEWS);
_skeletonModel->setGroupCulled(true);
_skeletonModel->setCanCastShadow(true);
@ -795,7 +809,7 @@ void Avatar::updateRenderItem(render::Transaction& transaction) {
avatarPtr->_renderBound = renderBound;
}
}
);
);
}
}
@ -939,7 +953,8 @@ void Avatar::fixupModelsInScene(const render::ScenePointer& scene) {
render::Transaction transaction;
if (_skeletonModel->isRenderable() && _skeletonModel->needsFixupInScene()) {
_skeletonModel->removeFromScene(scene, transaction);
_skeletonModel->addToScene(scene, transaction);
using namespace std::placeholders;
_skeletonModel->addToScene(scene, transaction, std::bind(&Avatar::metaBlendshapeOperator, this, _1, _2, _3, _4));
_skeletonModel->setTagMask(render::hifi::TAG_ALL_VIEWS);
_skeletonModel->setGroupCulled(true);

View file

@ -28,6 +28,8 @@
#include "Rig.h"
#include <ThreadSafeValueCache.h>
#include "MetaModelPayload.h"
namespace render {
template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar);
template <> const Item::Bound payloadGetBound(const AvatarSharedPointer& avatar);
@ -115,7 +117,7 @@ private:
float _scale { 1.0f };
};
class Avatar : public AvatarData, public scriptable::ModelProvider {
class Avatar : public AvatarData, public scriptable::ModelProvider, public MetaModelPayload {
Q_OBJECT
// This property has JSDoc in MyAvatar.h.
@ -623,6 +625,9 @@ protected:
static const float ATTACHMENT_LOADING_PRIORITY;
LoadingStatus _loadingStatus { LoadingStatus::NoModel };
void metaBlendshapeOperator(int blendshapeNumber, const QVector<BlendshapeOffset>& blendshapeOffsets, const QVector<int>& blendedMeshSizes,
const render::ItemIDs& subItemIDs);
};
#endif // hifi_Avatar_h

View file

@ -75,8 +75,11 @@ size_t AvatarDataPacket::maxJointDataSize(size_t numJoints, bool hasGrabJoints)
totalSize += numJoints * sizeof(SixByteTrans); // Translations
size_t NUM_FAUX_JOINT = 2;
size_t num_grab_joints = (hasGrabJoints ? 2 : 0);
totalSize += (NUM_FAUX_JOINT + num_grab_joints) * (sizeof(SixByteQuat) + sizeof(SixByteTrans)); // faux joints
totalSize += NUM_FAUX_JOINT * (sizeof(SixByteQuat) + sizeof(SixByteTrans)); // faux joints
if (hasGrabJoints) {
totalSize += sizeof(AvatarDataPacket::FarGrabJoints);
}
return totalSize;
}
@ -685,7 +688,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
if (hasGrabJoints) {
// the far-grab joints may range further than 3 meters, so we can't use packFloatVec3ToSignedTwoByteFixed etc
auto startSection = destinationBuffer;
auto data = reinterpret_cast<AvatarDataPacket::FarGrabJoints*>(destinationBuffer);
glm::vec3 leftFarGrabPosition = extractTranslation(leftFarGrabMatrix);
glm::quat leftFarGrabRotation = extractRotation(leftFarGrabMatrix);
glm::vec3 rightFarGrabPosition = extractTranslation(rightFarGrabMatrix);
@ -693,28 +696,17 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
glm::vec3 mouseFarGrabPosition = extractTranslation(mouseFarGrabMatrix);
glm::quat mouseFarGrabRotation = extractRotation(mouseFarGrabMatrix);
AVATAR_MEMCPY(leftFarGrabPosition);
// Can't do block copy as struct order is x, y, z, w.
data->leftFarGrabRotation[0] = leftFarGrabRotation.w;
data->leftFarGrabRotation[1] = leftFarGrabRotation.x;
data->leftFarGrabRotation[2] = leftFarGrabRotation.y;
data->leftFarGrabRotation[3] = leftFarGrabRotation.z;
destinationBuffer += sizeof(data->leftFarGrabPosition);
AVATAR_MEMCPY(rightFarGrabPosition);
data->rightFarGrabRotation[0] = rightFarGrabRotation.w;
data->rightFarGrabRotation[1] = rightFarGrabRotation.x;
data->rightFarGrabRotation[2] = rightFarGrabRotation.y;
data->rightFarGrabRotation[3] = rightFarGrabRotation.z;
destinationBuffer += sizeof(data->rightFarGrabRotation);
AVATAR_MEMCPY(mouseFarGrabPosition);
data->mouseFarGrabRotation[0] = mouseFarGrabRotation.w;
data->mouseFarGrabRotation[1] = mouseFarGrabRotation.x;
data->mouseFarGrabRotation[2] = mouseFarGrabRotation.y;
data->mouseFarGrabRotation[3] = mouseFarGrabRotation.z;
destinationBuffer += sizeof(data->mouseFarGrabRotation);
AvatarDataPacket::FarGrabJoints farGrabJoints = {
{ leftFarGrabPosition.x, leftFarGrabPosition.y, leftFarGrabPosition.z },
{ leftFarGrabRotation.w, leftFarGrabRotation.x, leftFarGrabRotation.y, leftFarGrabRotation.z },
{ rightFarGrabPosition.x, rightFarGrabPosition.y, rightFarGrabPosition.z },
{ rightFarGrabRotation.w, rightFarGrabRotation.x, rightFarGrabRotation.y, rightFarGrabRotation.z },
{ mouseFarGrabPosition.x, mouseFarGrabPosition.y, mouseFarGrabPosition.z },
{ mouseFarGrabRotation.w, mouseFarGrabRotation.x, mouseFarGrabRotation.y, mouseFarGrabRotation.z }
};
memcpy(destinationBuffer, &farGrabJoints, sizeof(farGrabJoints));
destinationBuffer += sizeof(AvatarDataPacket::FarGrabJoints);
int numBytes = destinationBuffer - startSection;
if (outboundDataRateOut) {
@ -1247,25 +1239,37 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
auto startSection = sourceBuffer;
PACKET_READ_CHECK(FarGrabJoints, sizeof(AvatarDataPacket::FarGrabJoints));
auto data = reinterpret_cast<const AvatarDataPacket::FarGrabJoints*>(sourceBuffer);
glm::vec3 leftFarGrabPosition = glm::vec3(data->leftFarGrabPosition[0], data->leftFarGrabPosition[1],
data->leftFarGrabPosition[2]);
glm::quat leftFarGrabRotation = glm::quat(data->leftFarGrabRotation[0], data->leftFarGrabRotation[1],
data->leftFarGrabRotation[2], data->leftFarGrabRotation[3]);
glm::vec3 rightFarGrabPosition = glm::vec3(data->rightFarGrabPosition[0], data->rightFarGrabPosition[1],
data->rightFarGrabPosition[2]);
glm::quat rightFarGrabRotation = glm::quat(data->rightFarGrabRotation[0], data->rightFarGrabRotation[1],
data->rightFarGrabRotation[2], data->rightFarGrabRotation[3]);
glm::vec3 mouseFarGrabPosition = glm::vec3(data->mouseFarGrabPosition[0], data->mouseFarGrabPosition[1],
data->mouseFarGrabPosition[2]);
glm::quat mouseFarGrabRotation = glm::quat(data->mouseFarGrabRotation[0], data->mouseFarGrabRotation[1],
data->mouseFarGrabRotation[2], data->mouseFarGrabRotation[3]);
AvatarDataPacket::FarGrabJoints farGrabJoints;
memcpy(&farGrabJoints, sourceBuffer, sizeof(farGrabJoints)); // to avoid misaligned floats
glm::vec3 leftFarGrabPosition = glm::vec3(farGrabJoints.leftFarGrabPosition[0],
farGrabJoints.leftFarGrabPosition[1],
farGrabJoints.leftFarGrabPosition[2]);
glm::quat leftFarGrabRotation = glm::quat(farGrabJoints.leftFarGrabRotation[0],
farGrabJoints.leftFarGrabRotation[1],
farGrabJoints.leftFarGrabRotation[2],
farGrabJoints.leftFarGrabRotation[3]);
glm::vec3 rightFarGrabPosition = glm::vec3(farGrabJoints.rightFarGrabPosition[0],
farGrabJoints.rightFarGrabPosition[1],
farGrabJoints.rightFarGrabPosition[2]);
glm::quat rightFarGrabRotation = glm::quat(farGrabJoints.rightFarGrabRotation[0],
farGrabJoints.rightFarGrabRotation[1],
farGrabJoints.rightFarGrabRotation[2],
farGrabJoints.rightFarGrabRotation[3]);
glm::vec3 mouseFarGrabPosition = glm::vec3(farGrabJoints.mouseFarGrabPosition[0],
farGrabJoints.mouseFarGrabPosition[1],
farGrabJoints.mouseFarGrabPosition[2]);
glm::quat mouseFarGrabRotation = glm::quat(farGrabJoints.mouseFarGrabRotation[0],
farGrabJoints.mouseFarGrabRotation[1],
farGrabJoints.mouseFarGrabRotation[2],
farGrabJoints.mouseFarGrabRotation[3]);
_farGrabLeftMatrixCache.set(createMatFromQuatAndPos(leftFarGrabRotation, leftFarGrabPosition));
_farGrabRightMatrixCache.set(createMatFromQuatAndPos(rightFarGrabRotation, rightFarGrabPosition));
_farGrabMouseMatrixCache.set(createMatFromQuatAndPos(mouseFarGrabRotation, mouseFarGrabPosition));
sourceBuffer += sizeof(AvatarDataPacket::AvatarGlobalPosition);
sourceBuffer += sizeof(AvatarDataPacket::FarGrabJoints);
int numBytesRead = sourceBuffer - startSection;
_farGrabJointRate.increment(numBytesRead);
_farGrabJointUpdateRate.increment();
@ -2821,10 +2825,10 @@ QScriptValue RayToAvatarIntersectionResultToScriptValue(QScriptEngine* engine, c
obj.setProperty("avatarID", avatarIDValue);
obj.setProperty("distance", value.distance);
obj.setProperty("face", boxFaceToString(value.face));
QScriptValue intersection = vec3ToScriptValue(engine, value.intersection);
QScriptValue intersection = vec3toScriptValue(engine, value.intersection);
obj.setProperty("intersection", intersection);
QScriptValue surfaceNormal = vec3toScriptValue(engine, value.surfaceNormal);
QScriptValue surfaceNormal = vec3ToScriptValue(engine, value.surfaceNormal);
obj.setProperty("surfaceNormal", surfaceNormal);
obj.setProperty("extraInfo", engine->toScriptValue(value.extraInfo));
return obj;

View file

@ -258,7 +258,6 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer<ReceivedMessag
if (isNewAvatar) {
QWriteLocker locker(&_hashLock);
_pendingAvatars.insert(sessionUUID, { std::chrono::steady_clock::now(), 0, avatar });
avatar->setIsNewAvatar(true);
auto replicaIDs = _replicas.getReplicaIDs(sessionUUID);
for (auto replicaID : replicaIDs) {
@ -300,7 +299,6 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage>
{
QReadLocker locker(&_hashLock);
_pendingAvatars.remove(identityUUID);
auto me = _avatarHash.find(EMPTY);
if ((me != _avatarHash.end()) && (identityUUID == me.value()->getSessionUUID())) {
// We add MyAvatar to _avatarHash with an empty UUID. Code relies on this. In order to correctly handle an
@ -419,7 +417,6 @@ void AvatarHashMap::removeAvatar(const QUuid& sessionUUID, KillAvatarReason remo
}
}
_pendingAvatars.remove(sessionUUID);
auto removedAvatar = _avatarHash.take(sessionUUID);
if (removedAvatar) {

View file

@ -161,6 +161,11 @@ protected slots:
*/
void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
/**jsdoc
* @function AvatarList.processBulkAvatarTraits
* @param {} message
* @param {} sendingNode
*/
void processBulkAvatarTraits(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
/**jsdoc
@ -183,15 +188,8 @@ protected:
virtual void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason);
AvatarHash _avatarHash;
struct PendingAvatar {
std::chrono::steady_clock::time_point creationTime;
int transmits;
AvatarSharedPointer avatar;
};
using AvatarPendingHash = QHash<QUuid, PendingAvatar>;
AvatarPendingHash _pendingAvatars;
mutable QReadWriteLock _hashLock;
AvatarHash _avatarHash;
std::unordered_map<QUuid, AvatarTraits::TraitVersions> _processedTraitVersions;
AvatarReplicas _replicas;

View file

@ -98,7 +98,7 @@ enum Hand {
class InputDevice {
public:
InputDevice(const QString& name) : _name(name) {}
virtual ~InputDevice() {}
virtual ~InputDevice() = default;
using Pointer = std::shared_ptr<InputDevice>;

View file

@ -41,10 +41,10 @@ namespace controller {
*/
QScriptValue Pose::toScriptValue(QScriptEngine* engine, const Pose& pose) {
QScriptValue obj = engine->newObject();
obj.setProperty("translation", vec3toScriptValue(engine, pose.translation));
obj.setProperty("translation", vec3ToScriptValue(engine, pose.translation));
obj.setProperty("rotation", quatToScriptValue(engine, pose.rotation));
obj.setProperty("velocity", vec3toScriptValue(engine, pose.velocity));
obj.setProperty("angularVelocity", vec3toScriptValue(engine, pose.angularVelocity));
obj.setProperty("velocity", vec3ToScriptValue(engine, pose.velocity));
obj.setProperty("angularVelocity", vec3ToScriptValue(engine, pose.angularVelocity));
obj.setProperty("valid", pose.valid);
return obj;
}

View file

@ -30,6 +30,8 @@ namespace controller {
using Factory = hifi::SimpleFactory<Conditional, QString>;
using Lambda = std::function<bool()>;
virtual ~Conditional() = default;
virtual bool satisfied() = 0;
virtual bool parseParameters(const QJsonValue& parameters) { return true; }

View file

@ -35,6 +35,8 @@ namespace controller {
using Lambda = std::function<float(float)>;
using Factory = hifi::SimpleFactory<Filter, QString>;
virtual ~Filter() = default;
virtual float apply(float value) const = 0;
virtual Pose apply(Pose value) const = 0;

View file

@ -24,8 +24,6 @@ public:
AndConditional(Conditional::Pointer& first, Conditional::Pointer& second)
: _children({ first, second }) {}
virtual ~AndConditional() {}
virtual bool satisfied() override;
private:

View file

@ -18,7 +18,6 @@ namespace controller {
class EndpointConditional : public Conditional {
public:
EndpointConditional(Endpoint::Pointer endpoint) : _endpoint(endpoint) {}
virtual ~EndpointConditional() {}
virtual bool satisfied() override { return _endpoint && _endpoint->peek() != 0.0f; }
private:
Endpoint::Pointer _endpoint;

View file

@ -19,7 +19,6 @@ namespace controller {
using Pointer = std::shared_ptr<NotConditional>;
NotConditional(Conditional::Pointer operand) : _operand(operand) { }
virtual ~NotConditional() {}
virtual bool satisfied() override;

View file

@ -18,7 +18,6 @@ class ClampFilter : public Filter {
REGISTER_FILTER_CLASS(ClampFilter);
public:
ClampFilter(float min = 0.0, float max = 1.0) : _min(min), _max(max) {};
virtual ~ClampFilter() {}
virtual float apply(float value) const override {
return glm::clamp(value, _min, _max);
}

View file

@ -17,16 +17,13 @@ namespace controller {
class ConstrainToIntegerFilter : public Filter {
REGISTER_FILTER_CLASS(ConstrainToIntegerFilter);
public:
ConstrainToIntegerFilter() {};
virtual ~ConstrainToIntegerFilter() {}
ConstrainToIntegerFilter() = default;
virtual float apply(float value) const override {
return glm::sign(value);
}
virtual Pose apply(Pose value) const override { return value; }
protected:
};
}

View file

@ -17,16 +17,13 @@ namespace controller {
class ConstrainToPositiveIntegerFilter : public Filter {
REGISTER_FILTER_CLASS(ConstrainToPositiveIntegerFilter);
public:
ConstrainToPositiveIntegerFilter() {};
virtual ~ConstrainToPositiveIntegerFilter() {};
ConstrainToPositiveIntegerFilter() = default;
virtual float apply(float value) const override {
return (value <= 0.0f) ? 0.0f : 1.0f;
}
virtual Pose apply(Pose value) const override { return value; }
protected:
};
}

View file

@ -18,7 +18,6 @@ class DeadZoneFilter : public Filter {
REGISTER_FILTER_CLASS(DeadZoneFilter);
public:
DeadZoneFilter(float min = 0.0) : _min(min) {};
virtual ~DeadZoneFilter() {}
virtual float apply(float value) const override;

View file

@ -20,7 +20,6 @@ namespace controller {
ExponentialSmoothingFilter() {}
ExponentialSmoothingFilter(float rotationConstant, float translationConstant) :
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
virtual ~ExponentialSmoothingFilter() {}
float apply(float value) const override { return value; }
Pose apply(Pose value) const override;

View file

@ -18,7 +18,6 @@ class HysteresisFilter : public Filter {
REGISTER_FILTER_CLASS(HysteresisFilter);
public:
HysteresisFilter(float min = 0.25, float max = 0.75);
virtual ~HysteresisFilter() {}
virtual float apply(float value) const override;
virtual Pose apply(Pose value) const override { return value; }

View file

@ -19,11 +19,8 @@ class InvertFilter : public ScaleFilter {
public:
using ScaleFilter::parseParameters;
InvertFilter() : ScaleFilter(-1.0f) {}
virtual ~InvertFilter() {}
virtual bool parseParameters(const QJsonArray& parameters) { return true; }
private:
};
}

View file

@ -17,10 +17,9 @@ namespace controller {
REGISTER_FILTER_CLASS(LowVelocityFilter);
public:
LowVelocityFilter() {}
LowVelocityFilter() = default;
LowVelocityFilter(float rotationConstant, float translationConstant) :
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
virtual ~LowVelocityFilter() {}
float apply(float value) const override { return value; }
Pose apply(Pose newPose) const override;

View file

@ -10,7 +10,6 @@ class NotFilter : public Filter {
REGISTER_FILTER_CLASS(NotFilter);
public:
NotFilter();
virtual ~NotFilter() {}
virtual float apply(float value) const override;
virtual Pose apply(Pose value) const override { return value; }

View file

@ -19,9 +19,8 @@ namespace controller {
class PostTransformFilter : public Filter {
REGISTER_FILTER_CLASS(PostTransformFilter);
public:
PostTransformFilter() { }
PostTransformFilter() = default;
PostTransformFilter(glm::mat4 transform) : _transform(transform) {}
virtual ~PostTransformFilter() {}
virtual float apply(float value) const override { return value; }
virtual Pose apply(Pose value) const override { return value.postTransform(_transform); }
virtual bool parseParameters(const QJsonValue& parameters) override { return parseMat4Parameter(parameters, _transform); }

View file

@ -18,9 +18,8 @@ namespace controller {
class PulseFilter : public Filter {
REGISTER_FILTER_CLASS(PulseFilter);
public:
PulseFilter() {}
PulseFilter() = default;
PulseFilter(float interval) : _interval(interval) {}
virtual ~PulseFilter() {}
virtual float apply(float value) const override;

View file

@ -19,9 +19,8 @@ namespace controller {
class RotateFilter : public Filter {
REGISTER_FILTER_CLASS(RotateFilter);
public:
RotateFilter() { }
RotateFilter() = default;
RotateFilter(glm::quat rotation) : _rotation(rotation) {}
virtual ~RotateFilter() {}
virtual float apply(float value) const override { return value; }

View file

@ -19,9 +19,8 @@ namespace controller {
class ScaleFilter : public Filter {
REGISTER_FILTER_CLASS(ScaleFilter);
public:
ScaleFilter() {}
ScaleFilter() = default;
ScaleFilter(float scale) : _scale(scale) {}
virtual ~ScaleFilter() {}
virtual float apply(float value) const override {
return value * _scale;

View file

@ -19,9 +19,8 @@ namespace controller {
class TransformFilter : public Filter {
REGISTER_FILTER_CLASS(TransformFilter);
public:
TransformFilter() { }
TransformFilter() = default;
TransformFilter(glm::mat4 transform) : _transform(transform) {}
virtual ~TransformFilter() {}
virtual float apply(float value) const override { return value; }
virtual Pose apply(Pose value) const override { return value.transform(_transform); }

Some files were not shown because too many files have changed in this diff Show more