From 2e5244663ebf7e1e1cb1ededd2f89d557cd81f06 Mon Sep 17 00:00:00 2001 From: Heather Anderson Date: Sun, 9 Aug 2020 14:57:00 -0700 Subject: [PATCH 001/127] transition listener registration from member string name to member string pointer --- assignment-client/src/Agent.cpp | 7 +- assignment-client/src/AssignmentClient.cpp | 6 +- .../src/AssignmentClientMonitor.cpp | 3 +- assignment-client/src/assets/AssetServer.cpp | 15 +- assignment-client/src/audio/AudioMixer.cpp | 17 +- assignment-client/src/avatars/AvatarMixer.cpp | 40 ++-- .../src/entities/EntityServer.cpp | 3 +- .../src/messages/MessagesMixer.cpp | 9 +- assignment-client/src/octree/OctreeServer.cpp | 6 +- .../src/scripts/EntityScriptServer.cpp | 17 +- domain-server/src/DomainGatekeeper.cpp | 3 +- domain-server/src/DomainServer.cpp | 57 ++++-- .../src/DomainServerSettingsManager.h | 2 + interface/src/commerce/Wallet.cpp | 6 +- .../src/octree/OctreePacketProcessor.cpp | 3 +- .../ScreenshareScriptingInterface.cpp | 3 +- interface/src/ui/DomainConnectionModel.cpp | 3 +- .../ui/overlays/ContextOverlayInterface.cpp | 3 +- libraries/audio-client/src/AudioClient.cpp | 21 +- libraries/avatars/src/AvatarHashMap.cpp | 12 +- libraries/avatars/src/ClientTraitsHandler.cpp | 3 +- .../entities/src/EntityEditPacketSender.cpp | 3 +- .../src/EntityScriptServerLogClient.cpp | 3 +- .../entities/src/EntityScriptingInterface.cpp | 3 +- libraries/networking/src/AssetClient.cpp | 12 +- .../networking/src/EntityScriptClient.cpp | 3 +- libraries/networking/src/MessagesClient.cpp | 3 +- libraries/networking/src/NodeList.cpp | 42 ++-- libraries/networking/src/PacketReceiver.cpp | 180 +++++------------- libraries/networking/src/PacketReceiver.h | 98 +++++++++- libraries/networking/src/ResourceCache.cpp | 5 +- libraries/octree/src/OctreePersistThread.cpp | 3 +- 32 files changed, 343 insertions(+), 251 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 59e53bb2cb..a8ce7e30e5 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -112,11 +112,12 @@ Agent::Agent(ReceivedMessage& message) : packetReceiver.registerListenerForTypes( { PacketType::MixedAudio, PacketType::SilentAudioFrame }, - this, "handleAudioPacket"); + PacketReceiver::makeUnsourcedListenerReference(this, &Agent::handleAudioPacket)); packetReceiver.registerListenerForTypes( { PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase }, - this, "handleOctreePacket"); - packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat"); + PacketReceiver::makeSourcedListenerReference(this, &Agent::handleOctreePacket)); + packetReceiver.registerListener(PacketType::SelectedAudioFormat, + PacketReceiver::makeUnsourcedListenerReference(this, &Agent::handleSelectedAudioFormat)); // 100Hz timer for audio const int TARGET_INTERVAL_MSEC = 10; // 10ms diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index ce724d7368..50eee258ab 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -118,8 +118,10 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri setUpStatusToMonitor(); } auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::CreateAssignment, this, "handleCreateAssignmentPacket"); - packetReceiver.registerListener(PacketType::StopNode, this, "handleStopNodePacket"); + packetReceiver.registerListener(PacketType::CreateAssignment, + PacketReceiver::makeUnsourcedListenerReference(this, &AssignmentClient::handleCreateAssignmentPacket)); + packetReceiver.registerListener(PacketType::StopNode, + PacketReceiver::makeUnsourcedListenerReference(this, &AssignmentClient::handleStopNodePacket)); } void AssignmentClient::stopAssignmentClient() { diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 4c7f71a7aa..68c0dfc9fd 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -72,7 +72,8 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen auto nodeList = DependencyManager::set(listenPort); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::AssignmentClientStatus, this, "handleChildStatusPacket"); + packetReceiver.registerListener(PacketType::AssignmentClientStatus, + PacketReceiver::makeUnsourcedListenerReference(this, &AssignmentClientMonitor::handleChildStatusPacket)); adjustOSResources(std::max(_numAssignmentClientForks, _maxAssignmentClientForks)); // use QProcess to fork off a process for each of the child assignment clients diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index b3344e3832..ffb6747fd7 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -308,7 +308,8 @@ AssetServer::AssetServer(ReceivedMessage& message) : // Queue all requests until the Asset Server is fully setup auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListenerForTypes({ PacketType::AssetGet, PacketType::AssetGetInfo, PacketType::AssetUpload, PacketType::AssetMappingOperation }, this, "queueRequests"); + packetReceiver.registerListenerForTypes({ PacketType::AssetGet, PacketType::AssetGetInfo, PacketType::AssetUpload, PacketType::AssetMappingOperation }, + PacketReceiver::makeSourcedListenerReference(this, &AssetServer::queueRequests)); #ifdef Q_OS_WIN updateConsumedCores(); @@ -464,10 +465,14 @@ void AssetServer::completeSetup() { qCDebug(asset_server) << "Overriding temporary queuing packet handler."; // We're fully setup, override the request queueing handler and replay all requests auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::AssetGet, this, "handleAssetGet"); - packetReceiver.registerListener(PacketType::AssetGetInfo, this, "handleAssetGetInfo"); - packetReceiver.registerListener(PacketType::AssetUpload, this, "handleAssetUpload"); - packetReceiver.registerListener(PacketType::AssetMappingOperation, this, "handleAssetMappingOperation"); + packetReceiver.registerListener(PacketType::AssetGet, + PacketReceiver::makeSourcedListenerReference(this, &AssetServer::handleAssetGet)); + packetReceiver.registerListener(PacketType::AssetGetInfo, + PacketReceiver::makeSourcedListenerReference(this, &AssetServer::handleAssetGetInfo)); + packetReceiver.registerListener(PacketType::AssetUpload, + PacketReceiver::makeSourcedListenerReference(this, &AssetServer::handleAssetUpload)); + packetReceiver.registerListener(PacketType::AssetMappingOperation, + PacketReceiver::makeSourcedListenerReference(this, &AssetServer::handleAssetMappingOperation)); replayRequests(); } diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 161a6f4285..42a269c544 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -101,20 +101,23 @@ AudioMixer::AudioMixer(ReceivedMessage& message) : PacketType::InjectorGainSet, PacketType::AudioSoloRequest, PacketType::StopInjector }, - this, "queueAudioPacket"); + PacketReceiver::makeSourcedListenerReference(this, &AudioMixer::queueAudioPacket) + ); // packets whose consequences are global should be processed on the main thread - packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); - packetReceiver.registerListener(PacketType::NodeMuteRequest, this, "handleNodeMuteRequestPacket"); - packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); + packetReceiver.registerListener(PacketType::MuteEnvironment, + PacketReceiver::makeSourcedListenerReference(this, &AudioMixer::handleMuteEnvironmentPacket)); + packetReceiver.registerListener(PacketType::NodeMuteRequest, + PacketReceiver::makeSourcedListenerReference(this, &AudioMixer::handleNodeMuteRequestPacket)); + packetReceiver.registerListener(PacketType::KillAvatar, + PacketReceiver::makeSourcedListenerReference(this, &AudioMixer::handleKillAvatarPacket)); packetReceiver.registerListenerForTypes({ PacketType::ReplicatedMicrophoneAudioNoEcho, PacketType::ReplicatedMicrophoneAudioWithEcho, PacketType::ReplicatedInjectAudio, - PacketType::ReplicatedSilentAudioFrame - }, - this, "queueReplicatedAudioPacket" + PacketType::ReplicatedSilentAudioFrame }, + PacketReceiver::makeUnsourcedListenerReference(this, &AudioMixer::queueReplicatedAudioPacket) ); connect(nodeList.data(), &NodeList::nodeKilled, this, &AudioMixer::handleNodeKilled); diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 807f54953e..27b7d0d302 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -71,26 +71,38 @@ AvatarMixer::AvatarMixer(ReceivedMessage& message) : connect(DependencyManager::get().data(), &NodeList::nodeKilled, this, &AvatarMixer::handleAvatarKilled); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::AvatarData, this, "queueIncomingPacket"); - packetReceiver.registerListener(PacketType::AdjustAvatarSorting, this, "handleAdjustAvatarSorting"); - packetReceiver.registerListener(PacketType::AvatarQuery, this, "handleAvatarQueryPacket"); - packetReceiver.registerListener(PacketType::AvatarIdentity, this, "handleAvatarIdentityPacket"); - packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); - packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket"); - packetReceiver.registerListener(PacketType::RadiusIgnoreRequest, this, "handleRadiusIgnoreRequestPacket"); - packetReceiver.registerListener(PacketType::RequestsDomainListData, this, "handleRequestsDomainListDataPacket"); - packetReceiver.registerListener(PacketType::SetAvatarTraits, this, "queueIncomingPacket"); - packetReceiver.registerListener(PacketType::BulkAvatarTraitsAck, this, "queueIncomingPacket"); + packetReceiver.registerListener(PacketType::AvatarData, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::queueIncomingPacket)); + packetReceiver.registerListener(PacketType::AdjustAvatarSorting, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleAdjustAvatarSorting)); + packetReceiver.registerListener(PacketType::AvatarQuery, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleAvatarQueryPacket)); + packetReceiver.registerListener(PacketType::AvatarIdentity, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleAvatarIdentityPacket)); + packetReceiver.registerListener(PacketType::KillAvatar, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleKillAvatarPacket)); + packetReceiver.registerListener(PacketType::NodeIgnoreRequest, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleNodeIgnoreRequestPacket)); + packetReceiver.registerListener(PacketType::RadiusIgnoreRequest, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleRadiusIgnoreRequestPacket)); + packetReceiver.registerListener(PacketType::RequestsDomainListData, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleRequestsDomainListDataPacket)); + packetReceiver.registerListener(PacketType::SetAvatarTraits, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::queueIncomingPacket)); + packetReceiver.registerListener(PacketType::BulkAvatarTraitsAck, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::queueIncomingPacket)); packetReceiver.registerListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase }, - this, "handleOctreePacket"); - packetReceiver.registerListener(PacketType::ChallengeOwnership, this, "queueIncomingPacket"); + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::handleOctreePacket)); + packetReceiver.registerListener(PacketType::ChallengeOwnership, + PacketReceiver::makeSourcedListenerReference(this, &AvatarMixer::queueIncomingPacket)); packetReceiver.registerListenerForTypes({ PacketType::ReplicatedAvatarIdentity, PacketType::ReplicatedKillAvatar - }, this, "handleReplicatedPacket"); + }, PacketReceiver::makeUnsourcedListenerReference(this, &AvatarMixer::handleReplicatedPacket)); - packetReceiver.registerListener(PacketType::ReplicatedBulkAvatarData, this, "handleReplicatedBulkAvatarPacket"); + packetReceiver.registerListener(PacketType::ReplicatedBulkAvatarData, + PacketReceiver::makeUnsourcedListenerReference(this, &AvatarMixer::handleReplicatedBulkAvatarPacket)); auto nodeList = DependencyManager::get(); connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &AvatarMixer::handlePacketVersionMismatch); diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 4c4fcbf2dd..e68f95bda0 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -59,8 +59,7 @@ EntityServer::EntityServer(ReceivedMessage& message) : PacketType::ChallengeOwnership, PacketType::ChallengeOwnershipRequest, PacketType::ChallengeOwnershipReply }, - this, - "handleEntityPacket"); + PacketReceiver::makeSourcedListenerReference(this, &EntityServer::handleEntityPacket)); connect(&_dynamicDomainVerificationTimer, &QTimer::timeout, this, &EntityServer::startDynamicDomainVerification); _dynamicDomainVerificationTimer.setSingleShot(true); diff --git a/assignment-client/src/messages/MessagesMixer.cpp b/assignment-client/src/messages/MessagesMixer.cpp index d2127835f9..bcf4881fcf 100644 --- a/assignment-client/src/messages/MessagesMixer.cpp +++ b/assignment-client/src/messages/MessagesMixer.cpp @@ -25,9 +25,12 @@ MessagesMixer::MessagesMixer(ReceivedMessage& message) : ThreadedAssignment(mess { connect(DependencyManager::get().data(), &NodeList::nodeKilled, this, &MessagesMixer::nodeKilled); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::MessagesData, this, "handleMessages"); - packetReceiver.registerListener(PacketType::MessagesSubscribe, this, "handleMessagesSubscribe"); - packetReceiver.registerListener(PacketType::MessagesUnsubscribe, this, "handleMessagesUnsubscribe"); + packetReceiver.registerListener(PacketType::MessagesData, + PacketReceiver::makeSourcedListenerReference(this, &MessagesMixer::handleMessages)); + packetReceiver.registerListener(PacketType::MessagesSubscribe, + PacketReceiver::makeSourcedListenerReference(this, &MessagesMixer::handleMessagesSubscribe)); + packetReceiver.registerListener(PacketType::MessagesUnsubscribe, + PacketReceiver::makeSourcedListenerReference(this, &MessagesMixer::handleMessagesUnsubscribe)); } void MessagesMixer::nodeKilled(SharedNodePointer killedNode) { diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 63520262cd..f72ab0ac05 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -1122,8 +1122,10 @@ void OctreeServer::run() { void OctreeServer::domainSettingsRequestComplete() { auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::OctreeDataNack, this, "handleOctreeDataNackPacket"); - packetReceiver.registerListener(getMyQueryMessageType(), this, "handleOctreeQueryPacket"); + packetReceiver.registerListener(PacketType::OctreeDataNack, + PacketReceiver::makeSourcedListenerReference(this, &OctreeServer::handleOctreeDataNackPacket)); + packetReceiver.registerListener(getMyQueryMessageType(), + PacketReceiver::makeSourcedListenerReference(this, &OctreeServer::handleOctreeQueryPacket)); qDebug(octree_server) << "Received domain settings"; diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 7c3d491470..065ab12abc 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -83,13 +83,18 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); packetReceiver.registerListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase }, - this, "handleOctreePacket"); - packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat"); + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptServer::handleOctreePacket)); + packetReceiver.registerListener(PacketType::SelectedAudioFormat, + PacketReceiver::makeUnsourcedListenerReference(this, &EntityScriptServer::handleSelectedAudioFormat)); - packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket"); - packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket"); - packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket"); - packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket"); + packetReceiver.registerListener(PacketType::ReloadEntityServerScript, + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptServer::handleReloadEntityServerScriptPacket)); + packetReceiver.registerListener(PacketType::EntityScriptGetStatus, + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptServer::handleEntityScriptGetStatusPacket)); + packetReceiver.registerListener(PacketType::EntityServerScriptLog, + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptServer::handleEntityServerScriptLogPacket)); + packetReceiver.registerListener(PacketType::EntityScriptCallMethod, + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptServer::handleEntityScriptCallMethodPacket)); static const int LOG_INTERVAL = MSECS_PER_SECOND / 10; auto timer = new QTimer(this); diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index ead4002334..ef37b80d1b 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -17,7 +17,8 @@ #include #include -#include +#include +#include #include #include diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 41b0e98ec5..455a425330 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -765,32 +765,51 @@ void DomainServer::setupNodeListAndAssignments() { // register as the packet receiver for the types we want PacketReceiver& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::RequestAssignment, this, "processRequestAssignmentPacket"); - packetReceiver.registerListener(PacketType::DomainListRequest, this, "processListRequestPacket"); - packetReceiver.registerListener(PacketType::DomainServerPathQuery, this, "processPathQueryPacket"); - packetReceiver.registerListener(PacketType::NodeJsonStats, this, "processNodeJSONStatsPacket"); - packetReceiver.registerListener(PacketType::DomainDisconnectRequest, this, "processNodeDisconnectRequestPacket"); - packetReceiver.registerListener(PacketType::AvatarZonePresence, this, "processAvatarZonePresencePacket"); + packetReceiver.registerListener(PacketType::RequestAssignment, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processRequestAssignmentPacket)); + packetReceiver.registerListener(PacketType::DomainListRequest, + PacketReceiver::makeSourcedListenerReference(this, &DomainServer::processListRequestPacket)); + packetReceiver.registerListener(PacketType::DomainServerPathQuery, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processPathQueryPacket)); + packetReceiver.registerListener(PacketType::NodeJsonStats, + PacketReceiver::makeSourcedListenerReference(this, &DomainServer::processNodeJSONStatsPacket)); + packetReceiver.registerListener(PacketType::DomainDisconnectRequest, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processNodeDisconnectRequestPacket)); + packetReceiver.registerListener(PacketType::AvatarZonePresence, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processAvatarZonePresencePacket)); // NodeList won't be available to the settings manager when it is created, so call registerListener here - packetReceiver.registerListener(PacketType::DomainSettingsRequest, &_settingsManager, "processSettingsRequestPacket"); - packetReceiver.registerListener(PacketType::NodeKickRequest, &_settingsManager, "processNodeKickRequestPacket"); - packetReceiver.registerListener(PacketType::UsernameFromIDRequest, &_settingsManager, "processUsernameFromIDRequestPacket"); + packetReceiver.registerListener(PacketType::DomainSettingsRequest, + PacketReceiver::makeUnsourcedListenerReference(&_settingsManager, &DomainServerSettingsManager::processSettingsRequestPacket)); + packetReceiver.registerListener(PacketType::NodeKickRequest, + PacketReceiver::makeSourcedListenerReference(&_settingsManager, &DomainServerSettingsManager::processNodeKickRequestPacket)); + packetReceiver.registerListener(PacketType::UsernameFromIDRequest, + PacketReceiver::makeSourcedListenerReference(&_settingsManager, &DomainServerSettingsManager::processUsernameFromIDRequestPacket)); // register the gatekeeper for the packets it needs to receive - packetReceiver.registerListener(PacketType::DomainConnectRequest, &_gatekeeper, "processConnectRequestPacket"); - packetReceiver.registerListener(PacketType::ICEPing, &_gatekeeper, "processICEPingPacket"); - packetReceiver.registerListener(PacketType::ICEPingReply, &_gatekeeper, "processICEPingReplyPacket"); - packetReceiver.registerListener(PacketType::ICEServerPeerInformation, &_gatekeeper, "processICEPeerInformationPacket"); + packetReceiver.registerListener(PacketType::DomainConnectRequest, + PacketReceiver::makeUnsourcedListenerReference(&_gatekeeper, &DomainGatekeeper::processConnectRequestPacket)); + packetReceiver.registerListener(PacketType::ICEPing, + PacketReceiver::makeUnsourcedListenerReference(&_gatekeeper, &DomainGatekeeper::processICEPingPacket)); + packetReceiver.registerListener(PacketType::ICEPingReply, + PacketReceiver::makeUnsourcedListenerReference(&_gatekeeper, &DomainGatekeeper::processICEPingReplyPacket)); + packetReceiver.registerListener(PacketType::ICEServerPeerInformation, + PacketReceiver::makeUnsourcedListenerReference(&_gatekeeper, &DomainGatekeeper::processICEPeerInformationPacket)); - packetReceiver.registerListener(PacketType::ICEServerHeartbeatDenied, this, "processICEServerHeartbeatDenialPacket"); - packetReceiver.registerListener(PacketType::ICEServerHeartbeatACK, this, "processICEServerHeartbeatACK"); + packetReceiver.registerListener(PacketType::ICEServerHeartbeatDenied, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processICEServerHeartbeatDenialPacket)); + packetReceiver.registerListener(PacketType::ICEServerHeartbeatACK, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processICEServerHeartbeatACK)); - packetReceiver.registerListener(PacketType::OctreeDataFileRequest, this, "processOctreeDataRequestMessage"); - packetReceiver.registerListener(PacketType::OctreeDataPersist, this, "processOctreeDataPersistMessage"); + packetReceiver.registerListener(PacketType::OctreeDataFileRequest, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processOctreeDataRequestMessage)); + packetReceiver.registerListener(PacketType::OctreeDataPersist, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::processOctreeDataPersistMessage)); - packetReceiver.registerListener(PacketType::OctreeFileReplacement, this, "handleOctreeFileReplacementRequest"); - packetReceiver.registerListener(PacketType::DomainContentReplacementFromUrl, this, "handleDomainContentReplacementFromURLRequest"); + packetReceiver.registerListener(PacketType::OctreeFileReplacement, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::handleOctreeFileReplacementRequest)); + packetReceiver.registerListener(PacketType::DomainContentReplacementFromUrl, + PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::handleDomainContentReplacementFromURLRequest)); // set a custom packetVersionMatch as the verify packet operator for the udt::Socket nodeList->setPacketFilterOperator(&DomainServer::isPacketVerified); diff --git a/domain-server/src/DomainServerSettingsManager.h b/domain-server/src/DomainServerSettingsManager.h index 294e441ba4..d0c7812a99 100644 --- a/domain-server/src/DomainServerSettingsManager.h +++ b/domain-server/src/DomainServerSettingsManager.h @@ -211,6 +211,8 @@ private: /// guard read/write access from multiple threads to settings QReadWriteLock _settingsLock { QReadWriteLock::Recursive }; + + friend class DomainServer; }; #endif // hifi_DomainServerSettingsManager_h diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index c449874117..95533b0fb9 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -288,8 +288,10 @@ Wallet::Wallet() { auto& packetReceiver = nodeList->getPacketReceiver(); _passphrase = new QString(""); - packetReceiver.registerListener(PacketType::ChallengeOwnership, this, "handleChallengeOwnershipPacket"); - packetReceiver.registerListener(PacketType::ChallengeOwnershipRequest, this, "handleChallengeOwnershipPacket"); + packetReceiver.registerListener(PacketType::ChallengeOwnership, + PacketReceiver::makeSourcedListenerReference(this, &Wallet::handleChallengeOwnershipPacket)); + packetReceiver.registerListener(PacketType::ChallengeOwnershipRequest, + PacketReceiver::makeSourcedListenerReference(this, &Wallet::handleChallengeOwnershipPacket)); connect(ledger.data(), &Ledger::accountResult, this, [](QJsonObject result) { auto wallet = DependencyManager::get(); diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index bc3c1afdd5..c2823e364f 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -25,7 +25,8 @@ OctreePacketProcessor::OctreePacketProcessor(): auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); const PacketReceiver::PacketTypeList octreePackets = { PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase, PacketType::EntityQueryInitialResultsComplete }; - packetReceiver.registerDirectListenerForTypes(octreePackets, this, "handleOctreePacket"); + packetReceiver.registerDirectListenerForTypes(octreePackets, + PacketReceiver::makeSourcedListenerReference(this, &OctreePacketProcessor::handleOctreePacket)); } OctreePacketProcessor::~OctreePacketProcessor() { } diff --git a/interface/src/scripting/ScreenshareScriptingInterface.cpp b/interface/src/scripting/ScreenshareScriptingInterface.cpp index 3bf8336fe4..54f3e195ee 100644 --- a/interface/src/scripting/ScreenshareScriptingInterface.cpp +++ b/interface/src/scripting/ScreenshareScriptingInterface.cpp @@ -42,7 +42,8 @@ ScreenshareScriptingInterface::ScreenshareScriptingInterface() { // This packet listener handles the packet containing information about the latest zone ID in which we are allowed to share. auto nodeList = DependencyManager::get(); PacketReceiver& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::AvatarZonePresence, this, "processAvatarZonePresencePacketOnClient"); + packetReceiver.registerListener(PacketType::AvatarZonePresence, + PacketReceiver::makeUnsourcedListenerReference(this, &ScreenshareScriptingInterface::processAvatarZonePresencePacketOnClient)); }; ScreenshareScriptingInterface::~ScreenshareScriptingInterface() { diff --git a/interface/src/ui/DomainConnectionModel.cpp b/interface/src/ui/DomainConnectionModel.cpp index 83aa18420c..596662a664 100644 --- a/interface/src/ui/DomainConnectionModel.cpp +++ b/interface/src/ui/DomainConnectionModel.cpp @@ -9,7 +9,8 @@ // #include "DomainConnectionModel.h" -#include +#include +#include #include #include diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 0f1c8978f0..807eed89ba 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -81,7 +81,8 @@ ContextOverlayInterface::ContextOverlayInterface() { auto nodeList = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::ChallengeOwnershipReply, this, "handleChallengeOwnershipReplyPacket"); + packetReceiver.registerListener(PacketType::ChallengeOwnershipReply, + PacketReceiver::makeSourcedListenerReference(this, &ContextOverlayInterface::handleChallengeOwnershipReplyPacket)); _challengeOwnershipTimeoutTimer.setSingleShot(true); } diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 4e8c88560b..5a255ffb82 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -369,13 +369,20 @@ AudioClient::AudioClient() { auto nodeList = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::AudioStreamStats, &_stats, "processStreamStatsPacket"); - packetReceiver.registerListener(PacketType::AudioEnvironment, this, "handleAudioEnvironmentDataPacket"); - packetReceiver.registerListener(PacketType::SilentAudioFrame, this, "handleAudioDataPacket"); - packetReceiver.registerListener(PacketType::MixedAudio, this, "handleAudioDataPacket"); - packetReceiver.registerListener(PacketType::NoisyMute, this, "handleNoisyMutePacket"); - packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); - packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat"); + packetReceiver.registerListener(PacketType::AudioStreamStats, + PacketReceiver::makeSourcedListenerReference(&_stats, &AudioIOStats::processStreamStatsPacket)); + packetReceiver.registerListener(PacketType::AudioEnvironment, + PacketReceiver::makeUnsourcedListenerReference(this, &AudioClient::handleAudioEnvironmentDataPacket)); + packetReceiver.registerListener(PacketType::SilentAudioFrame, + PacketReceiver::makeUnsourcedListenerReference(this, &AudioClient::handleAudioDataPacket)); + packetReceiver.registerListener(PacketType::MixedAudio, + PacketReceiver::makeUnsourcedListenerReference(this, &AudioClient::handleAudioDataPacket)); + packetReceiver.registerListener(PacketType::NoisyMute, + PacketReceiver::makeUnsourcedListenerReference(this, &AudioClient::handleNoisyMutePacket)); + packetReceiver.registerListener(PacketType::MuteEnvironment, + PacketReceiver::makeUnsourcedListenerReference(this, &AudioClient::handleMuteEnvironmentPacket)); + packetReceiver.registerListener(PacketType::SelectedAudioFormat, + PacketReceiver::makeUnsourcedListenerReference(this, &AudioClient::handleSelectedAudioFormat)); auto& domainHandler = nodeList->getDomainHandler(); connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this] { diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index d0b315b524..7ed93f346d 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -123,10 +123,14 @@ AvatarHashMap::AvatarHashMap() { auto nodeList = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket"); - packetReceiver.registerListener(PacketType::KillAvatar, this, "processKillAvatar"); - packetReceiver.registerListener(PacketType::AvatarIdentity, this, "processAvatarIdentityPacket"); - packetReceiver.registerListener(PacketType::BulkAvatarTraits, this, "processBulkAvatarTraits"); + packetReceiver.registerListener(PacketType::BulkAvatarData, + PacketReceiver::makeSourcedListenerReference(this, &AvatarHashMap::processAvatarDataPacket)); + packetReceiver.registerListener(PacketType::KillAvatar, + PacketReceiver::makeSourcedListenerReference(this, &AvatarHashMap::processKillAvatar)); + packetReceiver.registerListener(PacketType::AvatarIdentity, + PacketReceiver::makeSourcedListenerReference(this, &AvatarHashMap::processAvatarIdentityPacket)); + packetReceiver.registerListener(PacketType::BulkAvatarTraits, + PacketReceiver::makeSourcedListenerReference(this, &AvatarHashMap::processBulkAvatarTraits)); connect(nodeList.data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged); diff --git a/libraries/avatars/src/ClientTraitsHandler.cpp b/libraries/avatars/src/ClientTraitsHandler.cpp index e133f178df..c2576bea2e 100644 --- a/libraries/avatars/src/ClientTraitsHandler.cpp +++ b/libraries/avatars/src/ClientTraitsHandler.cpp @@ -28,7 +28,8 @@ ClientTraitsHandler::ClientTraitsHandler(AvatarData* owningAvatar) : } }); - nodeList->getPacketReceiver().registerListener(PacketType::SetAvatarTraits, this, "processTraitOverride"); + nodeList->getPacketReceiver().registerListener(PacketType::SetAvatarTraits, + PacketReceiver::makeSourcedListenerReference(this, &ClientTraitsHandler::processTraitOverride)); } void ClientTraitsHandler::markTraitUpdated(AvatarTraits::TraitType updatedTrait) { diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index aaaf7d645a..3da019ce06 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -26,7 +26,8 @@ EntityEditPacketSender::EntityEditPacketSender() { auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerDirectListener(PacketType::EntityEditNack, this, "processEntityEditNackPacket"); + packetReceiver.registerDirectListener(PacketType::EntityEditNack, + PacketReceiver::makeSourcedListenerReference(this, &EntityEditPacketSender::processEntityEditNackPacket)); } void EntityEditPacketSender::processEntityEditNackPacket(QSharedPointer message, SharedNodePointer sendingNode) { diff --git a/libraries/entities/src/EntityScriptServerLogClient.cpp b/libraries/entities/src/EntityScriptServerLogClient.cpp index 5853c9585e..5d7d4017cd 100644 --- a/libraries/entities/src/EntityScriptServerLogClient.cpp +++ b/libraries/entities/src/EntityScriptServerLogClient.cpp @@ -14,7 +14,8 @@ EntityScriptServerLogClient::EntityScriptServerLogClient() { auto nodeList = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket"); + packetReceiver.registerListener(PacketType::EntityServerScriptLog, + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptServerLogClient::handleEntityServerScriptLogPacket)); QObject::connect(nodeList.data(), &NodeList::nodeActivated, this, &EntityScriptServerLogClient::nodeActivated); QObject::connect(nodeList.data(), &NodeList::nodeKilled, this, &EntityScriptServerLogClient::nodeKilled); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index fd83c99ca5..05947551ba 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -59,7 +59,8 @@ EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership connect(nodeList.data(), &NodeList::canGetAndSetPrivateUserDataChanged, this, &EntityScriptingInterface::canGetAndSetPrivateUserDataChanged); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket"); + packetReceiver.registerListener(PacketType::EntityScriptCallMethod, + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptingInterface::handleEntityScriptCallMethodPacket)); } void EntityScriptingInterface::queueEntityMessage(PacketType packetType, diff --git a/libraries/networking/src/AssetClient.cpp b/libraries/networking/src/AssetClient.cpp index 44f42caec2..bbd743cf95 100644 --- a/libraries/networking/src/AssetClient.cpp +++ b/libraries/networking/src/AssetClient.cpp @@ -43,10 +43,14 @@ AssetClient::AssetClient() { auto nodeList = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::AssetMappingOperationReply, this, "handleAssetMappingOperationReply"); - packetReceiver.registerListener(PacketType::AssetGetInfoReply, this, "handleAssetGetInfoReply"); - packetReceiver.registerListener(PacketType::AssetGetReply, this, "handleAssetGetReply", true); - packetReceiver.registerListener(PacketType::AssetUploadReply, this, "handleAssetUploadReply"); + packetReceiver.registerListener(PacketType::AssetMappingOperationReply, + PacketReceiver::makeSourcedListenerReference(this, &AssetClient::handleAssetMappingOperationReply)); + packetReceiver.registerListener(PacketType::AssetGetInfoReply, + PacketReceiver::makeSourcedListenerReference(this, &AssetClient::handleAssetGetInfoReply)); + packetReceiver.registerListener(PacketType::AssetGetReply, + PacketReceiver::makeSourcedListenerReference(this, &AssetClient::handleAssetGetReply), true); + packetReceiver.registerListener(PacketType::AssetUploadReply, + PacketReceiver::makeSourcedListenerReference(this, &AssetClient::handleAssetUploadReply)); connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &AssetClient::handleNodeKilled); connect(nodeList.data(), &LimitedNodeList::clientConnectionToNodeReset, diff --git a/libraries/networking/src/EntityScriptClient.cpp b/libraries/networking/src/EntityScriptClient.cpp index 1eab5bf2d7..fb98e8042b 100644 --- a/libraries/networking/src/EntityScriptClient.cpp +++ b/libraries/networking/src/EntityScriptClient.cpp @@ -34,7 +34,8 @@ EntityScriptClient::EntityScriptClient() { auto nodeList = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::EntityScriptGetStatusReply, this, "handleGetScriptStatusReply"); + packetReceiver.registerListener(PacketType::EntityScriptGetStatusReply, + PacketReceiver::makeSourcedListenerReference(this, &EntityScriptClient::handleGetScriptStatusReply)); connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &EntityScriptClient::handleNodeKilled); connect(nodeList.data(), &LimitedNodeList::clientConnectionToNodeReset, diff --git a/libraries/networking/src/MessagesClient.cpp b/libraries/networking/src/MessagesClient.cpp index d6f9d041ea..c883935cb4 100644 --- a/libraries/networking/src/MessagesClient.cpp +++ b/libraries/networking/src/MessagesClient.cpp @@ -28,7 +28,8 @@ MessagesClient::MessagesClient() { }); auto nodeList = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); - packetReceiver.registerListener(PacketType::MessagesData, this, "handleMessagesPacket"); + packetReceiver.registerListener(PacketType::MessagesData, + PacketReceiver::makeSourcedListenerReference(this, &MessagesClient::handleMessagesPacket)); connect(nodeList.data(), &LimitedNodeList::nodeActivated, this, &MessagesClient::handleNodeActivated); } diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index e02a8dd56e..076e94522f 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -139,20 +139,34 @@ NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) startSTUNPublicSocketUpdate(); auto& packetReceiver = getPacketReceiver(); - packetReceiver.registerListener(PacketType::DomainList, this, "processDomainServerList"); - packetReceiver.registerListener(PacketType::Ping, this, "processPingPacket"); - packetReceiver.registerListener(PacketType::PingReply, this, "processPingReplyPacket"); - packetReceiver.registerListener(PacketType::ICEPing, this, "processICEPingPacket"); - packetReceiver.registerListener(PacketType::DomainServerAddedNode, this, "processDomainServerAddedNode"); - packetReceiver.registerListener(PacketType::DomainServerConnectionToken, this, "processDomainServerConnectionTokenPacket"); - packetReceiver.registerListener(PacketType::DomainConnectionDenied, &_domainHandler, "processDomainServerConnectionDeniedPacket"); - packetReceiver.registerListener(PacketType::DomainSettings, &_domainHandler, "processSettingsPacketList"); - packetReceiver.registerListener(PacketType::ICEServerPeerInformation, &_domainHandler, "processICEResponsePacket"); - packetReceiver.registerListener(PacketType::DomainServerRequireDTLS, &_domainHandler, "processDTLSRequirementPacket"); - packetReceiver.registerListener(PacketType::ICEPingReply, &_domainHandler, "processICEPingReplyPacket"); - packetReceiver.registerListener(PacketType::DomainServerPathResponse, this, "processDomainServerPathResponse"); - packetReceiver.registerListener(PacketType::DomainServerRemovedNode, this, "processDomainServerRemovedNode"); - packetReceiver.registerListener(PacketType::UsernameFromIDReply, this, "processUsernameFromIDReply"); + packetReceiver.registerListener(PacketType::DomainList, + PacketReceiver::makeUnsourcedListenerReference(this, &NodeList::processDomainServerList)); + packetReceiver.registerListener(PacketType::Ping, + PacketReceiver::makeSourcedListenerReference(this, &NodeList::processPingPacket)); + packetReceiver.registerListener(PacketType::PingReply, + PacketReceiver::makeSourcedListenerReference(this, &NodeList::processPingReplyPacket)); + packetReceiver.registerListener(PacketType::ICEPing, + PacketReceiver::makeUnsourcedListenerReference(this, &NodeList::processICEPingPacket)); + packetReceiver.registerListener(PacketType::DomainServerAddedNode, + PacketReceiver::makeUnsourcedListenerReference(this, &NodeList::processDomainServerAddedNode)); + packetReceiver.registerListener(PacketType::DomainServerConnectionToken, + PacketReceiver::makeUnsourcedListenerReference(this, &NodeList::processDomainServerConnectionTokenPacket)); + packetReceiver.registerListener(PacketType::DomainConnectionDenied, + PacketReceiver::makeUnsourcedListenerReference(&_domainHandler, &DomainHandler::processDomainServerConnectionDeniedPacket)); + packetReceiver.registerListener(PacketType::DomainSettings, + PacketReceiver::makeUnsourcedListenerReference(&_domainHandler, &DomainHandler::processSettingsPacketList)); + packetReceiver.registerListener(PacketType::ICEServerPeerInformation, + PacketReceiver::makeUnsourcedListenerReference(&_domainHandler, &DomainHandler::processICEResponsePacket)); + packetReceiver.registerListener(PacketType::DomainServerRequireDTLS, + PacketReceiver::makeUnsourcedListenerReference(&_domainHandler, &DomainHandler::processDTLSRequirementPacket)); + packetReceiver.registerListener(PacketType::ICEPingReply, + PacketReceiver::makeUnsourcedListenerReference(&_domainHandler, &DomainHandler::processICEPingReplyPacket)); + packetReceiver.registerListener(PacketType::DomainServerPathResponse, + PacketReceiver::makeUnsourcedListenerReference(this, &NodeList::processDomainServerPathResponse)); + packetReceiver.registerListener(PacketType::DomainServerRemovedNode, + PacketReceiver::makeUnsourcedListenerReference(this, &NodeList::processDomainServerRemovedNode)); + packetReceiver.registerListener(PacketType::UsernameFromIDReply, + PacketReceiver::makeUnsourcedListenerReference(this, &NodeList::processUsernameFromIDReply)); } qint64 NodeList::sendStats(QJsonObject statsObject, HifiSockAddr destination) { diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 962ceab00f..80222d38a9 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -12,7 +12,8 @@ #include "PacketReceiver.h" -#include +#include +#include #include "DependencyManager.h" #include "NetworkLogging.h" @@ -25,85 +26,56 @@ PacketReceiver::PacketReceiver(QObject* parent) : QObject(parent) { qRegisterMetaType>(); } -bool PacketReceiver::registerListenerForTypes(PacketTypeList types, QObject* listener, const char* slot) { +bool PacketReceiver::ListenerReference::invokeWithQt(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode) { + return QMetaObject::invokeMethod(getObject(), [=]() { + this->invokeDirectly(receivedMessagePointer, sourceNode); + }); +} + +bool PacketReceiver::registerListenerForTypes(PacketTypeList types, const ListenerReferencePointer& listener) { Q_ASSERT_X(!types.empty(), "PacketReceiver::registerListenerForTypes", "No types to register"); - Q_ASSERT_X(listener, "PacketReceiver::registerListenerForTypes", "No object to register"); - Q_ASSERT_X(slot, "PacketReceiver::registerListenerForTypes", "No slot to register"); + Q_ASSERT_X(listener, "PacketReceiver::registerListenerForTypes", "No listener to register"); - // Partition types based on whether they are sourced or not (non sourced in front) - auto middle = std::partition(std::begin(types), std::end(types), [](PacketType type) { - return PacketTypeEnum::getNonSourcedPackets().contains(type); - }); - - QMetaMethod nonSourcedMethod, sourcedMethod; - - // Check we have a valid method for non sourced types if any - if (middle != std::begin(types)) { - nonSourcedMethod = matchingMethodForListener(*std::begin(types), listener, slot); - if (!nonSourcedMethod.isValid()) { - return false; - } - } - - // Check we have a valid method for sourced types if any - if (middle != std::end(types)) { - sourcedMethod = matchingMethodForListener(*middle, listener, slot); - if (!sourcedMethod.isValid()) { - return false; - } - } - - // Register non sourced types - std::for_each(std::begin(types), middle, [this, &listener, &nonSourcedMethod](PacketType type) { - registerVerifiedListener(type, listener, nonSourcedMethod); - }); - - // Register sourced types - std::for_each(middle, std::end(types), [this, &listener, &sourcedMethod](PacketType type) { - registerVerifiedListener(type, listener, sourcedMethod); + std::for_each(std::begin(types), std::end(types), [this, &listener](PacketType type) { + registerVerifiedListener(type, listener); }); return true; } -void PacketReceiver::registerDirectListener(PacketType type, QObject* listener, const char* slot) { - Q_ASSERT_X(listener, "PacketReceiver::registerDirectListener", "No object to register"); - Q_ASSERT_X(slot, "PacketReceiver::registerDirectListener", "No slot to register"); +void PacketReceiver::registerDirectListener(PacketType type, const ListenerReferencePointer& listener) { + Q_ASSERT_X(listener, "PacketReceiver::registerDirectListener", "No listener to register"); - bool success = registerListener(type, listener, slot); + bool success = registerListener(type, listener); if (success) { QMutexLocker locker(&_directConnectSetMutex); // if we successfully registered, add this object to the set of objects that are directly connected - _directlyConnectedObjects.insert(listener); + _directlyConnectedObjects.insert(listener->getObject()); } } -void PacketReceiver::registerDirectListenerForTypes(PacketTypeList types, - QObject* listener, const char* slot) { - Q_ASSERT_X(listener, "PacketReceiver::registerDirectListenerForTypes", "No object to register"); - Q_ASSERT_X(slot, "PacketReceiver::registerDirectListenerForTypes", "No slot to register"); +void PacketReceiver::registerDirectListenerForTypes(PacketTypeList types, const ListenerReferencePointer& listener) { + Q_ASSERT_X(listener, "PacketReceiver::registerDirectListenerForTypes", "No listener to register"); // just call register listener for types to start - bool success = registerListenerForTypes(std::move(types), listener, slot); + bool success = registerListenerForTypes(std::move(types), listener); if (success) { QMutexLocker locker(&_directConnectSetMutex); // if we successfully registered, add this object to the set of objects that are directly connected - _directlyConnectedObjects.insert(listener); + _directlyConnectedObjects.insert(listener->getObject()); } } -bool PacketReceiver::registerListener(PacketType type, QObject* listener, const char* slot, - bool deliverPending) { - Q_ASSERT_X(listener, "PacketReceiver::registerListener", "No object to register"); - Q_ASSERT_X(slot, "PacketReceiver::registerListener", "No slot to register"); +bool PacketReceiver::registerListener(PacketType type, const ListenerReferencePointer& listener, bool deliverPending) { + Q_ASSERT_X(listener, "PacketReceiver::registerListener", "No listener to register"); - QMetaMethod matchingMethod = matchingMethodForListener(type, listener, slot); + bool matchingMethod = matchingMethodForListener(type, listener); - if (matchingMethod.isValid()) { + if (matchingMethod) { qCDebug(networking) << "Registering a packet listener for packet list type" << type; - registerVerifiedListener(type, listener, matchingMethod, deliverPending); + registerVerifiedListener(type, listener, deliverPending); return true; } else { qCWarning(networking) << "FAILED to Register a packet listener for packet list type" << type; @@ -111,62 +83,23 @@ bool PacketReceiver::registerListener(PacketType type, QObject* listener, const } } -QMetaMethod PacketReceiver::matchingMethodForListener(PacketType type, QObject* object, const char* slot) const { - Q_ASSERT_X(object, "PacketReceiver::matchingMethodForListener", "No object to call"); - Q_ASSERT_X(slot, "PacketReceiver::matchingMethodForListener", "No slot to call"); +bool PacketReceiver::matchingMethodForListener(PacketType type, const ListenerReferencePointer& listener) const { + Q_ASSERT_X(listener, "PacketReceiver::matchingMethodForListener", "No listener to call"); - // normalize the slot with the expected parameters - static const QString SIGNATURE_TEMPLATE("%1(%2)"); - static const QString NON_SOURCED_MESSAGE_LISTENER_PARAMETERS = "QSharedPointer"; + bool isSourced = listener->isSourced(); + bool isNonSourcedPacket = PacketTypeEnum::getNonSourcedPackets().contains(type); - QSet possibleSignatures { - SIGNATURE_TEMPLATE.arg(slot, NON_SOURCED_MESSAGE_LISTENER_PARAMETERS) - }; - - if (!PacketTypeEnum::getNonSourcedPackets().contains(type)) { - static const QString SOURCED_MESSAGE_LISTENER_PARAMETERS = "QSharedPointer,QSharedPointer"; - static const QString TYPEDEF_SOURCED_MESSAGE_LISTENER_PARAMETERS = "QSharedPointer,SharedNodePointer"; - - // a sourced packet must take the shared pointer to the ReceivedMessage but optionally could include - // a shared pointer to the node - possibleSignatures << SIGNATURE_TEMPLATE.arg(slot, TYPEDEF_SOURCED_MESSAGE_LISTENER_PARAMETERS); - possibleSignatures << SIGNATURE_TEMPLATE.arg(slot, SOURCED_MESSAGE_LISTENER_PARAMETERS); + assert(!isSourced || !isNonSourcedPacket); + if (isSourced && isNonSourcedPacket) { + qCDebug(networking) << "PacketReceiver::registerListener cannot support a sourced listener for type" << type; + return false; } - int methodIndex = -1; - - foreach(const QString& signature, possibleSignatures) { - QByteArray normalizedSlot = - QMetaObject::normalizedSignature(signature.toStdString().c_str()); - - // does the constructed normalized method exist? - methodIndex = object->metaObject()->indexOfSlot(normalizedSlot.toStdString().c_str()); - - if (methodIndex >= 0) { - break; - } - } - - if (methodIndex < 0) { - qCDebug(networking) << "PacketReceiver::registerListener expected a slot with one of the following signatures:" - << possibleSignatures.toList() << "- but such a slot was not found." - << "Could not complete listener registration for type" << type; - } - - Q_ASSERT(methodIndex >= 0); - - // return the converted QMetaMethod - if (methodIndex >= 0) { - return object->metaObject()->method(methodIndex); - } else { - // if somehow (scripting?) something bad gets in here at runtime that doesn't hit the asserts above - // return a non-valid QMetaMethod - return QMetaMethod(); - } + return true; } -void PacketReceiver::registerVerifiedListener(PacketType type, QObject* object, const QMetaMethod& slot, bool deliverPending) { - Q_ASSERT_X(object, "PacketReceiver::registerVerifiedListener", "No object to register"); +void PacketReceiver::registerVerifiedListener(PacketType type, const ListenerReferencePointer& listener, bool deliverPending) { + Q_ASSERT_X(listener, "PacketReceiver::registerVerifiedListener", "No listener to register"); QMutexLocker locker(&_packetListenerLock); if (_messageListenerMap.contains(type)) { @@ -175,7 +108,7 @@ void PacketReceiver::registerVerifiedListener(PacketType type, QObject* object, } // add the mapping - _messageListenerMap[type] = { QPointer(object), slot, deliverPending }; + _messageListenerMap[type] = { listener, deliverPending }; } void PacketReceiver::unregisterListener(QObject* listener) { @@ -188,7 +121,7 @@ void PacketReceiver::unregisterListener(QObject* listener) { auto it = _messageListenerMap.begin(); while (it != _messageListenerMap.end()) { - if (it.value().object == listener) { + if (it.value().listener->getObject() == listener) { it = _messageListenerMap.erase(it); } else { ++it; @@ -261,7 +194,7 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer recei QMutexLocker packetListenerLocker(&_packetListenerLock); auto it = _messageListenerMap.find(receivedMessage->getType()); - if (it != _messageListenerMap.end() && it->method.isValid()) { + if (it != _messageListenerMap.end() && !it->listener.isNull()) { auto listener = it.value(); @@ -271,36 +204,19 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer recei bool success = false; - Qt::ConnectionType connectionType; + bool isDirectConnect = false; // check if this is a directly connected listener { QMutexLocker directConnectLocker(&_directConnectSetMutex); - connectionType = _directlyConnectedObjects.contains(listener.object) ? Qt::DirectConnection : Qt::AutoConnection; + isDirectConnect = _directlyConnectedObjects.contains(listener.listener->getObject()); } - QMetaMethod metaMethod = listener.method; - - static const QByteArray QSHAREDPOINTER_NODE_NORMALIZED = QMetaObject::normalizedType("QSharedPointer"); - static const QByteArray SHARED_NODE_NORMALIZED = QMetaObject::normalizedType("SharedNodePointer"); - // one final check on the QPointer before we go to invoke - if (listener.object) { - if (metaMethod.parameterTypes().contains(SHARED_NODE_NORMALIZED)) { - success = metaMethod.invoke(listener.object, - connectionType, - Q_ARG(QSharedPointer, receivedMessage), - Q_ARG(SharedNodePointer, matchingNode)); - - } else if (metaMethod.parameterTypes().contains(QSHAREDPOINTER_NODE_NORMALIZED)) { - success = metaMethod.invoke(listener.object, - connectionType, - Q_ARG(QSharedPointer, receivedMessage), - Q_ARG(QSharedPointer, matchingNode)); - + if (listener.listener->getObject()) { + if (isDirectConnect) { + success = listener.listener->invokeDirectly(receivedMessage, matchingNode); } else { - success = metaMethod.invoke(listener.object, - connectionType, - Q_ARG(QSharedPointer, receivedMessage)); + success = listener.listener->invokeWithQt(receivedMessage, matchingNode); } } else { qCDebug(networking).nospace() << "Listener for packet " << receivedMessage->getType() @@ -310,19 +226,19 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer recei // if it exists, remove the listener from _directlyConnectedObjects { QMutexLocker directConnectLocker(&_directConnectSetMutex); - _directlyConnectedObjects.remove(listener.object); + _directlyConnectedObjects.remove(listener.listener->getObject()); } } if (!success) { qCDebug(networking).nospace() << "Error delivering packet " << receivedMessage->getType() << " to listener " - << listener.object << "::" << qPrintable(listener.method.methodSignature()); + << listener.listener->getObject(); } } else if (it == _messageListenerMap.end()) { qCWarning(networking) << "No listener found for packet type" << receivedMessage->getType(); // insert a dummy listener so we don't print this again - _messageListenerMap.insert(receivedMessage->getType(), { nullptr, QMetaMethod(), false }); + _messageListenerMap.insert(receivedMessage->getType(), { ListenerReferencePointer(), false }); } } diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index e29a0d6e5a..0bed88cff9 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -16,8 +16,6 @@ #include #include -#include -#include #include #include #include @@ -29,6 +27,7 @@ #include "udt/PacketHeaders.h" class EntityEditPacketSender; +class Node; class OctreePacketProcessor; namespace std { @@ -42,6 +41,22 @@ namespace std { class PacketReceiver : public QObject { Q_OBJECT +public: + class ListenerReference { + public: + virtual bool invokeDirectly(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode) = 0; + bool invokeWithQt(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode); + virtual bool isSourced() const = 0; + virtual QObject* getObject() const = 0; + }; + typedef QSharedPointer ListenerReferencePointer; + + template + static ListenerReferencePointer makeUnsourcedListenerReference(T* target, void (T::*slot)(QSharedPointer)); + + template + static ListenerReferencePointer makeSourcedListenerReference(T* target, void (T::*slot)(QSharedPointer, QSharedPointer)); + public: using PacketTypeList = std::vector; @@ -55,8 +70,8 @@ public: // If deliverPending is false, ReceivedMessage will only be delivered once all packets for the message have // been received. If deliverPending is true, ReceivedMessage will be delivered as soon as the first packet // for the message is received. - bool registerListener(PacketType type, QObject* listener, const char* slot, bool deliverPending = false); - bool registerListenerForTypes(PacketTypeList types, QObject* listener, const char* slot); + bool registerListener(PacketType type, const ListenerReferencePointer& listener, bool deliverPending = false); + bool registerListenerForTypes(PacketTypeList types, const ListenerReferencePointer& listener); void unregisterListener(QObject* listener); void handleVerifiedPacket(std::unique_ptr packet); @@ -64,9 +79,34 @@ public: void handleMessageFailure(HifiSockAddr from, udt::Packet::MessageNumber messageNumber); private: + template + class UnsourcedListenerReference : public ListenerReference { + public: + inline UnsourcedListenerReference(T* target, void (T::*slot)(QSharedPointer)); + virtual bool invokeDirectly(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode); + virtual bool isSourced() const { return false; } + virtual QObject* getObject() const { return _target; } + + private: + QPointer _target; + void (T::*_slot)(QSharedPointer); + }; + + template + class SourcedListenerReference : public ListenerReference { + public: + inline SourcedListenerReference(T* target, void (T::*slot)(QSharedPointer, QSharedPointer)); + virtual bool invokeDirectly(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode); + virtual bool isSourced() const { return true; } + virtual QObject* getObject() const { return _target; } + + private: + QPointer _target; + void (T::*_slot)(QSharedPointer, QSharedPointer); + }; + struct Listener { - QPointer object; - QMetaMethod method; + ListenerReferencePointer listener; bool deliverPending; }; @@ -74,11 +114,11 @@ private: // these are brutal hacks for now - ideally GenericThread / ReceivedPacketProcessor // should be changed to have a true event loop and be able to handle our QMetaMethod::invoke - void registerDirectListenerForTypes(PacketTypeList types, QObject* listener, const char* slot); - void registerDirectListener(PacketType type, QObject* listener, const char* slot); + void registerDirectListenerForTypes(PacketTypeList types, const ListenerReferencePointer& listener); + void registerDirectListener(PacketType type, const ListenerReferencePointer& listener); - QMetaMethod matchingMethodForListener(PacketType type, QObject* object, const char* slot) const; - void registerVerifiedListener(PacketType type, QObject* listener, const QMetaMethod& slot, bool deliverPending = false); + bool matchingMethodForListener(PacketType type, const ListenerReferencePointer& listener) const; + void registerVerifiedListener(PacketType type, const ListenerReferencePointer& listener, bool deliverPending = false); QMutex _packetListenerLock; QHash _messageListenerMap; @@ -93,4 +133,42 @@ private: friend class OctreePacketProcessor; }; +template +PacketReceiver::ListenerReferencePointer PacketReceiver::makeUnsourcedListenerReference(T* target, void (T::* slot)(QSharedPointer)) { + return QSharedPointer>::create(target, slot); +} + +template +PacketReceiver::ListenerReferencePointer PacketReceiver::makeSourcedListenerReference(T* target, void (T::* slot)(QSharedPointer, QSharedPointer)) { + return QSharedPointer>::create(target, slot); +} + +template +PacketReceiver::UnsourcedListenerReference::UnsourcedListenerReference(T* target, void (T::*slot)(QSharedPointer)) : + _target(target),_slot(slot) { +} + +template +bool PacketReceiver::UnsourcedListenerReference::invokeDirectly(const QSharedPointer& receivedMessagePointer, const QSharedPointer&) { + if (_target.isNull()) { + return false; + } + (_target->*_slot)(receivedMessagePointer); + return true; +} + +template +PacketReceiver::SourcedListenerReference::SourcedListenerReference(T* target, void (T::*slot)(QSharedPointer, QSharedPointer)) : + _target(target),_slot(slot) { +} + +template +bool PacketReceiver::SourcedListenerReference::invokeDirectly(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode) { + if (_target.isNull()) { + return false; + } + (_target->*_slot)(receivedMessagePointer, sourceNode); + return true; +} + #endif // hifi_PacketReceiver_h diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index 88a4f5bf32..4ba456d859 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -16,8 +16,9 @@ #include #include -#include -#include +#include +#include +#include #include #include diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index dd2cc12d50..c4f24c552b 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -64,7 +64,8 @@ void OctreePersistThread::start() { cleanupOldReplacementBackups(); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::OctreeDataFileReply, this, "handleOctreeDataFileReply"); + packetReceiver.registerListener(PacketType::OctreeDataFileReply, + PacketReceiver::makeUnsourcedListenerReference(this, &OctreePersistThread::handleOctreeDataFileReply)); auto nodeList = DependencyManager::get(); const DomainHandler& domainHandler = nodeList->getDomainHandler(); From 34e3d9dd2b9b96a8a809e87a4d70a542c8738d08 Mon Sep 17 00:00:00 2001 From: Heather Anderson Date: Sun, 9 Aug 2020 15:44:41 -0700 Subject: [PATCH 002/127] improved listener lifetime controls (in case a deferred invoke takes longer than expected) --- libraries/networking/src/PacketReceiver.cpp | 3 ++- libraries/networking/src/PacketReceiver.h | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 80222d38a9..c13fb8566b 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -27,8 +27,9 @@ PacketReceiver::PacketReceiver(QObject* parent) : QObject(parent) { } bool PacketReceiver::ListenerReference::invokeWithQt(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode) { + ListenerReferencePointer thisPointer = sharedFromThis(); return QMetaObject::invokeMethod(getObject(), [=]() { - this->invokeDirectly(receivedMessagePointer, sourceNode); + thisPointer->invokeDirectly(receivedMessagePointer, sourceNode); }); } diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index 0bed88cff9..071638cda9 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "NLPacket.h" #include "NLPacketList.h" @@ -42,7 +44,7 @@ namespace std { class PacketReceiver : public QObject { Q_OBJECT public: - class ListenerReference { + class ListenerReference : public QEnableSharedFromThis { public: virtual bool invokeDirectly(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode) = 0; bool invokeWithQt(const QSharedPointer& receivedMessagePointer, const QSharedPointer& sourceNode); From 776b1071a01a1df2d71b4bf15a1679f72991c51d Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Mon, 31 Aug 2020 15:44:06 -0700 Subject: [PATCH 003/127] try to do it without QCursor::setPos --- .../resources/controllers/keyboardMouse.json | 18 +++++++++++ interface/src/Application.cpp | 20 +++++++++++- interface/src/Application.h | 1 + libraries/shared/src/shared/Camera.h | 31 +++++++++++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/interface/resources/controllers/keyboardMouse.json b/interface/resources/controllers/keyboardMouse.json index 11c80a4dd2..9449d37f7d 100644 --- a/interface/resources/controllers/keyboardMouse.json +++ b/interface/resources/controllers/keyboardMouse.json @@ -213,6 +213,15 @@ ] }, + { "from": { "makeAxis" : ["Keyboard.MouseMoveLeft", "Keyboard.MouseMoveRight"] }, + "to": "Actions.DeltaYaw", + "when": "Application.CaptureMouse", + "filters": + [ + { "type": "scale", "scale": 0.2 } + ] + }, + { "from": { "makeAxis" : ["Keyboard.MouseMoveUp", "Keyboard.MouseMoveDown"] }, "when": ["!Application.CameraSelfie", "!Application.CameraLookAt", "Keyboard.RightMouseButton"], "to": "Actions.DeltaPitch", @@ -222,6 +231,15 @@ ] }, + { "from": { "makeAxis" : ["Keyboard.MouseMoveUp", "Keyboard.MouseMoveDown"] }, + "to": "Actions.DeltaPitch", + "when": "Application.CaptureMouse", + "filters": + [ + { "type": "scale", "scale": 0.2 } + ] + }, + { "from": { "makeAxis" : ["Keyboard.MouseMoveUp", "Keyboard.MouseMoveDown"] }, "when": ["Application.CameraLookAt", "Keyboard.RightMouseButton"], "to": "Actions.DeltaPitch", diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cc2aed7f53..024df2343b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -680,6 +680,7 @@ private: * CameraIndependentnumbernumberThe camera is in independent mode. * CameraEntitynumbernumberThe camera is in entity mode. * InHMDnumbernumberThe user is in HMD mode. + * CaptureMousenumbernumberThe mouse is captured. * AdvancedMovementnumbernumberAdvanced movement (walking) controls are * enabled. * StrafeEnablednumbernumberStrafing is enabled @@ -715,6 +716,7 @@ static const QString STATE_PLATFORM_ANDROID = "PlatformAndroid"; static const QString STATE_LEFT_HAND_DOMINANT = "LeftHandDominant"; static const QString STATE_RIGHT_HAND_DOMINANT = "RightHandDominant"; static const QString STATE_STRAFE_ENABLED = "StrafeEnabled"; +static const QString STATE_CAMERA_CAPTURE_MOUSE = "CaptureMouse"; // Statically provided display and input plugins extern DisplayPluginList getDisplayPlugins(); @@ -918,7 +920,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); controller::StateController::setStateVariables({ { STATE_IN_HMD, STATE_CAMERA_FULL_SCREEN_MIRROR, STATE_CAMERA_FIRST_PERSON, STATE_CAMERA_FIRST_PERSON_LOOK_AT, STATE_CAMERA_THIRD_PERSON, - STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT, STATE_CAMERA_LOOK_AT, STATE_CAMERA_SELFIE, + STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT, STATE_CAMERA_LOOK_AT, STATE_CAMERA_SELFIE, STATE_CAMERA_CAPTURE_MOUSE, STATE_SNAP_TURN, STATE_ADVANCED_MOVEMENT_CONTROLS, STATE_GROUNDED, STATE_NAV_FOCUSED, STATE_PLATFORM_WINDOWS, STATE_PLATFORM_MAC, STATE_PLATFORM_ANDROID, STATE_LEFT_HAND_DOMINANT, STATE_RIGHT_HAND_DOMINANT, STATE_STRAFE_ENABLED } }); DependencyManager::set(); @@ -1891,6 +1893,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _applicationStateDevice->setInputVariant(STATE_CAMERA_INDEPENDENT, []() -> float { return qApp->getCamera().getMode() == CAMERA_MODE_INDEPENDENT ? 1 : 0; }); + _applicationStateDevice->setInputVariant(STATE_CAMERA_CAPTURE_MOUSE, []() -> float { + return qApp->getCamera().getCaptureMouse() ? 1 : 0; + }); _applicationStateDevice->setInputVariant(STATE_SNAP_TURN, []() -> float { return qApp->getMyAvatar()->getSnapTurn() ? 1 : 0; }); @@ -2406,6 +2411,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo updateSystemTabletMode(); connect(&_myCamera, &Camera::modeUpdated, this, &Application::cameraModeChanged); + connect(&_myCamera, &Camera::captureMouseUpdated, this, &Application::captureMouseChanged); DependencyManager::get()->setShouldPickHUDOperator([]() { return DependencyManager::get()->isHMDMode(); }); DependencyManager::get()->setCalculatePos2DFromHUDOperator([this](const glm::vec3& intersection) { @@ -5910,6 +5916,18 @@ void Application::cameraModeChanged() { cameraMenuChanged(); } +void Application::captureMouseChanged() { + if (_myCamera.getCaptureMouse()) { + // we want to grab the mouse here so that no other widgets get events, and also hide the mouse, but these don't work: + //_glWidget->grabMouse(); + //QCursor::setShape(Qt::CursorShape::BlankCursor); + } else { + // we want to release the mouse here so that other widgets get events, and also show the mouse, but these don't work: + //_glWidget->releaseMouse(); + //QCursor::setShape(Qt::CursorShape::ArrowCursor); + } +} + void Application::changeViewAsNeeded(float boomLength) { // Switch between first and third person views as needed // This is called when the boom length has changed diff --git a/interface/src/Application.h b/interface/src/Application.h index f42696cda0..50ae9860fa 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -430,6 +430,7 @@ public slots: void cycleCamera(); void cameraModeChanged(); void cameraMenuChanged(); + void captureMouseChanged(); void toggleOverlays(); void setOverlaysVisible(bool visible); Q_INVOKABLE void centerUI(); diff --git a/libraries/shared/src/shared/Camera.h b/libraries/shared/src/shared/Camera.h index 48cd814d86..2564a3f7c8 100644 --- a/libraries/shared/src/shared/Camera.h +++ b/libraries/shared/src/shared/Camera.h @@ -43,6 +43,7 @@ class Camera : public QObject { Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation) Q_PROPERTY(QString mode READ getModeString WRITE setModeString NOTIFY modeUpdated) Q_PROPERTY(QVariantMap frustum READ getViewFrustum CONSTANT) + Q_PROPERTY(bool captureMouse READ getCaptureMouse WRITE setCaptureMouse NOTIFY captureMouseUpdated) public: Camera(); @@ -110,6 +111,20 @@ public slots: */ void setOrientation(const glm::quat& orientation); + /**jsdoc + * Gets the current mouse capture state. + * @function Camera.getMouseCapture + * @returns {boolean} The current mouse capture state. + */ + bool getCaptureMouse() const { return _captureMouse; } + + /**jsdoc + * Sets mouse capture state. + * @function Camera.setCaptureMouse + * @param {boolean} captureMouse - Whether or not to capture the mouse. + */ + void setCaptureMouse(bool captureMouse) { _captureMouse = captureMouse; } + /**jsdoc * Computes a {@link PickRay} based on the current camera configuration and the specified x, y position on the * screen. The {@link PickRay} can be used in functions such as {@link Entities.findRayIntersection} and @@ -181,6 +196,20 @@ signals: */ void modeUpdated(const QString& newMode); + /**jsdoc + * Triggered when the camera mouse capture state changes. + * @function Camera.captureMouseUpdated + * @param {boolean} newCaptureMouse - The new mouse capture state. + * @returns {Signal} + * @example Report mouse capture state changes. + * function onCaptureMouseUpdated(newCaptureMouse) { + * print("The mouse capture has changed to " + newCaptureMouse); + * } + * + * Camera.captureMouseUpdated.connect(onCaptureMouseUpdated); + */ + void captureMouseUpdated(bool newCaptureMouse); + private: void recompose(); void decompose(); @@ -194,6 +223,8 @@ private: glm::quat _orientation; bool _isKeepLookingAt{ false }; glm::vec3 _lookingAt; + + bool _captureMouse { false }; }; #endif // hifi_Camera_h From 5281f89d0ddadb6d248bf5eed5caca98f9ac25c1 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Wed, 2 Sep 2020 11:28:43 -0700 Subject: [PATCH 004/127] FUUUUUUUCK FINALLY --- .../resources/controllers/keyboardMouse.json | 128 +++--------------- interface/src/Application.cpp | 30 ++-- interface/src/Application.h | 6 +- .../src/display-plugins/CompositorHelper.cpp | 1 - .../src/input-plugins/KeyboardMouseDevice.cpp | 20 ++- .../src/input-plugins/KeyboardMouseDevice.h | 4 +- libraries/shared/src/shared/Camera.h | 2 +- 7 files changed, 61 insertions(+), 130 deletions(-) diff --git a/interface/resources/controllers/keyboardMouse.json b/interface/resources/controllers/keyboardMouse.json index 9449d37f7d..a91151f4e5 100644 --- a/interface/resources/controllers/keyboardMouse.json +++ b/interface/resources/controllers/keyboardMouse.json @@ -3,9 +3,9 @@ "channels": [ { "from": "Keyboard.A", "when": ["Keyboard.RightMouseButton", "!Keyboard.Control"], "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.D", "when": ["Keyboard.RightMouseButton", "!Keyboard.Control"], "to": "Actions.LATERAL_RIGHT" }, - { "from": "Keyboard.E", "when": ["!Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LATERAL_RIGHT" }, - { "from": "Keyboard.Q", "when": ["!Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LATERAL_LEFT" }, + { "from": "Keyboard.Q", "when": ["!Application.CameraSelfie", "!Keyboard.Control", "!Application.CaptureMouse"], "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.Q", "when": ["Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LATERAL_RIGHT" }, + { "from": "Keyboard.E", "when": ["!Application.CameraSelfie", "!Keyboard.Control", "!Application.CaptureMouse"], "to": "Actions.LATERAL_RIGHT" }, { "from": "Keyboard.E", "when": ["Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.T", "when": "!Keyboard.Control", "to": "Actions.TogglePushToTalk" }, @@ -72,46 +72,20 @@ { "from": { "makeAxis" : [ ["Keyboard.Left"], ["Keyboard.Right"] - ] + ] }, - "when": ["Application.CameraFirstPerson", "!Keyboard.Shift"], + "when": ["!Application.CameraFSM", "!Application.CameraIndependent", "!Application.CameraEntity", "!Application.CaptureMouse", "!Keyboard.Shift"], "to": "Actions.Yaw" }, - { "from": { "makeAxis" : [ - ["Keyboard.Left"], - ["Keyboard.Right"] - ] - }, - "when": ["Application.CameraFirstPersonLookat", "!Keyboard.Shift"], - "to": "Actions.Yaw" + { "from": "Keyboard.Left", + "when": ["!Application.CameraFSM", "!Application.CameraIndependent", "!Application.CameraEntity", "Application.CaptureMouse", "!Keyboard.Shift"], + "to": "Actions.LATERAL_LEFT" }, - { "from": { "makeAxis" : [ - ["Keyboard.Left"], - ["Keyboard.Right"] - ] - }, - "when": ["Application.CameraThirdPerson", "!Keyboard.Shift"], - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.Left"], - ["Keyboard.Right"] - ] - }, - "when": ["Application.CameraLookAt", "!Keyboard.Shift"], - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.Left"], - ["Keyboard.Right"] - ] - }, - "when": ["Application.CameraSelfie", "!Keyboard.Shift"], - "to": "Actions.Yaw" + { "from": "Keyboard.Right", + "when": ["!Application.CameraFSM", "!Application.CameraIndependent", "!Application.CameraEntity", "Application.CaptureMouse", "!Keyboard.Shift"], + "to": "Actions.LATERAL_RIGHT" }, { "from": { "makeAxis" : [ @@ -119,53 +93,18 @@ ["Keyboard.D"] ] }, - "when": ["Application.CameraFirstPerson", "!Keyboard.Control"], + "when": ["!Application.CameraFSM", "!Application.CameraIndependent", "!Application.CameraEntity", "!Application.CaptureMouse", "!Keyboard.Control"], "to": "Actions.Yaw" }, - { "from": { "makeAxis" : [ - ["Keyboard.A"], - ["Keyboard.D"] - ] - }, - "when": ["Application.CameraFirstPersonLookat", "!Keyboard.Control"], - "to": "Actions.Yaw" + { "from": "Keyboard.A", + "when": ["!Application.CameraFSM", "!Application.CameraIndependent", "!Application.CameraEntity", "Application.CaptureMouse", "!Keyboard.Control"], + "to": "Actions.LATERAL_LEFT" }, - { "from": { "makeAxis" : [ - ["Keyboard.A"], - ["Keyboard.D"] - ] - }, - "when": ["Application.CameraThirdPerson", "!Keyboard.Control"], - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.A"], - ["Keyboard.D"] - ] - }, - "when": ["Application.CameraLookAt", "!Keyboard.Control"], - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.A"], - ["Keyboard.D"] - ] - }, - "when": ["Application.CameraSelfie", "!Keyboard.Control"], - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.TouchpadLeft"], - ["Keyboard.TouchpadRight"] - ] - }, - "when": "Application.CameraFirstPerson", - "to": "Actions.Yaw" + { "from": "Keyboard.D", + "when": ["!Application.CameraFSM", "!Application.CameraIndependent", "!Application.CameraEntity", "Application.CaptureMouse", "!Keyboard.Control"], + "to": "Actions.LATERAL_RIGHT" }, { "from": { "makeAxis" : [ @@ -173,39 +112,12 @@ ["Keyboard.TouchpadRight"] ] }, - "when": "Application.CameraFirstPersonLookat", - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.TouchpadLeft"], - ["Keyboard.TouchpadRight"] - ] - }, - "when": "Application.CameraThirdPerson", - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.TouchpadLeft"], - ["Keyboard.TouchpadRight"] - ] - }, - "when": "Application.CameraLookAt", - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.TouchpadLeft"], - ["Keyboard.TouchpadRight"] - ] - }, - "when": "Application.CameraSelfie", + "when": ["!Application.CameraFSM", "!Application.CameraIndependent", "!Application.CameraEntity"], "to": "Actions.Yaw" }, { "from": { "makeAxis" : ["Keyboard.MouseMoveLeft", "Keyboard.MouseMoveRight"] }, - "when": "Keyboard.RightMouseButton", + "when": ["Keyboard.RightMouseButton", "!Application.CaptureMouse"], "to": "Actions.DeltaYaw", "filters": [ @@ -223,7 +135,7 @@ }, { "from": { "makeAxis" : ["Keyboard.MouseMoveUp", "Keyboard.MouseMoveDown"] }, - "when": ["!Application.CameraSelfie", "!Application.CameraLookAt", "Keyboard.RightMouseButton"], + "when": ["!Application.CameraSelfie", "!Application.CameraLookAt", "!Application.CaptureMouse", "Keyboard.RightMouseButton"], "to": "Actions.DeltaPitch", "filters": [ diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 024df2343b..e46182ed83 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4699,6 +4699,11 @@ void Application::maybeToggleMenuVisible(QMouseEvent* event) const { void Application::mouseMoveEvent(QMouseEvent* event) { PROFILE_RANGE(app_input_mouse, __FUNCTION__); + if (_ignoreMouseMove) { + _ignoreMouseMove = false; + return; + } + maybeToggleMenuVisible(event); auto& compositor = getApplicationCompositor(); @@ -4744,7 +4749,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) { } if (_keyboardMouseDevice->isActive()) { - _keyboardMouseDevice->mouseMoveEvent(event); + _keyboardMouseDevice->mouseMoveEvent(event, _captureMouse, _mouseCaptureTarget); } } @@ -5916,15 +5921,13 @@ void Application::cameraModeChanged() { cameraMenuChanged(); } -void Application::captureMouseChanged() { - if (_myCamera.getCaptureMouse()) { - // we want to grab the mouse here so that no other widgets get events, and also hide the mouse, but these don't work: - //_glWidget->grabMouse(); - //QCursor::setShape(Qt::CursorShape::BlankCursor); +void Application::captureMouseChanged(bool captureMouse) { + _captureMouse = captureMouse; + if (_captureMouse) { + _glWidget->setCursor(QCursor(Qt::BlankCursor)); } else { - // we want to release the mouse here so that other widgets get events, and also show the mouse, but these don't work: - //_glWidget->releaseMouse(); - //QCursor::setShape(Qt::CursorShape::ArrowCursor); + _mouseCaptureTarget = QPointF(NAN, NAN); + _glWidget->unsetCursor(); } } @@ -6278,6 +6281,15 @@ void Application::update(float deltaTime) { PROFILE_ASYNC_END(app, "Scene Loading", ""); } + if (_captureMouse) { + QPoint point = _glWidget->mapToGlobal(_glWidget->geometry().center()); + if (QCursor::pos() != point) { + _mouseCaptureTarget = point; + _ignoreMouseMove = true; + QCursor::setPos(point); + } + } + auto myAvatar = getMyAvatar(); { PerformanceTimer perfTimer("devices"); diff --git a/interface/src/Application.h b/interface/src/Application.h index 50ae9860fa..d66d9c32b3 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -430,7 +430,7 @@ public slots: void cycleCamera(); void cameraModeChanged(); void cameraMenuChanged(); - void captureMouseChanged(); + void captureMouseChanged(bool captureMouse); void toggleOverlays(); void setOverlaysVisible(bool visible); Q_INVOKABLE void centerUI(); @@ -756,7 +756,9 @@ private: bool _settingsLoaded { false }; - bool _fakedMouseEvent { false }; + bool _captureMouse { false }; + bool _ignoreMouseMove { false }; + QPointF _mouseCaptureTarget { NAN, NAN }; bool _isMissingSequenceNumbers { false }; diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp index a1138b3018..0cc3e5216e 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp @@ -213,7 +213,6 @@ void CompositorHelper::setAllowMouseCapture(bool capture) { _allowMouseCapture = capture; emit allowMouseCaptureChanged(); } - _allowMouseCapture = capture; } void CompositorHelper::handleLeaveEvent() { diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index c436a5b510..a49c822014 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -36,13 +36,12 @@ void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputC _inputDevice->_axisStateMap[MOUSE_AXIS_X].value = _lastCursor.x(); _inputDevice->_axisStateMap[MOUSE_AXIS_Y].value = _lastCursor.y(); - QPoint currentMove = _lastCursor - _previousCursor; - updateDeltaAxisValue(MOUSE_AXIS_X_POS, currentMove.x() > 0 ? currentMove.x() : 0.0f); - updateDeltaAxisValue(MOUSE_AXIS_X_NEG, currentMove.x() < 0 ? -currentMove.x() : 0.0f); + updateDeltaAxisValue(MOUSE_AXIS_X_POS, _accumulatedMove.x() > 0 ? _accumulatedMove.x() : 0.0f); + updateDeltaAxisValue(MOUSE_AXIS_X_NEG, _accumulatedMove.x() < 0 ? -_accumulatedMove.x() : 0.0f); // Y mouse is inverted positive is pointing up the screen - updateDeltaAxisValue(MOUSE_AXIS_Y_POS, currentMove.y() < 0 ? -currentMove.y() : 0.0f); - updateDeltaAxisValue(MOUSE_AXIS_Y_NEG, currentMove.y() > 0 ? currentMove.y() : 0.0f); - _previousCursor = _lastCursor; + updateDeltaAxisValue(MOUSE_AXIS_Y_POS, _accumulatedMove.y() < 0 ? -_accumulatedMove.y() : 0.0f); + updateDeltaAxisValue(MOUSE_AXIS_Y_NEG, _accumulatedMove.y() > 0 ? _accumulatedMove.y() : 0.0f); + _accumulatedMove = QPoint(0.0f, 0.0f); }); // For touch event, we need to check that the last event is not too long ago @@ -113,9 +112,16 @@ void KeyboardMouseDevice::eraseMouseClicked() { _inputDevice->_buttonPressedMap.erase(_inputDevice->makeInput(Qt::RightButton, true).getChannel()); } -void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event) { +void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event, bool capture, QPointF captureTarget) { QPoint currentPos = event->pos(); + if (!capture) { + _accumulatedMove += currentPos - _lastCursor; + } else if (!isNaN(captureTarget.x())) { + QPointF change = event->globalPos() - captureTarget; + _accumulatedMove += QPoint(change.x(), change.y()); + } + // FIXME - this has the characteristic that it will show large jumps when you move the cursor // outside of the application window, because we don't get MouseEvents when the cursor is outside // of the application window. diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h index 4286ced477..158e2f594f 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h @@ -79,7 +79,7 @@ public: void keyPressEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent* event); - void mouseMoveEvent(QMouseEvent* event); + void mouseMoveEvent(QMouseEvent* event, bool capture, QPointF captureTarget); void mousePressEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event); void eraseMouseClicked(); @@ -123,7 +123,7 @@ public: protected: QPoint _lastCursor; - QPoint _previousCursor; + QPoint _accumulatedMove; QPoint _mousePressPos; quint64 _mousePressTime; qreal _lastTotalScaleFactor; diff --git a/libraries/shared/src/shared/Camera.h b/libraries/shared/src/shared/Camera.h index 2564a3f7c8..d8ed98c0a2 100644 --- a/libraries/shared/src/shared/Camera.h +++ b/libraries/shared/src/shared/Camera.h @@ -123,7 +123,7 @@ public slots: * @function Camera.setCaptureMouse * @param {boolean} captureMouse - Whether or not to capture the mouse. */ - void setCaptureMouse(bool captureMouse) { _captureMouse = captureMouse; } + void setCaptureMouse(bool captureMouse) { _captureMouse = captureMouse; emit captureMouseUpdated(captureMouse); } /**jsdoc * Computes a {@link PickRay} based on the current camera configuration and the specified x, y position on the From 1403f8908f59417de53ccfad4005c217b4106936 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Wed, 2 Sep 2020 11:58:22 -0700 Subject: [PATCH 005/127] don't capture mouse when other windows or menus are active --- interface/src/Application.cpp | 18 +++++++++++++++++- interface/src/Application.h | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e46182ed83..270013a80d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5921,6 +5921,22 @@ void Application::cameraModeChanged() { cameraMenuChanged(); } +bool Application::shouldCaptureMouse() const { + if (!_captureMouse) { + return false; + } + + if (!_glWidget->isActiveWindow()) { + return false; + } + + if (ui::Menu::isSomeSubmenuShown()) { + return false; + } + + return true; +} + void Application::captureMouseChanged(bool captureMouse) { _captureMouse = captureMouse; if (_captureMouse) { @@ -6281,7 +6297,7 @@ void Application::update(float deltaTime) { PROFILE_ASYNC_END(app, "Scene Loading", ""); } - if (_captureMouse) { + if (shouldCaptureMouse()) { QPoint point = _glWidget->mapToGlobal(_glWidget->geometry().center()); if (QCursor::pos() != point) { _mouseCaptureTarget = point; diff --git a/interface/src/Application.h b/interface/src/Application.h index d66d9c32b3..7ab62016c8 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -603,6 +603,7 @@ private: void maybeToggleMenuVisible(QMouseEvent* event) const; void toggleTabletUI(bool shouldOpen = false) const; + bool shouldCaptureMouse() const; void userKickConfirmation(const QUuid& nodeID); From 932f5dbfb313ffb65bdb3bd67bcbc9d34c7f55cc Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Sun, 6 Sep 2020 22:41:17 -0700 Subject: [PATCH 006/127] CR --- interface/src/Application.cpp | 14 +------------- .../src/display-plugins/CompositorHelper.cpp | 1 + .../src/display-plugins/CompositorHelper.h | 1 + .../src/input-plugins/KeyboardMouseDevice.cpp | 1 + .../src/input-plugins/KeyboardMouseDevice.h | 1 + libraries/shared/src/shared/Camera.h | 5 +++-- 6 files changed, 8 insertions(+), 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 270013a80d..a83b2c4431 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5922,19 +5922,7 @@ void Application::cameraModeChanged() { } bool Application::shouldCaptureMouse() const { - if (!_captureMouse) { - return false; - } - - if (!_glWidget->isActiveWindow()) { - return false; - } - - if (ui::Menu::isSomeSubmenuShown()) { - return false; - } - - return true; + return _captureMouse && _glWidget->isActiveWindow() && !ui::Menu::isSomeSubmenuShown(); } void Application::captureMouseChanged(bool captureMouse) { diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp index 0cc3e5216e..9b6946bbcc 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp @@ -1,6 +1,7 @@ // // Created by Benjamin Arnold on 5/27/14. // Copyright 2014 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.h b/libraries/display-plugins/src/display-plugins/CompositorHelper.h index 1279050a57..c45119fd63 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.h +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.h @@ -1,6 +1,7 @@ // // Created by Bradley Austin Davis Arnold on 2015/06/13 // Copyright 2015 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index a49c822014..c7c5543d44 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -4,6 +4,7 @@ // // Created by Sam Gateau on 4/27/15. // Copyright 2015 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h index 158e2f594f..216194a712 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h @@ -4,6 +4,7 @@ // // Created by Sam Gateau on 4/27/15. // Copyright 2015 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/libraries/shared/src/shared/Camera.h b/libraries/shared/src/shared/Camera.h index d8ed98c0a2..76d344c21c 100644 --- a/libraries/shared/src/shared/Camera.h +++ b/libraries/shared/src/shared/Camera.h @@ -3,6 +3,7 @@ // interface/src // // Copyright 2013 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -119,9 +120,9 @@ public slots: bool getCaptureMouse() const { return _captureMouse; } /**jsdoc - * Sets mouse capture state. + * Sets the mouse capture state. * @function Camera.setCaptureMouse - * @param {boolean} captureMouse - Whether or not to capture the mouse. + * @param {boolean} captureMouse - true to capture the mouse, false to release the mouse. */ void setCaptureMouse(bool captureMouse) { _captureMouse = captureMouse; emit captureMouseUpdated(captureMouse); } From 9546cebe3cae48dbf186fe5f620b040a2fb241f6 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Wed, 9 Sep 2020 08:32:54 -0700 Subject: [PATCH 007/127] CR --- interface/src/Application.cpp | 10 ++++++---- libraries/shared/src/shared/Camera.h | 4 +++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a83b2c4431..795325d761 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -680,7 +680,9 @@ private: * CameraIndependentnumbernumberThe camera is in independent mode. * CameraEntitynumbernumberThe camera is in entity mode. * InHMDnumbernumberThe user is in HMD mode. - * CaptureMousenumbernumberThe mouse is captured. + * CaptureMousenumbernumberThe mouse is captured. In this mode, + * the mouse is invisible and cannot leave the bounds of Interface, as long as Interface is the active window and + * no menu item is selected. * AdvancedMovementnumbernumberAdvanced movement (walking) controls are * enabled. * StrafeEnablednumbernumberStrafing is enabled @@ -716,7 +718,7 @@ static const QString STATE_PLATFORM_ANDROID = "PlatformAndroid"; static const QString STATE_LEFT_HAND_DOMINANT = "LeftHandDominant"; static const QString STATE_RIGHT_HAND_DOMINANT = "RightHandDominant"; static const QString STATE_STRAFE_ENABLED = "StrafeEnabled"; -static const QString STATE_CAMERA_CAPTURE_MOUSE = "CaptureMouse"; +static const QString STATE_CAPTURE_MOUSE = "CaptureMouse"; // Statically provided display and input plugins extern DisplayPluginList getDisplayPlugins(); @@ -920,7 +922,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); controller::StateController::setStateVariables({ { STATE_IN_HMD, STATE_CAMERA_FULL_SCREEN_MIRROR, STATE_CAMERA_FIRST_PERSON, STATE_CAMERA_FIRST_PERSON_LOOK_AT, STATE_CAMERA_THIRD_PERSON, - STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT, STATE_CAMERA_LOOK_AT, STATE_CAMERA_SELFIE, STATE_CAMERA_CAPTURE_MOUSE, + STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT, STATE_CAMERA_LOOK_AT, STATE_CAMERA_SELFIE, STATE_CAPTURE_MOUSE, STATE_SNAP_TURN, STATE_ADVANCED_MOVEMENT_CONTROLS, STATE_GROUNDED, STATE_NAV_FOCUSED, STATE_PLATFORM_WINDOWS, STATE_PLATFORM_MAC, STATE_PLATFORM_ANDROID, STATE_LEFT_HAND_DOMINANT, STATE_RIGHT_HAND_DOMINANT, STATE_STRAFE_ENABLED } }); DependencyManager::set(); @@ -1893,7 +1895,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _applicationStateDevice->setInputVariant(STATE_CAMERA_INDEPENDENT, []() -> float { return qApp->getCamera().getMode() == CAMERA_MODE_INDEPENDENT ? 1 : 0; }); - _applicationStateDevice->setInputVariant(STATE_CAMERA_CAPTURE_MOUSE, []() -> float { + _applicationStateDevice->setInputVariant(STATE_CAPTURE_MOUSE, []() -> float { return qApp->getCamera().getCaptureMouse() ? 1 : 0; }); _applicationStateDevice->setInputVariant(STATE_SNAP_TURN, []() -> float { diff --git a/libraries/shared/src/shared/Camera.h b/libraries/shared/src/shared/Camera.h index 76d344c21c..0dc8703b2d 100644 --- a/libraries/shared/src/shared/Camera.h +++ b/libraries/shared/src/shared/Camera.h @@ -120,7 +120,9 @@ public slots: bool getCaptureMouse() const { return _captureMouse; } /**jsdoc - * Sets the mouse capture state. + * Sets the mouse capture state. When true, the mouse will be invisible and cannot leave the bounds of + * Interface, as long as Interface is the active window and no menu item is selected. When false, the mouse + * will behave normally. * @function Camera.setCaptureMouse * @param {boolean} captureMouse - true to capture the mouse, false to release the mouse. */ From 9395caa7d0f812a1fabb3b4bdb8da9d1b5900f9c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 17 Sep 2020 09:01:27 +1200 Subject: [PATCH 008/127] Rework GitHub Actions builds for merges to master --- .github/workflows/master_build.yml | 308 +++++++++++++---------------- tools/ci-scripts/upload.py | 3 +- 2 files changed, 137 insertions(+), 174 deletions(-) diff --git a/.github/workflows/master_build.yml b/.github/workflows/master_build.yml index 9ef4728cb0..824c279845 100644 --- a/.github/workflows/master_build.yml +++ b/.github/workflows/master_build.yml @@ -3,114 +3,60 @@ name: Master CI Build on: push: branches: - - master + - gha-master-ci +# FIXME: Change target branch to "master" before merging into "master" branch. env: - #APP_NAME: gpu-frame-player APP_NAME: interface BUILD_TYPE: Release - BUCKET_NAME: hifi-gh-builds + BUILD_NUMBER: ${{ github.run_number }} CI_BUILD: Github - CMAKE_BACKTRACE_URL: https://highfidelity.sp.backtrace.io:6098 - CMAKE_BACKTRACE_TOKEN: ${{ secrets.backtrace_token }} - CMAKE_BACKTRACE_SYMBOLS_TOKEN: ${{ secrets.backtrace_symbols_token }} GIT_COMMIT: ${{ github.sha }} - HIFI_VCPKG_BOOTSTRAP: true - LAUNCHER_HMAC_SECRET: ${{ secrets.launcher_hmac_secret }} - OCULUS_APP_ID: '${{ secrets.oculus_app_id }}' + # VCPKG did not build well on OSX disabling HIFI_VCPKG_BOOTSTRAP, which invokes a download to a working version of vcpkg + # HIFI_VCPKG_BOOTSTRAP: true RELEASE_TYPE: PRODUCTION - RELEASE_DYNAMODB_V2: ReleaseManager2-ReleaseQueue-prod + RELEASE_NUMBER: ${{ github.run_number }} STABLE_BUILD: 0 + UPLOAD_BUCKET: athena-public - - # OSX specific variables + # OSX-specific variables DEVELOPER_DIR: /Applications/Xcode_11.2.app/Contents/Developer MACOSX_DEPLOYMENT_TARGET: '10.11' - # WIN32 specific variables + # WIN-specific variables PreferredToolArchitecture: X64 -# Mac OS -#PLATFORM_CMAKE_GENERATOR=Xcode -#PLATFORM_BUILD_ARGUMENTS=--config Release --target package -#ARTIFACT_EXPRESSION=build/*.dmg,build/*.zip - -# Windows -#PLATFORM_CMAKE_GENERATOR=Visual Studio 15 2017 Win64 -#PLATFORM_BUILD_ARGUMENTS=--target package --config release -#ARTIFACT_EXPRESSION=build/*.exe,build/*.zip,*-symbols.zip - -# Ubuntu -#PLATFORM_CMAKE_GENERATOR=Unix Makefiles -#PLATFORM_BUILD_ARGUMENTS=--target all -- -j4 -#ARTIFACT_EXPRESSION=build/assignment-client/**,build/domain-server/**,build/ice-server/ice-server,build/tools/ice-client/ice-client,build/tools/ac-client/ac-client,build/tools/oven,build/ext/makefiles/nvtt/project/lib/**,build/ext/makefiles/quazip/project/lib/** - -# Android -# branch: master -# GA_TRACKING_ID: ${{ secrets.ga_tracking_id }} -# ANDROID_OAUTH_CLIENT_SECRET=${MASKED_ANDROID_OAUTH_CLIENT_SECRET_NIGHTLY} -# ANDROID_OAUTH_CLIENT_ID=6c7d2349c0614640150db37457a1f75dce98a28ffe8f14d47f6cfae4de5b262a -# ANDROID_OAUTH_REDIRECT_URI=https://dev-android-interface.highfidelity.com/auth -# branch: !master -# GA_TRACKING_ID=UA-39558647-11 -# ANDROID_OAUTH_CLIENT_SECRET=${MASKED_ANDROID_OAUTH_CLIENT_SECRET_RELEASE} -# ANDROID_OAUTH_CLIENT_ID= c1063ea5d0b0c405e0c9cd77351328e211a91496a3f25985a99e861f1661db1d -# ANDROID_OAUTH_REDIRECT_URI=https://android-interface.highfidelity.com/auth -# ARTIFACT_EXPRESSION=android/*.apk -# ANDROID_APK_NAME=HighFidelity-Beta-PR${RELEASE_NUMBER}-${GIT_COMMIT_SHORT}.apk -# ANDROID_BUILT_APK_NAME=interface-debug.apk -# ANDROID_APP=interface -# ANDROID_BUILD_DIR=debug -# ANDROID_BUILD_TARGET=assembleDebug -# STABLE_BUILD=0 - - - jobs: - generate_build_number: - runs-on: ubuntu-latest - steps: - - name: Generate build number - id: buildnumber - uses: highfidelity/build-number@v3 - with: - token: ${{secrets.github_token}} - - name: Upload build number - uses: actions/upload-artifact@v1 - with: - name: BUILD_NUMBER - path: BUILD_NUMBER - build: strategy: matrix: - os: [windows-latest, macOS-latest] - build_type: [full, client] - #os: [windows-latest, macOS-latest, ubuntu-latest] - # exclude: - # - os: ubuntu-latest - # build_type: client + os: [windows-latest, macOS-latest, ubuntu-18.04] + # build_type: [full, client] + build_type: [full] + include: + - os: ubuntu-18.04 + build_type: full + apt-dependencies: mesa-common-dev libegl1 libglvnd-dev libdouble-conversion1 libpulse0 + fail-fast: false runs-on: ${{matrix.os}} - needs: generate_build_number steps: - - name: Download build number - uses: actions/download-artifact@v1 - with: - name: BUILD_NUMBER - - name: Restore build number - id: buildnumber - uses: highfidelity/build-number@v3 - with: - output_name: RELEASE_NUMBER - - name: Configure Build Environment 1 + - name: Report Build Number + shell: bash + run: | + echo "Build number: $BUILD_NUMBER" + - name: Configure build environment 1 shell: bash id: buildenv1 run: | echo ::set-env name=UPLOAD_PREFIX::master echo ::set-env name=GIT_COMMIT_SHORT::`echo $GIT_COMMIT | cut -c1-7` + echo ::set-env name=JOB_NAME::"build (${{matrix.os}}, ${{matrix.build_type}})" # Linux build variables - if [ "${{ matrix.os }}" = "ubuntu-latest" ]; then + if [[ "${{ matrix.os }}" = "ubuntu-"* ]]; then + echo ::set-env name=PYTHON_EXEC::python3 echo ::set-env name=INSTALLER_EXT::tgz + echo ::set-env name=CMAKE_BUILD_EXTRA::"-- -j3" + echo ::set-env name=CMAKE_EXTRA::"-DBUILD_TOOLS:BOOLEAN=FALSE -DHIFI_PYTHON_EXEC:FILEPATH=$(which python3)" fi # Mac build variables if [ "${{ matrix.os }}" = "macOS-latest" ]; then @@ -118,8 +64,8 @@ jobs: echo ::set-env name=ZIP_COMMAND::zip echo ::set-env name=ZIP_ARGS::-r echo ::set-env name=INSTALLER_EXT::dmg - echo ::set-env name=SYMBOL_REGEX::dSYM - echo "::set-output name=symbols_archive::${{ steps.buildnumber.outputs.build_number }}-${{ matrix.build_type }}-mac-symbols.zip" + echo ::set-env name=CMAKE_EXTRA::"-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" + echo "::set-output name=symbols_archive::${BUILD_NUMBER}-${{ matrix.build_type }}-mac-symbols.zip" fi # Windows build variables if [ "${{ matrix.os }}" = "windows-latest" ]; then @@ -127,40 +73,28 @@ jobs: echo ::set-env name=ZIP_COMMAND::7z echo ::set-env name=ZIP_ARGS::a echo ::set-env name=INSTALLER_EXT::exe + echo ::set-env name=CMAKE_EXTRA::"-A x64" echo "::set-env name=SYMBOL_REGEX::\(exe\|dll\|pdb\)" - echo "::set-output name=symbols_archive::${{ steps.buildnumber.outputs.build_number }}-${{ matrix.build_type }}-win-symbols.zip" + echo "::set-output name=symbols_archive::${BUILD_NUMBER}-${{ matrix.build_type }}-win-symbols.zip" + # echo ::set-env name=HF_PFX_PASSPHRASE::${{secrets.pfx_key}} + # echo "::set-env name=HF_PFX_FILE::${{runner.workspace}}\build\codesign.pfx" fi # Configuration is broken into two steps because you can't set an env var and also reference it in the same step - - name: Configure Build Environment 2 + - name: Configure build environment 2 shell: bash run: | echo "${{ steps.buildenv1.outputs.symbols_archive }}" - echo ::set-env name=ARTIFACT_PATTERN::HighFidelity-Beta-*.$INSTALLER_EXT + echo ::set-env name=ARTIFACT_PATTERN::Vircadia-Alpha-*.$INSTALLER_EXT # Build type variables if [ "${{ matrix.build_type }}" = "full" ]; then echo ::set-env name=CLIENT_ONLY::FALSE - echo ::set-env name=INSTALLER::HighFidelity-Beta-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT + echo ::set-env name=INSTALLER::Vircadia-Alpha-$BUILD_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT else echo ::set-env name=CLIENT_ONLY::TRUE - echo ::set-env name=INSTALLER::HighFidelity-Beta-Interface-$RELEASE_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT + echo ::set-env name=INSTALLER::Vircadia-Alpha-Interface-$BUILD_NUMBER-$GIT_COMMIT_SHORT.$INSTALLER_EXT fi - # Linux build variables - if [ "${{ matrix.os }}" = "ubuntu-latest" ]; then - echo ::set-env name=PYTHON_EXEC::python3 - echo ::set-env name=CMAKE_EXTRA::"" - fi - # Mac build variables - if [ "${{ matrix.os }}" = "macOS-latest" ]; then - echo ::set-env name=CMAKE_EXTRA::"-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" - fi - # Windows build variables - if [ "${{ matrix.os }}" = "windows-latest" ]; then - echo ::set-env name=CMAKE_EXTRA::"-A x64" - echo ::set-env name=HF_PFX_PASSPHRASE::${{secrets.pfx_key}} - echo "::set-env name=HF_PFX_FILE::${{runner.workspace}}\build\codesign.pfx" - fi - - name: Clear Working Directory - if: matrix.os == 'windows-latest' + - name: Clear working directory + if: startsWith(matrix.os, 'windows') shell: bash working-directory: ${{runner.workspace}} run: rm -rf ./* @@ -168,89 +102,119 @@ jobs: with: submodules: true fetch-depth: 1 - - name: Create Build Directory - run: cmake -E make_directory ${{runner.workspace}}/build - - name: Decrypt Signing Key (Windows) - if: matrix.os == 'windows-latest' - working-directory: ${{runner.workspace}}/build + - name: Install dependencies + if: startsWith(matrix.os, 'ubuntu') shell: bash - run: gpg --batch --yes -o codesign.pfx --passphrase "${{secrets.gpg_symmetric_key}}" --decrypt $GITHUB_WORKSPACE/tools/ci-scripts/codesign.pfx.gpg - - name: Import Signing Key (Windows) - if: matrix.os == 'windows-latest' - working-directory: ${{runner.workspace}}/build - shell: powershell - run: | - $mypwd=ConvertTo-SecureString -String ${{ secrets.pfx_key }} -Force -AsPlainText - Import-PfxCertificate -Password $mypwd -CertStoreLocation Cert:\CurrentUser\My -FilePath ${{runner.workspace}}\build\codesign.pfx - Import-PfxCertificate -Password $mypwd -CertStoreLocation Cert:\LocalMachine\My -FilePath ${{runner.workspace}}\build\codesign.pfx + run: | + echo "Installing Python Modules:" + pip3 install distro || exit 1 + echo "Updating apt repository index" + sudo apt update || exit 1 + echo "Installing apt packages" + sudo apt install -y ${{ matrix.apt-dependencies }} || exit 1 - name: Install Python modules - if: matrix.os != 'ubuntu-latest' + if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS') shell: bash run: $PYTHON_EXEC -m pip install boto3 PyGithub + - name: Create build environment + shell: bash + run: cmake -E make_directory "${{runner.workspace}}/build" - name: Configure CMake working-directory: ${{runner.workspace}}/build shell: bash - run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCLIENT_ONLY:BOOLEAN=$CLIENT_ONLY $CMAKE_EXTRA - - name: Build Application + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DVCPKG_BUILD_TYPE=release -DCLIENT_ONLY:BOOLEAN=$CLIENT_ONLY -DBYPASS_SIGNING:BOOLEAN=TRUE $CMAKE_EXTRA + - name: Build application working-directory: ${{runner.workspace}}/build shell: bash - run: cmake --build . --config $BUILD_TYPE --target $APP_NAME - - name: Build Console + run: cmake --build . --config $BUILD_TYPE --target $APP_NAME $CMAKE_BUILD_EXTRA + - name: Build domain server working-directory: ${{runner.workspace}}/build shell: bash - run: cmake --build . --config $BUILD_TYPE --target packaged-server-console - - name: Build Domain Server (FullBuild) - if: matrix.build_type == 'full' - shell: bash - working-directory: ${{runner.workspace}}/build - run: cmake --build . --config $BUILD_TYPE --target domain-server - - name: Build Assignment Client (FullBuild) - if: matrix.build_type == 'full' - shell: bash - working-directory: ${{runner.workspace}}/build - run: cmake --build . --config $BUILD_TYPE --target assignment-client - - name: Build Installer + run: cmake --build . --config $BUILD_TYPE --target domain-server $CMAKE_BUILD_EXTRA + - name: Build assignment client working-directory: ${{runner.workspace}}/build shell: bash - run: cmake --build . --config $BUILD_TYPE --target package - - name: Sign Installer (Windows) - if: matrix.os == 'windows-latest' - shell: powershell - working-directory: C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64 - run: .\signtool.exe sign /fd sha256 /f ${{runner.workspace}}\build\codesign.pfx /p ${{secrets.pfx_key}} /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /td SHA256 ${{runner.workspace}}\build\${env:INSTALLER} - - name: Upload Artifact - if: matrix.os != 'ubuntu-latest' + run: cmake --build . --config $BUILD_TYPE --target assignment-client $CMAKE_BUILD_EXTRA + - name: Build console + working-directory: ${{runner.workspace}}/build + shell: bash + run: cmake --build . --config $BUILD_TYPE --target packaged-server-console $CMAKE_BUILD_EXTRA + - name: Build installer + working-directory: ${{runner.workspace}}/build + shell: bash + run: | + echo "Retry code from https://unix.stackexchange.com/a/137639" + function fail { + echo $1 >&2 + exit 1 + } + function retry { + local n=1 + local max=5 + local delay=15 + while true; do + "$@" && break || { + if [[ $n -lt $max ]]; then + ((n++)) + echo "Command failed. Attempt $n/$max:" + sleep $delay; + else + fail "The command has failed after $n attempts." + fi + } + done + } + retry cmake --build . --config $BUILD_TYPE --target package $CMAKE_BUILD_EXTRA + #- name: Sign installer (Windows) + # if: startsWith(matrix.os, 'windows') + # shell: powershell + # working-directory: C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64 + # run: .\signtool.exe sign /fd sha256 /f ${{runner.workspace}}\build\codesign.pfx /p ${{secrets.pfx_key}} /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /td SHA256 ${{runner.workspace}}\build\${env:INSTALLER} + - name: Output system stats + if: ${{ always() }} + working-directory: ${{runner.workspace}}/build + shell: bash + run: | + echo "Disk usage:" + df -h + - name: Output installer logs + if: failure() && startsWith(matrix.os, 'windows') + shell: bash + working-directory: ${{runner.workspace}}/build + run: cat ./_CPack_Packages/win64/NSIS/NSISOutput.log + - name: Upload artifact + if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS') shell: bash working-directory: ${{runner.workspace}}/build env: AWS_ACCESS_KEY_ID: ${{ secrets.aws_access_key_id }} AWS_SECRET_ACCESS_KEY: ${{ secrets.aws_secret_access_key }} run: $PYTHON_EXEC $GITHUB_WORKSPACE/tools/ci-scripts/upload.py - - name: Archive Symbols - if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest') - working-directory: ${{runner.workspace}} - shell: bash - run: | - SYMBOLS_TEMP="symbols-temp" - mkdir $SYMBOLS_TEMP - find "./build" \( -path '*/tools/gpu-frame-player/*' -or -path '*/interface/*' -or -path '*/plugins/*' \) -regex ".*\.$SYMBOL_REGEX" -exec cp -r {} $SYMBOLS_TEMP \; - cd $SYMBOLS_TEMP - $ZIP_COMMAND $ZIP_ARGS ../${{ steps.buildenv1.outputs.symbols_archive }} . - - name: Upload Symbols - if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest') - working-directory: ${{runner.workspace}} - shell: bash - run: | - curl --data-binary @${{ steps.buildenv1.outputs.symbols_archive }} "$CMAKE_BACKTRACE_URL/post?format=symbols&token=$CMAKE_BACKTRACE_SYMBOLS_TOKEN&upload_file=${{steps.buildenv1.outputs.symbols_archive}}&tag=$RELEASE_NUMBER" - # - name: Debug List Symbols - # if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest') - # working-directory: ${{runner.workspace}} - # shell: bash - # run: | - # unzip -v "${{runner.workspace}}/${{ steps.buildenv1.outputs.symbols_archive }}" - # - name: Debug Upload Symbols Artifact - # if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest') - # uses: actions/upload-artifact@v1 - # with: - # name: symbols - # path: ${{runner.workspace}}/${{ steps.buildenv1.outputs.symbols_archive }} + #- name: Archive symbols + # if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS') + # working-directory: ${{runner.workspace}} + # shell: bash + # run: | + # SYMBOLS_TEMP="symbols-temp" + # mkdir $SYMBOLS_TEMP + # find "./build" \( -path '*/tools/gpu-frame-player/*' -or -path '*/interface/*' -or -path '*/plugins/*' \) -regex ".*\.$SYMBOL_REGEX" -exec cp -r {} $SYMBOLS_TEMP \; + # cd $SYMBOLS_TEMP + # $ZIP_COMMAND $ZIP_ARGS ../${{ steps.buildenv1.outputs.symbols_archive }} . + #- name: Upload symbols + # if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS') + # working-directory: ${{runner.workspace}} + # shell: bash + # run: | + # curl --data-binary @${{ steps.buildenv1.outputs.symbols_archive }} "$CMAKE_BACKTRACE_URL/post?format=symbols&token=$CMAKE_BACKTRACE_SYMBOLS_TOKEN&upload_file=${{steps.buildenv1.outputs.symbols_archive}}&tag=$BUILD_NUMBER" + #- name: Debug list symbols + # if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS') + # working-directory: ${{runner.workspace}} + # shell: bash + # run: | + # unzip -v "${{runner.workspace}}/${{ steps.buildenv1.outputs.symbols_archive }}" + #- name: Upload debug list symbols + # if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'macOS') + # uses: actions/upload-artifact@v1 + # with: + # name: symbols + # path: ${{runner.workspace}}/${{ steps.buildenv1.outputs.symbols_archive }} diff --git a/tools/ci-scripts/upload.py b/tools/ci-scripts/upload.py index f43fbfd574..90d5d9be06 100644 --- a/tools/ci-scripts/upload.py +++ b/tools/ci-scripts/upload.py @@ -6,9 +6,8 @@ import boto3 import glob from github import Github - def main(): - bucket_name = os.environ['BUCKET_NAME'] + bucket_name = os.environ['UPLOAD_BUCKET'] upload_prefix = os.environ['UPLOAD_PREFIX'] release_number = os.environ['RELEASE_NUMBER'] full_prefix = upload_prefix + '/' + release_number[0:-2] + '/' + release_number From 0f1c5f895ffbfd978589868e4a44d1502f27b460 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 17 Sep 2020 09:01:43 +1200 Subject: [PATCH 009/127] Fix bypassing signing installer --- cmake/templates/NSIS.template.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index f40141be32..2a8052e735 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -202,9 +202,9 @@ ; The Inner invocation has written an uninstaller binary for us. ; We need to sign it if it's a production or PR build. !if @PRODUCTION_BUILD@ == 1 - !if @BYPASS_SIGNING@ == 1 + !if @BYPASS_SIGNING@ == TRUE !warning "BYPASS_SIGNING set - installer will not be signed" - !else + !else !system '"@SIGNTOOL_EXECUTABLE@" sign /fd sha256 /f %HF_PFX_FILE% /p %HF_PFX_PASSPHRASE% /tr http://timestamp.comodoca.com?td=sha256 /td SHA256 $%TEMP%\@UNINSTALLER_NAME@' = 0 !endif !endif From 2ed37d0c4701e9ee842669b439be8a347ffe8e21 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 17 Sep 2020 09:02:00 +1200 Subject: [PATCH 010/127] Fix upload target location and path --- tools/ci-scripts/upload.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ci-scripts/upload.py b/tools/ci-scripts/upload.py index 90d5d9be06..ab96e4ba24 100644 --- a/tools/ci-scripts/upload.py +++ b/tools/ci-scripts/upload.py @@ -10,14 +10,14 @@ def main(): bucket_name = os.environ['UPLOAD_BUCKET'] upload_prefix = os.environ['UPLOAD_PREFIX'] release_number = os.environ['RELEASE_NUMBER'] - full_prefix = upload_prefix + '/' + release_number[0:-2] + '/' + release_number + full_prefix = upload_prefix + '/' + release_number S3 = boto3.client('s3') path = os.path.join(os.getcwd(), os.environ['ARTIFACT_PATTERN']) files = glob.glob(path, recursive=False) for archiveFile in files: filePath, fileName = os.path.split(archiveFile) S3.upload_file(os.path.join(filePath, fileName), bucket_name, full_prefix + '/' + fileName) - print("Uploaded Artifact to S3: https://{}.s3-us-west-2.amazonaws.com/{}/{}".format(bucket_name, full_prefix, fileName)) + print("Uploaded Artifact to S3: https://{}.s3-eu-west-3.amazonaws.com/{}/{}".format(bucket_name, full_prefix, fileName)) print("Finished") main() From e4f32f1cea7c57d6a3273a360eb762fc05d55443 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Sat, 19 Sep 2020 11:23:59 -0700 Subject: [PATCH 011/127] add camera sensitivity slider --- interface/src/Application.cpp | 4 ++-- interface/src/ui/PreferencesDialog.cpp | 10 ++++++++++ libraries/shared/src/shared/Camera.h | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 795325d761..d8c4dde1a8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6351,8 +6351,8 @@ void Application::update(float deltaTime) { if (deltaTime > FLT_EPSILON && userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z) == 0.0f) { myAvatar->setDriveKey(MyAvatar::PITCH, -1.0f * userInputMapper->getActionState(controller::Action::PITCH)); myAvatar->setDriveKey(MyAvatar::YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW)); - myAvatar->setDriveKey(MyAvatar::DELTA_PITCH, -1.0f * userInputMapper->getActionState(controller::Action::DELTA_PITCH)); - myAvatar->setDriveKey(MyAvatar::DELTA_YAW, -1.0f * userInputMapper->getActionState(controller::Action::DELTA_YAW)); + myAvatar->setDriveKey(MyAvatar::DELTA_PITCH, -_myCamera.getSensitivity() * userInputMapper->getActionState(controller::Action::DELTA_PITCH)); + myAvatar->setDriveKey(MyAvatar::DELTA_YAW, -_myCamera.getSensitivity() * userInputMapper->getActionState(controller::Action::DELTA_YAW)); myAvatar->setDriveKey(MyAvatar::STEP_YAW, -1.0f * userInputMapper->getActionState(controller::Action::STEP_YAW)); } } diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 9f8a8ec013..79d9ebaa5c 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -358,6 +358,16 @@ void setupPreferences() { preference->setItems(items); preferences->addPreference(preference); } + { + auto getter = [myAvatar]()->float { return qApp->getCamera().getSensitivity(); }; + auto setter = [myAvatar](float value) { qApp->getCamera().setSensitivity(value); }; + auto preference = new SpinnerSliderPreference(VR_MOVEMENT, "Camera Sensitivity", getter, setter); + preference->setMin(0.01f); + preference->setMax(5.0f); + preference->setStep(0.1); + preference->setDecimals(2); + preferences->addPreference(preference); + } { auto getter = [myAvatar]()->int { return myAvatar->getControlScheme(); }; auto setter = [myAvatar](int index) { myAvatar->setControlScheme(index); }; diff --git a/libraries/shared/src/shared/Camera.h b/libraries/shared/src/shared/Camera.h index 0dc8703b2d..f6ce9be2d8 100644 --- a/libraries/shared/src/shared/Camera.h +++ b/libraries/shared/src/shared/Camera.h @@ -45,6 +45,7 @@ class Camera : public QObject { Q_PROPERTY(QString mode READ getModeString WRITE setModeString NOTIFY modeUpdated) Q_PROPERTY(QVariantMap frustum READ getViewFrustum CONSTANT) Q_PROPERTY(bool captureMouse READ getCaptureMouse WRITE setCaptureMouse NOTIFY captureMouseUpdated) + Q_PROPERTY(float sensitivity READ getSensitivity WRITE setSensitivity) public: Camera(); @@ -128,6 +129,20 @@ public slots: */ void setCaptureMouse(bool captureMouse) { _captureMouse = captureMouse; emit captureMouseUpdated(captureMouse); } + /**jsdoc + * Gets the current camera sensitivity. + * @function Camera.getSensitivity + * @returns {boolean} The current camera sensitivity. + */ + float getSensitivity() const { return _sensitivity; } + + /**jsdoc + * Sets the camera sensitivity. Higher values mean that the camera will be more sensitive to mouse movements. + * @function Camera.setSensitivity + * @param {boolean} sensitivity - The desired camera sensitivity. + */ + void setSensitivity(float sensitivity) { _sensitivity = glm::max(0.0f, sensitivity); } + /**jsdoc * Computes a {@link PickRay} based on the current camera configuration and the specified x, y position on the * screen. The {@link PickRay} can be used in functions such as {@link Entities.findRayIntersection} and @@ -228,6 +243,7 @@ private: glm::vec3 _lookingAt; bool _captureMouse { false }; + float _sensitivity { 1.0f }; }; #endif // hifi_Camera_h From 4f353ec66859476d20c21c319ba5ad9a15b1b975 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 26 Sep 2020 00:38:53 -0400 Subject: [PATCH 012/127] New fonts for pictograms New fonts for pictograms since "hifi-glyphs.ttf" has no more room for new icons. This contains icons for copy, cut, paste, duplicate, undo, redo... and a V logo. --- interface/resources/fonts/vircadia_glyphs.ttf | Bin 0 -> 3568 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 interface/resources/fonts/vircadia_glyphs.ttf diff --git a/interface/resources/fonts/vircadia_glyphs.ttf b/interface/resources/fonts/vircadia_glyphs.ttf new file mode 100644 index 0000000000000000000000000000000000000000..fe69e4bf6fe3eab1bc86ca68e963419b3db6149b GIT binary patch literal 3568 zcmd6qe{2-T7017C_I7XYcK2@2cenS`_TApyo_#iV$JyQk^P@Om2PmWwB(8A-=4u@5 zV6d?R1(GUhs9K5g2k8$*Q7YPshM)>5DM{5zNu;R!Q>y+EwJ4QRlvZk_@<%HrZK_0# za;|1?v5=dPM*XL=+S$*|y!Yn4cQdoIAOIR3hk$!WM(*4BASZKkDwcE zfc6rAjxX%4)TXaa9s+0#!2Zd@jrqWEq6pAUfOZ{hEY2@2K>)PN0OW(SCm)QS^t}%V zV}Nvdda7|Cfd{q&xBhb^OxZuLFJ$Ak56qEk2AZI1gy^00zNhBf#_g(f22U>;DNw zxCsD%_>MZU{EPtX5_^vO3&vYpI_#C^b%61>!7e$LZZE3SqT=iDI?Y^@oVHD_n85bY zdk_J3hP@2nZ0kvX#A>=V&aJ}zTrOi{V`JEa47R#Hyx?>>GPI9Rt7TIy0qksn!ymKr9UrS zz1>TaoW!;qCvQtQ)2kS5jP;Q{#%4JO{8j2X} zC>k;PvNd}k)NhHQe!DMQGukOSUW(PrRo*4 z`FpckHSLN?rEIm@YzryWt>~|s6O7|wG+#&@Ts!Om~c59U)`68A4r5`Kc9yplIUiK*jZ%J zkNYu$<3QMsbx_RkO06qqbW)ItWtOvw)Ltq zOOdw^^mB=P-6kt%@@6M9uF~fy#?zXUidKcb;SY7yCB{7AfJg8!#$t&~W>Cw7D5pw- zf9;xBBrl8cL@=spy*|doP?V5P#Wgfk-g2GkZUlmbswpU; zu2fa^iNSI}kF`Y`%rDqO$B7AIsv2rrosM`I^RJ1g1Hp1!_=^x|zRQ?Ws^oRi*AYtS z!GzwnGkjKLBrrix8h{sRsBD-$hafsJgi*}m37iHBIn&xe{q{QIYdsG(OQQTEsHrb7mZMG?XJx|*^r+F^@6dzJ{*+k#>*#s>FmhnQ%4_|TbRkW z(=q3*e#-{m&&2^VX9hgp{*7Ya02^< zMk~7wQ(dL4Gxq-Op8ZchwxeA3v9OuWMVZpo#psz;QfYcA^u(gl}8@X}R&vhn!bb4iN{9gtjR2*7q(Kn?e}>_HjdcbV^nZ@Vm^mjW(( z!DzS3G8pY~*#|}wF8je~%4G$N4!Nv?(NUK*F#3wi0WkWi%Q`yfw96p`=tX4sfe*(q zg9S{YfdiO90~0uiS)9Z?rm+YdpIMk}9GGcL9GpElKfMU-!W0hT7-rGH05rN zwYvJ#@~|T672_?t-Ad_yU*9>*mBV~;@;~OJyt1gyp2Hv@j{+f5(BlZw(h`_6 e)481C*dqvh#lUl$b?0m0&D~GG!?kYz-uX8H`r}vt literal 0 HcmV?d00001 From 08038fb1bcfe96bab892f5d8e7ea3d82be8a76bb Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 26 Sep 2020 00:42:19 -0400 Subject: [PATCH 013/127] New css for new buttons and icons New css for new buttons and icons for the Create App. new HMD button for copy, cut, paste, duplicate, undo and redo. --- scripts/system/html/css/edit-style.css | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index ada8116a0d..8a381ff4ad 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -65,6 +65,14 @@ url(../fonts/hifi-glyphs.ttf); } +@font-face { + font-family: Vircadia-Glyphs; + src: url(../../../../resources/fonts/vircadia_glyphs.ttf), + url(../../../../fonts/vircadia_glyphs.ttf), + url(../../../../interface/resources/fonts/vircadia_glyphs.ttf), + url(../fonts/vircadia_glyphs.ttf); +} + * { margin: 0; padding: 0; @@ -407,6 +415,14 @@ input[type=button].glyph, button.hifi-edit-button.glyph { padding: 0; } +input[type=button].vglyph, button.hifi-edit-button.vglyph { + font-family: Vircadia-Glyphs; + font-size: 20px; + text-transform: none; + min-width: 32px; + padding: 0; +} + input[type=button].red, button.hifi-edit-button.red { color: #fff; background-color: #94132e; @@ -417,6 +433,16 @@ input[type=button].blue, button.hifi-edit-button.blue { background-color: #1080b8; background: linear-gradient(#00b4ef 20%, #1080b8 100%); } +input[type=button].orange, button.hifi-edit-button.orange { + color: #fff; + background-color: #8f5100; + background: linear-gradient(#d97b00 20%, #8f5100 100%); +} +input[type=button].green, button.hifi-edit-button.green { + color: #fff; + background-color: #078a00; + background: linear-gradient(#00cc07 20%, #078a00 100%); +} input[type=button].white, button.hifi-edit-button.white { color: #121212; background-color: #afafaf; @@ -435,6 +461,14 @@ input[type=button].blue:enabled:hover, button.hifi-edit-button.blue:enabled:hove background: linear-gradient(#00b4ef, #00b4ef); border: none; } +input[type=button].orange:enabled:hover, button.hifi-edit-button.orange:enabled:hover { + background: linear-gradient(#d97b00, #d97b00); + border: none; +} +input[type=button].green:enabled:hover, button.hifi-edit-button.green:enabled:hover { + background: linear-gradient(#00cc07, #00cc07); + border: none; +} input[type=button].white:enabled:hover, button.hifi-edit-button.white:enabled:hover { background: linear-gradient(#fff, #fff); border: none; @@ -449,6 +483,12 @@ input[type=button].red:active, button.hifi-edit-button.red:active { input[type=button].blue:active, button.hifi-edit-button.blue:active { background: linear-gradient(#1080b8, #1080b8); } +input[type=button].orange:active, button.hifi-edit-button.orange:active { + background: linear-gradient(#8f5100, #8f5100); +} +input[type=button].green:active, button.hifi-edit-button.green:active { + background: linear-gradient(#078a00, #078a00); +} input[type=button].white:active, button.hifi-edit-button.white:active { background: linear-gradient(#afafaf, #afafaf); } From ab45a32feaea289eb59a7a5150ddb2a7e08159f9 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 26 Sep 2020 00:46:32 -0400 Subject: [PATCH 014/127] Add new button in HMD Add new button in HMD: - add undo and redo support - add HMD detection --- scripts/system/create/entityList/entityList.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index b68dcf80ba..644e68bec8 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -3,6 +3,7 @@ // entityList.js // // Copyright 2014 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -73,7 +74,7 @@ EntityListTool = function(shouldUseEditTabletApp) { that.setVisible = function(newVisible) { visible = newVisible; webView.setVisible(shouldUseEditTabletApp() && visible); - entityListWindow.setVisible(!shouldUseEditTabletApp() && visible); + entityListWindow.setVisible(!shouldUseEditTabletApp() && visible); }; that.isVisible = function() { @@ -163,6 +164,12 @@ EntityListTool = function(shouldUseEditTabletApp) { } that.sendUpdate = function() { + + emitJSONScriptEvent({ + "type": "confirmHMDstate", + "isHmd": HMD.active + }); + PROFILE('Script-sendUpdate', function() { var entities = []; @@ -302,6 +309,10 @@ EntityListTool = function(shouldUseEditTabletApp) { SelectionDisplay.toggleSpaceMode(); } else if (data.type === 'keyUpEvent') { keyUpEventFromUIWindow(data.keyUpEvent); + } else if (data.type === 'undo') { + undoHistory.undo(); + } else if (data.type === 'redo') { + undoHistory.redo(); } }; From 41ef2fafce7b74d82ed71e8c56d0ed0f61e0c298 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 26 Sep 2020 00:50:49 -0400 Subject: [PATCH 015/127] Add 6 new buttons 4 buttons for HMD enforce to be hidden by default. (Copy - Cut - Paste - Duplicate) 2 button (Undo and Redo) --- scripts/system/create/entityList/html/entityList.html | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index b7ff7cd4e4..c7c2d0e8bd 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -3,6 +3,7 @@ // // Created by Ryan Huffman on 19 Nov 2014 // Copyright 2014 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -30,6 +31,14 @@ + + + + +
+ + +
From d72f707862c12dd01f6f45832f17e68097581878 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 26 Sep 2020 00:55:16 -0400 Subject: [PATCH 016/127] Add the support for HMD buttons This adds the support for 6 new buttons: Copy-Cut-Paste-Duplicate-Undo-Redo It adds the automatic toggling of the HMD only buttons: Copy-Cut-Paste-Duplicate --- .../create/entityList/html/js/entityList.js | 49 ++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index b70e53ce15..b23b6b5403 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -2,6 +2,7 @@ // // Created by Ryan Huffman on 19 Nov 2014 // Copyright 2014 High Fidelity, Inc. +// Copyright 2020 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -198,6 +199,12 @@ let elEntityTable, elRefresh, elToggleLocked, elToggleVisible, + elHmdCopy, + elHmdCut, + elHmdPaste, + elHmdDuplicate, + elUndo, + elRedo, elDelete, elFilterTypeMultiselectBox, elFilterTypeText, @@ -233,7 +240,7 @@ const PROFILE = !ENABLE_PROFILING ? PROFILE_NOOP : function(name, fn, args) { console.log("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); }; -function loaded() { +function loaded() { openEventBridge(function() { elEntityTable = document.getElementById("entity-table"); elEntityTableHeader = document.getElementById("entity-table-header"); @@ -242,6 +249,12 @@ function loaded() { elRefresh = document.getElementById("refresh"); elToggleLocked = document.getElementById("locked"); elToggleVisible = document.getElementById("visible"); + elHmdCopy = document.getElementById("hmdcopy"); + elHmdCut = document.getElementById("hmdcut"); + elHmdPaste = document.getElementById("hmdpaste"); + elHmdDuplicate = document.getElementById("hmdduplicate"); + elUndo = document.getElementById("undo"); + elRedo = document.getElementById("redo"); elDelete = document.getElementById("delete"); elFilterTypeMultiselectBox = document.getElementById("filter-type-multiselect-box"); elFilterTypeText = document.getElementById("filter-type-text"); @@ -270,6 +283,24 @@ function loaded() { elExport.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'export'})); }; + elHmdCopy.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'copy' })); + }; + elHmdCut.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'cut' })); + }; + elHmdPaste.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'paste' })); + }; + elHmdDuplicate.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'duplicate' })); + }; + elUndo.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'undo' })); + }; + elRedo.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'redo' })); + }; elDelete.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); }; @@ -1364,10 +1395,12 @@ function loaded() { } })); }, false); - + if (window.EventBridge !== undefined) { EventBridge.scriptEventReceived.connect(function(data) { + data = JSON.parse(data); + if (data.type === "clearEntityList") { clearEntities(); } else if (data.type === "selectionUpdate") { @@ -1395,6 +1428,18 @@ function loaded() { removeEntities(data.ids); } else if (data.type === "setSpaceMode") { setSpaceMode(data.spaceMode); + } else if (data.type === "confirmHMDstate") { + if (data.isHmd) { + document.getElementById("hmdcopy").style.display = "inline"; + document.getElementById("hmdcut").style.display = "inline"; + document.getElementById("hmdpaste").style.display = "inline"; + document.getElementById("hmdduplicate").style.display = "inline"; + } else { + document.getElementById("hmdcopy").style.display = "none"; + document.getElementById("hmdcut").style.display = "none"; + document.getElementById("hmdpaste").style.display = "none"; + document.getElementById("hmdduplicate").style.display = "none"; + } } }); } From 6ecbbd258b8bce2368beb3bc21c40e4459015930 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 27 Sep 2020 15:22:00 -0400 Subject: [PATCH 017/127] Fix: Reset Landscape mode in HMD Fix: Reset Landscape mode in HMD In HMD, clicking on the button "Open this Domain's Asset server" is reverting the tablet to "portrait" mode This fix forces the mode to return to Landscape if from the Asset server we click on the "Properties" tab. --- scripts/system/create/edit.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index e01e761cb4..2fb38efad7 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -2339,6 +2339,10 @@ var PropertiesTool = function (opts) { }; function updateSelections(selectionUpdated, caller) { + if (HMD.active){ + webView.setLandscape(true); + } + if (blockPropertyUpdates) { return; } From 3f98cd49340b8a7b820332aa0899e35d39c2a9a7 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 27 Sep 2020 15:23:17 -0400 Subject: [PATCH 018/127] Fix: Reset Landscape mode in HMD Fix: Reset Landscape mode in HMD In HMD, clicking on the button "Open this Domain's Asset server" is reverting the tablet to "portrait" mode This fix forces the mode to return to Landscape if from the Asset server we click on the "List" tab. --- scripts/system/create/entityList/entityList.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 644e68bec8..3efa95dc07 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -164,7 +164,10 @@ EntityListTool = function(shouldUseEditTabletApp) { } that.sendUpdate = function() { - + var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + if (HMD.active){ + tablet.setLandscape(true); + } emitJSONScriptEvent({ "type": "confirmHMDstate", "isHmd": HMD.active From c2064eed894c39f94a91730b8b98fc00b5e06ffd Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 27 Sep 2020 23:49:48 -0400 Subject: [PATCH 019/127] Fix a bug about tablet stuck in Landscape Fix a bug about tablet stuck in Landscape when the create app was open in desktop and you put your VR Headset on, then next time you open the tablet it was in landscape mode. (because a refresh was happening after the landscape set to false at the closure) Now the condition is geared to deal with the situation. --- scripts/system/create/edit.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index 2fb38efad7..b051c19800 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -824,7 +824,7 @@ var toolBar = (function () { HMD.displayModeChanged.connect(function() { if (isActive) { - tablet.gotoHomeScreen(); + tablet.gotoHomeScreen(); } that.setActive(false); }); @@ -2339,8 +2339,12 @@ var PropertiesTool = function (opts) { }; function updateSelections(selectionUpdated, caller) { - if (HMD.active){ + if (HMD.active && visible){ webView.setLandscape(true); + } else { + if (!visible) { + webView.setLandscape(false); + } } if (blockPropertyUpdates) { From 5047cf338fbdd8f8e1db0338a47b370af59800fe Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 28 Sep 2020 00:36:42 -0400 Subject: [PATCH 020/127] HMD: Make the 2 buttons visible without scrolling HMD: Make the 2 buttons visible without scrolling In HMD, the 2 buttons: - Open This Domain's Asset Server - Import Entities (.json) were not visible without scrolling. people would not even notice their presence This fix adjust the spacing and the margin to have the entities button on 2 rows when the UI is in landscape mode this way the button are visible. --- scripts/system/create/qml/EditTabView.qml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/system/create/qml/EditTabView.qml b/scripts/system/create/qml/EditTabView.qml index a0cff70d50..53f6068424 100644 --- a/scripts/system/create/qml/EditTabView.qml +++ b/scripts/system/create/qml/EditTabView.qml @@ -55,18 +55,18 @@ TabBar { font.pixelSize: 14 font.bold: true anchors.top: parent.top - anchors.topMargin: 28 + anchors.topMargin: 30 anchors.left: parent.left - anchors.leftMargin: 28 + anchors.leftMargin: 30 } Flow { id: createEntitiesFlow - spacing: 35 + spacing: 20 anchors.right: parent.right - anchors.rightMargin: 55 + anchors.rightMargin: 30 anchors.left: parent.left - anchors.leftMargin: 55 + anchors.leftMargin: 30 anchors.top: parent.top anchors.topMargin: 70 @@ -186,9 +186,9 @@ TabBar { color: hifi.buttons.black colorScheme: hifi.colorSchemes.dark anchors.right: parent.right - anchors.rightMargin: 55 + anchors.rightMargin: 30 anchors.left: parent.left - anchors.leftMargin: 55 + anchors.leftMargin: 30 anchors.top: createEntitiesFlow.bottom anchors.topMargin: 35 onClicked: { @@ -205,9 +205,9 @@ TabBar { color: hifi.buttons.black colorScheme: hifi.colorSchemes.dark anchors.right: parent.right - anchors.rightMargin: 55 + anchors.rightMargin: 30 anchors.left: parent.left - anchors.leftMargin: 55 + anchors.leftMargin: 30 anchors.top: assetServerButton.bottom anchors.topMargin: 20 onClicked: { From e1e09546cfb3ee421a37e67787a7174280b37239 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 28 Sep 2020 23:07:16 -0400 Subject: [PATCH 021/127] Add HMD MultiSelect icon Add HMD MultiSelect icon --- interface/resources/fonts/vircadia_glyphs.ttf | Bin 3568 -> 4116 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/interface/resources/fonts/vircadia_glyphs.ttf b/interface/resources/fonts/vircadia_glyphs.ttf index fe69e4bf6fe3eab1bc86ca68e963419b3db6149b..33b794fb0d6408dfb816d4b8047a745c8edc2361 100644 GIT binary patch literal 4116 zcmd5+(vpct)nVsECW@mT1w>D%+kX;E7gn$sDfh-{= zV6wSega<@L9xxBFP{YNF$|VS5VNpI*MgNr_ep%&c{KdQ%}N zg_IATuI}^o>HmJt|DV$!00!=age&LguUY@qyT*SDBu@hv`1r+h^B6$}Nd6AM;3uwL z+1>H;t&0F{1h8f6u7y2?x!e>$Cjr{9ePREer6ou}^49>=?K=;BX6)6;+X3ljAb!D) zZ3{Q&wAU8_`~iT!W5>1yc{?2iCs{0h2&kvO@MT<(7$Wp zwmrBG#{ilJP+DBrwQYLh%mG0EHo*S6XZQXC_#<8hl1Bi{Lik2N`QU?{8`9uxM0iP1g}JJEXuV9$tG_IN1i+-8O&CLV+m4hv2S$JRt-61$b& zh77QK*z*7m_j`I1zHFtA`gi93GabO@8ys}G=La7VH}ntQNpE5OQH4> z)(W)r=cS*WYc26GzDFxyt0xM*AZ9XWF3V!>QnW=cO9m)_`9)Kwmv*;=oiYdRkbl@cMGQmdq2o05{kL9 zGjAFliN|PwcyUYfYn+~G7-pt;WR%6&Q1g;PH?EI0bs8OOjnZhbR%4&alzZ36@}OxX zBtEomUDK0d<`_NL?)@}bC=7ITW4_Zdh$OltSoz4s?`F5kpv3?tM*&iaV@GQ@Y@jkm4?{f$$s4VcNc#||#4$=*pKmKa@GOUdy;E0;>lHBsT&j1aBxfZlm=$Z;HZ z@Wnybah&{bG*OYXe)kr=luxD8sr-n>Ip^Als_W`YO`Xeerbx0JJE3w#kGBl*)oA51 zHdi(;#dSMf@Qhl`i?dwbwz+!h6+PaH>j_QM1mMaOx}DCQ&e`d-ojaXN+jJRMmD4I$ z6t13DRNi|dozBy-d^(-b5}K~|Zc=qp;|7x$5tTSskE^HFS%JOnTW?^A~`83wykNy_56ZMr4!HJ7K3yx29H4*LTW1Cff^gH>x?wr3g;_~VkQ0QTW`H$%L8{@-fqW9V;;}O*r1Z3xTH0k zjP6xev|FtfTk9k=c8}3;n9;CR;3{ zx{^e*X?DZrn6&Be3NP2+$LBE1wz5M=z(F13z_3-dGSzan-1Y5ndlqQQQmjd_xrga7 zQSSN;QPl(2xsY6DH#5B-)7o6MsjIyo(M7rHaW~a_E#-MB8cDf7Otn&@17oVXr}ze4 z)qBcqH_7fjl`z^P19a6BRJIERyZ5GDC|qw@^3qVC%4KK9UA+onE>b;D(= z{9jnuJI?Mn^TiKs=hJ8QiZ}ulI(GKVNr*+5pumYRgMxO1C0N)L;TV!Q9AOy-o{KPt zfj>o90paZkt024+;W&tv54Q;r@n~EFkse_kMCk|{Ao3z?f@mtLwrxMSb77xgnK_TAbUtlqCX!M*%k^F@@8ftM{k7PJeb|p%Lc2=npp6bX zA``FOwr~F}yBABHcBeDmw}09C^K4#!NVsy=hQ7Za{`p>;mu>vdk$L|g)cMT}YrmMm y8ir9v15J#eg;9)QMMz9bOJL!O(*Zc4OoAj&R5fA#$*1=qR%#Qy?AJ{UXz literal 3568 zcmd6qe{2-T7017C_I7XYcK2@2cenS`_TApyo_#iV$JyQk^P@Om2PmWwB(8A-=4u@5 zV6d?R1(GUhs9K5g2k8$*Q7YPshM)>5DM{5zNu;R!Q>y+EwJ4QRlvZk_@<%HrZK_0# za;|1?v5=dPM*XL=+S$*|y!Yn4cQdoIAOIR3hk$!WM(*4BASZKkDwcE zfc6rAjxX%4)TXaa9s+0#!2Zd@jrqWEq6pAUfOZ{hEY2@2K>)PN0OW(SCm)QS^t}%V zV}Nvdda7|Cfd{q&xBhb^OxZuLFJ$Ak56qEk2AZI1gy^00zNhBf#_g(f22U>;DNw zxCsD%_>MZU{EPtX5_^vO3&vYpI_#C^b%61>!7e$LZZE3SqT=iDI?Y^@oVHD_n85bY zdk_J3hP@2nZ0kvX#A>=V&aJ}zTrOi{V`JEa47R#Hyx?>>GPI9Rt7TIy0qksn!ymKr9UrS zz1>TaoW!;qCvQtQ)2kS5jP;Q{#%4JO{8j2X} zC>k;PvNd}k)NhHQe!DMQGukOSUW(PrRo*4 z`FpckHSLN?rEIm@YzryWt>~|s6O7|wG+#&@Ts!Om~c59U)`68A4r5`Kc9yplIUiK*jZ%J zkNYu$<3QMsbx_RkO06qqbW)ItWtOvw)Ltq zOOdw^^mB=P-6kt%@@6M9uF~fy#?zXUidKcb;SY7yCB{7AfJg8!#$t&~W>Cw7D5pw- zf9;xBBrl8cL@=spy*|doP?V5P#Wgfk-g2GkZUlmbswpU; zu2fa^iNSI}kF`Y`%rDqO$B7AIsv2rrosM`I^RJ1g1Hp1!_=^x|zRQ?Ws^oRi*AYtS z!GzwnGkjKLBrrix8h{sRsBD-$hafsJgi*}m37iHBIn&xe{q{QIYdsG(OQQTEsHrb7mZMG?XJx|*^r+F^@6dzJ{*+k#>*#s>FmhnQ%4_|TbRkW z(=q3*e#-{m&&2^VX9hgp{*7Ya02^< zMk~7wQ(dL4Gxq-Op8ZchwxeA3v9OuWMVZpo#psz;QfYcA^u(gl}8@X}R&vhn!bb4iN{9gtjR2*7q(Kn?e}>_HjdcbV^nZ@Vm^mjW(( z!DzS3G8pY~*#|}wF8je~%4G$N4!Nv?(NUK*F#3wi0WkWi%Q`yfw96p`=tX4sfe*(q zg9S{YfdiO90~0uiS)9Z?rm+YdpIMk}9GGcL9GpElKfMU-!W0hT7-rGH05rN zwYvJ#@~|T672_?t-Ad_yU*9>*mBV~;@;~OJyt1gyp2Hv@j{+f5(BlZw(h`_6 e)481C*dqvh#lUl$b?0m0&D~GG!?kYz-uX8H`r}vt From a394b427d4616a54a0672161bd2d814b3b77232f Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 28 Sep 2020 23:08:48 -0400 Subject: [PATCH 022/127] Add HMD MultiSelect button Add HMD MultiSelect button --- scripts/system/create/entityList/html/entityList.html | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index c7c2d0e8bd..fea3227951 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -31,6 +31,7 @@
+ From 427351bcd83493531c17c50f43c5b966f7584dfe Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Mon, 28 Sep 2020 23:13:18 -0400 Subject: [PATCH 023/127] Add a HMD MultiSelect button Add a HMD MultiSelect button Since it's impossible in HDM to do a multiple selection This adds a MultiSelect button (available in HMD only) When active, the selection in the list behaves like having CTRL pressed When inactive (default value) the selection in the list behaves as before (on item only) --- .../create/entityList/html/js/entityList.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index b23b6b5403..3f77d11e57 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -165,6 +165,7 @@ let selectedEntities = []; let entityList = null; // The ListView +let hmdMultiSelectMode = false; /** * @type EntityListContextMenu */ @@ -199,6 +200,7 @@ let elEntityTable, elRefresh, elToggleLocked, elToggleVisible, + elHmdMultiSelect, elHmdCopy, elHmdCut, elHmdPaste, @@ -249,6 +251,7 @@ function loaded() { elRefresh = document.getElementById("refresh"); elToggleLocked = document.getElementById("locked"); elToggleVisible = document.getElementById("visible"); + elHmdMultiSelect = document.getElementById("hmdmultiselect"); elHmdCopy = document.getElementById("hmdcopy"); elHmdCut = document.getElementById("hmdcut"); elHmdPaste = document.getElementById("hmdpaste"); @@ -283,6 +286,15 @@ function loaded() { elExport.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'export'})); }; + elHmdMultiSelect.onclick = function() { + if (hmdMultiSelectMode) { + elHmdMultiSelect.className = "vglyph"; + hmdMultiSelectMode = false; + } else { + elHmdMultiSelect.className = "white vglyph"; + hmdMultiSelectMode = true; + } + }; elHmdCopy.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'copy' })); }; @@ -569,7 +581,7 @@ function loaded() { let selection = [entityID]; let controlKey = window.navigator.platform.startsWith("Mac") ? clickEvent.metaKey : clickEvent.ctrlKey; - if (controlKey) { + if (controlKey || hmdMultiSelectMode) { let selectedIndex = selectedEntities.indexOf(entityID); if (selectedIndex >= 0) { selection = []; @@ -1430,11 +1442,13 @@ function loaded() { setSpaceMode(data.spaceMode); } else if (data.type === "confirmHMDstate") { if (data.isHmd) { + document.getElementById("hmdmultiselect").style.display = "inline"; document.getElementById("hmdcopy").style.display = "inline"; document.getElementById("hmdcut").style.display = "inline"; document.getElementById("hmdpaste").style.display = "inline"; document.getElementById("hmdduplicate").style.display = "inline"; } else { + document.getElementById("hmdmultiselect").style.display = "none"; document.getElementById("hmdcopy").style.display = "none"; document.getElementById("hmdcut").style.display = "none"; document.getElementById("hmdpaste").style.display = "none"; From 4f3f2a079e42574f1416d107cca26b274b25af7f Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 30 Sep 2020 00:37:59 -0400 Subject: [PATCH 024/127] Added Parent and Unparent icon Added Parent and Unparent icons: Link (K) / Unlink (L) --- interface/resources/fonts/vircadia_glyphs.ttf | Bin 4116 -> 4660 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/interface/resources/fonts/vircadia_glyphs.ttf b/interface/resources/fonts/vircadia_glyphs.ttf index 33b794fb0d6408dfb816d4b8047a745c8edc2361..b6a8c2e7ad4c30ed5d6d713f6590cae1f5a27f10 100644 GIT binary patch delta 2454 zcmb7GYit}>6+Y+QnL9H(@5j#Uu6JkGyX$?~-i_Dm9mjE0#$mVBC-&}}getfI z=4}A*4?fUnuDrSYZ2+7FfW_t2rL~?1DgglA2Eb20v~+rHV*@CFc@qG{hfY3n{MC!c z&jHXi0C{TV*wSZ{)-#s?;7jLPO91EqKyhXD%=tnZmjUo+0I=)i!^=zY zN3FL2=oA3tSC`JO!GjP17zKdbsioCpqr-R30BAP=$UoN}K79r)xD8;w3;=sJlS6>p z&wGFSj6VKvkm zrL>c|+)p@?t?ch<3fe$L!T!N&KlW#e1u|z9x-%T-Yif+L+~sP5a_V5Xi>0RBJ3md% z*7g`iA1bwg_j=))X62NYIZX{6_I!38w zQO9zr5PqLcbeaT$^&kO<+dIIiS#%FNkcQ@$t?B9>Cw zj%w`gQK(wP>hZBRg;e)@G%6P5jRDmt8eT1DGDK!LSih3Xy+>p!ktiUCj8NNh$&*O< zbh=_1IWHCkp+wUhyI}G>$0tf=T+{m!i9D5!YQ{|{60g@a!?oi}Bu0n#p2G=3`P7hU z4W(@!Q4SJmO|K`C)t{na;;G`c*!@DhMqL6%93MWqDT=D38kSaPNEkc68plh zh@Z>9$K%^6!?KK2Rc4Gaxhg7(_;y8MyhH@T*z2Jv`6Py6MH(f4CE=2k;E-T8d`wCc zRS2J#%AH;Sj1OYGd3V`9c*jf8dTdDn3*B3&@5z;m`FPyaWRd3)Igt}Y%a-N7zMds~ z=Io8v&U3t`>t?|(mA2nAntZglJyRcR4aF^8B~cGMAd$o5S;zz6h>9cq$T|@Pq8=cE zhC(YM!Uuw%M5BAtTTB=GWKDMjq#U6V62h3KJMlt(aF}Gzzjos+YPyxEk8Ed7UbiQd zu~YZnGf^!1SxptiXp5lG12(x#o&^_La4!J1Js^9Ft=Qj(qj>gR|Y=T}3OVZ|9SW zCJ}BYpAeW#sj7RF;)F#Oj&StwrA);H4)(zWStgHw3`rP(0HDt-m`6ftA)>KuqyMM9Ln)Zhara9Ex zl;sQ29+(1~JV##q5bTb-a62Cp?$Bln^rL|0y zQNQD-XVa^`uiB_(5@xHl+CoJc^~Y!YRo_<}qHbx|S6WArTw7UhEgNDfKkC=2zVEO4 zwMtGEZ7rjkt@YNaR`=b$;;26}?w|6jHD41QHKSUs_10=@WxaKj>KrggLoa!OyZ~{i zL1zfI!!FnlV0%Hi9wm^);b5d(M-2t$!UQ&OL>Tt`D1!zH&amfNC8lH0_L}W-9d!gB zccPH@0)e@n+n$}@F`wcqg?4ogcgzF-a@W@4&gD=j|P8EOftl;<=GI{HUc(z8Ew0 zg(>BdugOdt?fy0`NuzXqVM_A}8bA7$;?Q1W^BO^bLJ|6)1ZAi|6>88A12716XoSDf RGpL9E&@=Lf_mQg`{{cm^o+JPO delta 1882 zcmbVNYm8l06<%xYbM|?^?m73K`<(lJ%)NK++TosnsIv<0MAs=bujp)%8H zIyHqKy+n{7*dH~ASOi1RRHQ(FKuI7>FeVTJKh#7cCK!zW_@j1WOo(J|&6!ao8e`&K z$=Z9bwb#z~t+gLlN{{6RfB;~?gTP?l!oux0fA`^uUjbO306_YSyXO~R6g&Xyw*WA5 z>uuwcOK%@t0lF9qm;u160C?bd|Mcp$Yrp`kUjl%9{J#6Y-u%t<0|4wE z0Oh)+WBq#)+J`Fu@H+tLEG-=y^u^j z?G6Df_s_1vo$wR@&H_MgrN4Y^c4~7CKz|y5{ z^1~1Ei6AR1Qa%x!5Sm<7Wm)}p@B?A(U(Rt6|I*p^H@5r$BE%s(cFwm16p4{(dTvpb1XYYzoTzD)<9?oL zPA%=nbw#vVrX6#meNx%N#5a+cm})zbcE%MEwQfA!Fs)Xc&aBAR@G2syjq#E#DkDz9 zwi328=eg%eL_{RUv|vnL2-f5>`oZ_*dv|?|?#7>TCoO7;?%DOJUSJSzuki)S$5ItRL=-J1xvr*_E6Ki(x%D^C3W8-gPBB}q z&s;xSIaxa8cDqw<#4-^OJW%KmU4#q(8aUIyty>@sxMZR<9iD`4r`yABXA1YAJ-q54 zNteo+?zl3uL_&$1Ml8C}Z1?Emo9k!Lv?9@o={fgQ=}QN?i#HUq#cW!V0T`sfr3-Ws zV$g!?0r1}rWk_jey5m-h)sU>>kDwn5Rj{eX2M6zLkJkJG=VL~u5V`BbiCd05aqgy8 zOF@m|JSxzLe9xPRZgm&s{!ntJo$hfcpT{Kc~v zVKHIG9FxVKRVPpO8N*(LzIs?-ht7}16XDw>z&!NmC=Koh6=G0<34pRwbi86dnxE{r zj>or0Gmhj;SBm)pk2+p#DnHq&^1?WF{n!rl$*p6B4Kd|F* z8%J&b4ZChP(oI=j&3uIWhcEf98oI-mRHHST#{JJ>-W{Y;?(p|+D)nW@naEG7>Vr85 zpR**m^f>+KGjKEi54>{T$^Q?Cz0YGDK11g=zx7{`{wL5^Hc!3!hUqahgP%K@;LlDP PjX;lNw9o#Oy&HcAN#aXr From 2a0d508bb6232ee9806a2bf274247776afe8e801 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 30 Sep 2020 00:39:36 -0400 Subject: [PATCH 025/127] Add HmdMultiSelection on inworld Selection Add HmdMultiSelection on inworld Selection --- scripts/system/create/edit.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index b051c19800..739db3d411 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -104,6 +104,8 @@ var entityIconOverlayManager = new EntityIconOverlayManager(['Light', 'ParticleE } }); +var hmdMultiSelectMode = false; + var cameraManager = new CameraManager(); var grid = new Grid(); @@ -1131,7 +1133,11 @@ function handleOverlaySelectionToolUpdates(channel, message, sender) { var entity = entityIconOverlayManager.findEntity(data.overlayID); if (entity !== null) { - selectionManager.setSelections([entity], this); + if (hmdMultiSelectMode) { + selectionManager.addEntity(entity, true, this); + } else { + selectionManager.setSelections([entity], this); + } } } } From 94d030fb5cc403e9f1af75b3a511b22b98a1f4ef Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 30 Sep 2020 00:40:38 -0400 Subject: [PATCH 026/127] Add HmdMultiSelection on inworld Selection Add HmdMultiSelection on inworld Selection --- .../create/entitySelectionTool/entitySelectionTool.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index e224e28fca..9b5ba8c495 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -104,7 +104,11 @@ SelectionManager = (function() { if (wantDebug) { print("setting selection to " + messageParsed.entityID); } - that.setSelections([messageParsed.entityID], that); + if (hmdMultiSelectMode) { + that.addEntity(messageParsed.entityID, true, that); + } else { + that.setSelections([messageParsed.entityID], that); + } } } else if (messageParsed.method === "clearSelection") { if (!SelectionDisplay.triggered() || SelectionDisplay.triggeredHand === messageParsed.hand) { From 16324ace16ee52a66b9f6101f8be6856783577d1 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 30 Sep 2020 00:42:15 -0400 Subject: [PATCH 027/127] Add parent and unparent buttons Add parent and unparent buttons --- scripts/system/create/entityList/entityList.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 3efa95dc07..b611d006c5 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -15,6 +15,7 @@ var PROFILING_ENABLED = false; var profileIndent = ''; + const PROFILE_NOOP = function(_name, fn, args) { fn.apply(this, args); }; @@ -316,6 +317,12 @@ EntityListTool = function(shouldUseEditTabletApp) { undoHistory.undo(); } else if (data.type === 'redo') { undoHistory.redo(); + } else if (data.type === 'parent') { + parentSelectedEntities(); + } else if (data.type === 'unparent') { + unparentSelectedEntities(); + } else if (data.type === 'hmdMultiSelectMode') { + hmdMultiSelectMode = data.value; } }; From f1f58dcbd4db67f708e7e84a2c350b1199482fcf Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 30 Sep 2020 00:42:57 -0400 Subject: [PATCH 028/127] Add parent and unparent buttons Add parent and unparent buttons --- scripts/system/create/entityList/html/entityList.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index fea3227951..26b6ec6f00 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -35,7 +35,11 @@ - + +
+ + +
From ff39a03b5d98d3cae08c97a78eef8b3fb883e483 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 30 Sep 2020 00:44:07 -0400 Subject: [PATCH 029/127] Add parent and unparent buttons Add parent and unparent buttons --- .../system/create/entityList/html/js/entityList.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index 3f77d11e57..aa40d5286f 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -207,6 +207,8 @@ let elEntityTable, elHmdDuplicate, elUndo, elRedo, + elParent, + elUnparent, elDelete, elFilterTypeMultiselectBox, elFilterTypeText, @@ -258,6 +260,8 @@ function loaded() { elHmdDuplicate = document.getElementById("hmdduplicate"); elUndo = document.getElementById("undo"); elRedo = document.getElementById("redo"); + elParent = document.getElementById("parent"); + elUnparent = document.getElementById("unparent"); elDelete = document.getElementById("delete"); elFilterTypeMultiselectBox = document.getElementById("filter-type-multiselect-box"); elFilterTypeText = document.getElementById("filter-type-text"); @@ -294,6 +298,7 @@ function loaded() { elHmdMultiSelect.className = "white vglyph"; hmdMultiSelectMode = true; } + EventBridge.emitWebEvent(JSON.stringify({ type: 'hmdMultiSelectMode', value: hmdMultiSelectMode })); }; elHmdCopy.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'copy' })); @@ -307,12 +312,18 @@ function loaded() { elHmdDuplicate.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'duplicate' })); }; + elParent.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'parent' })); + }; + elUnparent.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'unparent' })); + }; elUndo.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'undo' })); }; elRedo.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'redo' })); - }; + }; elDelete.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); }; From 64ad0b5afbdf3be71cf183ae388f2f0894f07472 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 30 Sep 2020 23:54:06 -0400 Subject: [PATCH 030/127] Add audioFeedback mechanism Add an audio feedback mechanism to play confirmation or rejection sound on specific actions that are not visually detectable. - Duplicate (mainly for the HMD use case where the new entity is generated at the exact same position) - Parent and Unparent (because it not visually detectable in HMD if the action was successful or not) --- .../create/audioFeedback/audioFeedback.js | 34 ++++++++++++++++++ .../audioFeedback/sounds/confirmation.mp3 | Bin 0 -> 65200 bytes .../create/audioFeedback/sounds/rejection.mp3 | Bin 0 -> 14209 bytes 3 files changed, 34 insertions(+) create mode 100644 scripts/system/create/audioFeedback/audioFeedback.js create mode 100644 scripts/system/create/audioFeedback/sounds/confirmation.mp3 create mode 100644 scripts/system/create/audioFeedback/sounds/rejection.mp3 diff --git a/scripts/system/create/audioFeedback/audioFeedback.js b/scripts/system/create/audioFeedback/audioFeedback.js new file mode 100644 index 0000000000..de94fb6efa --- /dev/null +++ b/scripts/system/create/audioFeedback/audioFeedback.js @@ -0,0 +1,34 @@ +// +// audioFeedback.js +// +// Created by Alezia Kurdis on September 30, 2020. +// Copyright 2020 Vircadia contributors +// +// This script add audio feedback (confirmation and rejection) for user interactions that require one. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +audioFeedback = (function() { + var that = {}; + + var confirmationSound = SoundCache.getSound(Script.resolvePath("./sounds/confirmation.mp3")); + var rejectionSound = SoundCache.getSound(Script.resolvePath("./sounds/rejection.mp3")); + + that.confirmation = function() { //Play a confirmation sound + var injector = Audio.playSound(confirmationSound, { + "volume": 0.3, + "localOnly": true + }); + } + + that.rejection = function() { //Play a rejection sound + var injector = Audio.playSound(rejectionSound, { + "volume": 0.3, + "localOnly": true + }); + } + + return that; +})(); \ No newline at end of file diff --git a/scripts/system/create/audioFeedback/sounds/confirmation.mp3 b/scripts/system/create/audioFeedback/sounds/confirmation.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..39143fce4fb01095034778c697714b9e24362c2b GIT binary patch literal 65200 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
  • mnvrCQA(9cq9 z-^KP*Z70G%13eey5_WyCKYON}k7l1^-s8`0hpC~Q+T31TNECC7$fsvC$DXq#ZR090 zI&gPJV|Rt92W_|BnUC+oR1#=AhCO>RV}<- zTkZ6et||#-2yo*nT=$VkLD?=F4CI_`sG%=JnV*1G0mXVRmTnsx#MBh=TV;0QMB2dx zh000w_gaWlycEBs>ZNX&Ic|2P8QeyABJjYiRW9lsGenu!vQN-&I&kv1=i5#0>;(Xz z>$6A}fPkvUGcKvl(9jbT8hb!ruM38QkcI2TH zXU?Pe`Qy2>d|1+_wfzY7L6MyIh11SIl+e}I%uHNuVmAfmIty|DfOpv^JuR7#P9Kw+ z?YZ4jn8tcLkot-i#zG;WC!VbV|67tVjj`OzWc?pNdWWwFAI7lr?dq`#=CMdoz! z|IPOt7Gz!126u_IUne}Y*?o)0|0P)a z8QX^%=wAZ>(4(WxEZ|K_1ecANl7tmZMnlFZ!dfV)dOnlc$9l}=<;9s^t50hy<7jyn zadJXIC+9u4U}i{S3Kd*YpIHVf8`D>-Hww!qXC{aj3ZY~9pPd4|^29MSTljC`(4 zy(N+;g!G8(`CVUskm?cFX4{inV~k(CG9I-ayRl7AEZ={cxGc3|Ei9MBG?g}+N-4ZT z1WB*}FBqJT8Ag)&wTt%U^EX`F|7se%Iz3`}aR1|?Y@p}MHL z>ZuUxWao>7@^UjCUM|%rBM$%|SRCc`YMHaPN+MTEAY<(EXqpkaZ`LO`STX!go=aZV z_FO38S?yzU!Hvzb`=$2Lsw&{GumT@7OM1$dBt}CluxEquSfn5nR?+T?R;}Fa^!ohu z5x!Ii*>p8LLrr)bkhKCFQotn`gNJgp4I6svW#YE3L@v*WIe1?bjd%UrI}36&xX4pHex5V9*NbHk zU0BZBrm^QH)$ti-y>N$(hjqZ^m3ZTXu9O5T1)(KYs*>cbmGM)~pK)$8Wzvd;3>ac(+BKC=J{&F{s;+Q267ahsR#8#O z0EFP`L^Kb(LZ#M~dPvPHl#m_RD2H*eC03J4Iz1XElh)4SD%$mX&4gpDfJ^BYw`57h zZzPaJV6IZUEexTzY` zpF>}L5u0X7#jC|L@HZKe`(O0Gf7AT`L1@8(CB%6B^C1+2^f=DjCmz zzP^kA{Sad1_rJ?y+`86<9{FHJnUTF;IYm`~B2^nk4b$A^`P41Mo+5BYB4)Y0QgB;2 zGhc3OZicGWXdx2+Q*vnP*b!DHBLoHz#9}WVbS=D~#10sP0)n3oUfc?lEQ6#3IJ)6Z z6yTRSLDyc-7M}fZ@Jq@4^plHdn}03n)9<^Vb@>#(%*j73`TSb zuhV!rUl2ho31U88jgr}Al!;59A4^2mbUF_MD11mJXFk_plT1Tz%F(xZ0094d*wF@( z>86h0dI$>oBH=?EY_1S@(WB&~8LzW!eq!74a$xMJ>iIsjz#=knLg8`GBsm2Q>8<=q zF)|(~B|wlW9RA+=9dEO$2GPo^ly}eZH$OCf!V=JPOnSnY%N@82?d-W-$l@p^4^mB{ z9;DO;TrxJ||7`~M1Y!ZO-4}07;65zPK?>QZD>Gj-K_h(c&AX-edM>Sjw|z$sxtlB- zpN-XEsukDWmY&45-7-*jr-cRFg7dNZ)Knr0XZrLNsNF|HDo_YEjZ|fdnB&`c{FXZg zb>7EwsfHK>aD=_%B0f+ljk&V&a|c)_HQnp|N9N@|iHDI-HSa(A+0Rr-{O&&HBQ*6O z$kB^NVA>?%bfoFG`ldAaPL z+-8JQ>Ab&S=?fUCT!8 zJSzX9&^iiiAPkpu;3FG+2v-=2#JBz@$zh{s*>yc(l6?-b+WPj~ZZNqj!KN0Es1RID zU_9*5rr@*mX_3m_b}uu4BoS`zq2ZhpO&qKlQ;0Utl$mEsF=!jKj(WgkAQR~Ikrp9Z zc*x1aBcJb{RhIhi@2k{dZYr^q9y5jKW9EYMFPlC^eE9Gh^H@khvN&Qb!1*TS;!o}d zyyTrVI+)`5oB}{jR$p>sVbrPmN0P+^pm z-x~T#;H%XmM#%;$1-+c|y#9bJ-MaT@+f!_eJzYpX!H?ozMT2s+HGzT%e^` z*mv3oK=d(fS}T;5|A^(Ea{E&TZbPWFhtRjcnxmkeYgv)DuX_bfl?s^-yH0*_UdGQ( zh>?~;Xo?ppQUW`%YEU;P2O?O}jADwxiq!~-3K5;o13dnUBm7;FRRyvQ0s%kLWKFBc z_RN~NeUhi@Nw@9{yLbg6c~-J1F#qw?t9qX~D?H&d2el47?%q836xe96uIk>T~e2QbIeV>j^v+Y-0584@mzg z8&A$S@(D~hfKHOlQ^nE(HZM%asbYxZASY@RCC+Gvh&B!zMmAlZq|P#rgVYY1!Yq_!H$9whbzV zv9fKI1Y&&Y>e~Ro>Zi@)70^z+AzJ$sq_H~5i)F0mIEXf-9b{7S=O#5x&9$Yj$|4Ei z5!E`$v{!YF?qf{ChjUshmS4wNGNm zNeBf1@^NA9E*ukBfMB2x-j}NXURBSL+fZjt&!>z0bqD5H0@-?J3?icf_m_gesqIH- zATXpo53Q+XXmpFDY>DG%7!Bcffj%EBh|qcqqC8WQ>MaAxENj4@^Vn zT(G<)7~?bhcZYn|vv*=slTc6%M&EncaTIc96%4Qz_qxKskH;M| zLe?6CLo-E9Sm5Uz`PW>EoLo_!5Iw{G|0cdYbTmdp?zaMuORz zm-fA)`kJbj9;Uk3k;Z$Oao>CTYscG8RXqC3hbO&b70XSJlvb$IJ0yln!6#dtA$x?F?)xwmR>GApZ!{_@M_|s^vT$8<|p0KvbwrXJpS@s-E2lLJMtan1Q`T? zbZKq4w{SQ@a-Jpz(-KG5Yw4?4!Z_o+aWl9P+Cy>>61l3Mu3A0NX{SGy&@7>nL`82^ z7pKk6699GU_JgPsyH~6ioTo6i?BBC-aDau1XlVXj>RSHdGunuAfdb$>ewHNQ{npQ9 zK5&Mb4-CvfuGXjNNae7rTgYfB(NCr3?!F*cQ8jATrZeDvBrfyGb6lLXdF4Y*#G1;F zD%zioiI;Or>?VY!9PE7`{_{Dsj|IP{(f#~IyWDKhJzR;~ft7K~(?(?B_o)MAZ9~Xac7ZJnQ5jcZv0sN|cNCmWjkCCe05(YUjtm z)>5YI$8_S$++7?P*EiqW?rc0~_`Ph!ckftrUH56l)45{Vi{_%Yc>Fy6x_x!(!ftGt zehf8TCgFtSyyN6GvO*wBudtb)pr9sO1j0EPa`cbrs^n3yxw(jrM1)oLLnk2mC5Xht z;60~uhk9{lrycr~YB2$Y69bQJEY%3kZs@>Twjm9VUp!rpkIhDprqaZbKxi^z*@keS5O z4xw{k_ZlLW(J+59=e)KVzmEUg?45gy%S}#*!3U<$qIDObCd}+D@q%|)T!U-48r9xl zc8UhGG}$gP7i!XmNMx%+-DPF(-+CE}iOys%ydQRJN%~`P#1_TsJa_lBKKmm_(Zi8R z;mS_Y*XAP{VR#+py!Q?_9y-7hfW^l>VN8Z-eI^k_hjd*_ZT=<+XHZ1?{`qLCgk(+E zf2zf*P20-viHs?SCfZ?oQ!13ys$*JL43I=QHo(f8)K4bSGUdpTkW0^0#T=`1c&aBj zR339mWB$aHyoz334*?ZYgGf%$_UZANRv~v(2o1C9bGj!9_%(`oSQKmr*0P~9|yG~gGd~HVzzOIoyt2mSrtF2O{sKnQw zQq!Z-dX+1hxM&plIWKh5%&P3sgSU^~ex1x5+cymtmMyO#mAcu(t1(nA-@lWhniP==*=MrqsTKO)} z57{-cP}K8TsSI4oZ%Z$IkH4zUZIxoC`|o2kV$x>+hxK1|h`_*e+>?lA7p+>Tq&VnD zx=15gmuiHv&g1R4BuD(8x+NG4Lue(OyA2J|Rt_9djginN*W@*Ky8C^c%vW*|UoDIg z?gW?D3+Ix9%bzDjmAjn=B4=dSjzYv>(RD%nhNkqa!S(K_5C7ih-Z>^0U?!@|H|e(? zMDq_x@qy+{AQsT)GY plxIWKBa&a3W^Bn5YZV Date: Wed, 30 Sep 2020 23:55:46 -0400 Subject: [PATCH 031/127] Add audio feedback on Duplicate Add an audio feedback mechanism to play confirmation or rejection sound on specific actions that are not visually detectable. here for "Duplicate" (mainly for the HMD use case where the new entity is generated at the exact same position) --- .../create/entitySelectionTool/entitySelectionTool.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index 9b5ba8c495..51608a2d87 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -319,6 +319,7 @@ SelectionManager = (function() { that.addChildrenEntities(originalEntityID, entitiesToDuplicate, entityHostTypes[i].entityHostType); } + var hasItFailed = false; // duplicate entities from above and store their original to new entity mappings and children needing re-parenting for (var i = 0; i < entitiesToDuplicate.length; i++) { var originalEntityID = entitiesToDuplicate[i]; @@ -365,6 +366,8 @@ SelectionManager = (function() { duplicatedChildrenWithOldParents[newEntityID] = properties.parentID; } originalEntityToNewEntityID[originalEntityID] = newEntityID; + } else { + hasItFailed = true; } } @@ -383,6 +386,11 @@ SelectionManager = (function() { } }); + if (!hasItFailed) { + audioFeedback.confirmation(); + } else { + audioFeedback.rejection(); + } return duplicatedEntityIDs; }; From a7ca92fb9bd64071960094bdf10f7b45f4cd724b Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 30 Sep 2020 23:58:12 -0400 Subject: [PATCH 032/127] Add an audio feedback on Parent/Unparent Add an audio feedback mechanism to play confirmation or rejection sound on specific actions that are not visually detectable. Here for Parent and Unparent (because it not visually detectable in HMD if the action was successful or not) Fix also a bug where the HMD multiselection could stay active after we return in Desktop mode Now it is deactivated when the create window are closed. --- scripts/system/create/edit.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index 739db3d411..11d4dead86 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -34,7 +34,8 @@ Script.include([ "../libraries/entityIconOverlayManager.js", "../libraries/gridTool.js", "entityList/entityList.js", - "entitySelectionTool/entitySelectionTool.js" + "entitySelectionTool/entitySelectionTool.js", + "audioFeedback/audioFeedback.js" ]); var CreateWindow = Script.require('./modules/createWindow.js'); @@ -1700,6 +1701,7 @@ function unparentSelectedEntities() { var parentCheck = false; if (selectedEntities.length < 1) { + audioFeedback.rejection(); Window.notifyEditError("You must have an entity selected in order to unparent it."); return; } @@ -1712,12 +1714,14 @@ function unparentSelectedEntities() { return true; }); if (parentCheck) { + audioFeedback.confirmation(); if (selectedEntities.length > 1) { Window.notify("Entities unparented"); } else { Window.notify("Entity unparented"); } } else { + audioFeedback.rejection(); if (selectedEntities.length > 1) { Window.notify("Selected Entities have no parents"); } else { @@ -1725,6 +1729,7 @@ function unparentSelectedEntities() { } } } else { + audioFeedback.rejection(); Window.notifyEditError("You have nothing selected to unparent"); } } @@ -1732,6 +1737,7 @@ function parentSelectedEntities() { if (SelectionManager.hasSelection()) { var selectedEntities = selectionManager.selections; if (selectedEntities.length <= 1) { + audioFeedback.rejection(); Window.notifyEditError("You must have multiple entities selected in order to parent them"); return; } @@ -1748,11 +1754,14 @@ function parentSelectedEntities() { }); if (parentCheck) { + audioFeedback.confirmation(); Window.notify("Entities parented"); } else { + audioFeedback.rejection(); Window.notify("Entities are already parented to last"); } } else { + audioFeedback.rejection(); Window.notifyEditError("You have nothing selected to parent"); } } @@ -2349,6 +2358,7 @@ var PropertiesTool = function (opts) { webView.setLandscape(true); } else { if (!visible) { + hmdMultiSelectMode = false; webView.setLandscape(false); } } From 6b7b1c5040c2d9ce6f73baa5296cd83589c704b3 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 2 Oct 2020 16:23:00 +1300 Subject: [PATCH 033/127] Fix handling of missing glTF blendshape target meshes --- libraries/fbx/src/GLTFSerializer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/fbx/src/GLTFSerializer.cpp b/libraries/fbx/src/GLTFSerializer.cpp index 3a0271945b..4f730fe03e 100755 --- a/libraries/fbx/src/GLTFSerializer.cpp +++ b/libraries/fbx/src/GLTFSerializer.cpp @@ -1586,12 +1586,16 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash& int targetIndex = weightedIndex; hfmModel.blendshapeChannelNames.push_back("target_" + QString::number(weightedIndex)); - if (!names.isEmpty() && names.contains(keys[weightedIndex])) { + if (!names.isEmpty()) { targetIndex = names.indexOf(keys[weightedIndex]); + if (targetIndex == -1) { + continue; // Ignore blendshape targets not present in glTF file. + } indexFromMapping = values[weightedIndex].first; weight = values[weightedIndex].second; hfmModel.blendshapeChannelNames[weightedIndex] = keys[weightedIndex]; } + HFMBlendshape& blendshape = mesh.blendshapes[indexFromMapping]; auto target = primitive.targets[targetIndex]; From 61d4fb2ad104fdefd9a6ea0f25c3991fd7b80e65 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Mon, 5 Oct 2020 20:40:58 -0400 Subject: [PATCH 034/127] First run script. --- scripts/defaultScripts.js | 3 ++- scripts/system/onFirstRun.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 scripts/system/onFirstRun.js diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js index d9a86dbd91..71fb644528 100644 --- a/scripts/defaultScripts.js +++ b/scripts/defaultScripts.js @@ -35,7 +35,8 @@ var DEFAULT_SCRIPTS_COMBINED = [ "system/audioMuteOverlay.js", "system/inspect.js", "system/keyboardShortcuts/keyboardShortcuts.js", - "system/checkForUpdates.js" + "system/checkForUpdates.js", + "system/onFirstRun.js" ]; var DEFAULT_SCRIPTS_SEPARATE = [ "system/controllers/controllerScripts.js", diff --git a/scripts/system/onFirstRun.js b/scripts/system/onFirstRun.js new file mode 100644 index 0000000000..b2ab89a932 --- /dev/null +++ b/scripts/system/onFirstRun.js @@ -0,0 +1,28 @@ +'use strict'; + +// +// onFirstRun.js +// +// Created by Kalila L. on Oct 5 2020. +// Copyright 2020 Vircadia contributors. +// +// This script triggers on first run to perform first party +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function() { // BEGIN LOCAL_SCOPE + var SETTING_TO_CHECK = 'firstRun'; + var DEFAULT_NAME = 'anonymous'; + + if (Settings.getValue('firstRun', false)) { + var selectedDisplayName = Window.prompt('Enter a display name.', MyAvatar.displayName); + + if (selectedDisplayName === '') { + MyAvatar.displayName = DEFAULT_NAME; + } else { + MyAvatar.displayName = selectedDisplayName; + } + } +}()); \ No newline at end of file From 3882aad55194c7d76bee21da1a413f9a2ff3f342 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 6 Oct 2020 21:48:23 -0400 Subject: [PATCH 035/127] Minor code adjustments Minor code adjustments --- scripts/system/create/audioFeedback/audioFeedback.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/audioFeedback/audioFeedback.js b/scripts/system/create/audioFeedback/audioFeedback.js index de94fb6efa..f1900d5716 100644 --- a/scripts/system/create/audioFeedback/audioFeedback.js +++ b/scripts/system/create/audioFeedback/audioFeedback.js @@ -2,7 +2,7 @@ // audioFeedback.js // // Created by Alezia Kurdis on September 30, 2020. -// Copyright 2020 Vircadia contributors +// Copyright 2020 Vircadia contributors. // // This script add audio feedback (confirmation and rejection) for user interactions that require one. // @@ -31,4 +31,4 @@ audioFeedback = (function() { } return that; -})(); \ No newline at end of file +})(); From e273c920a464f97221cce51aee5875c943096f1b Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 6 Oct 2020 21:50:24 -0400 Subject: [PATCH 036/127] Minor Code Adjustment Minor Code Adjustment --- scripts/system/create/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index 11d4dead86..69cb04e9e5 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -2354,7 +2354,7 @@ var PropertiesTool = function (opts) { }; function updateSelections(selectionUpdated, caller) { - if (HMD.active && visible){ + if (HMD.active && visible) { webView.setLandscape(true); } else { if (!visible) { From 7c9808de409d8aa8cfc31635cf6f71f85a4f53fb Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 6 Oct 2020 21:52:40 -0400 Subject: [PATCH 037/127] Minor Code Adjustment Minor Code Adjustment --- scripts/system/create/entityList/entityList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index b611d006c5..4b8163968d 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -166,7 +166,7 @@ EntityListTool = function(shouldUseEditTabletApp) { that.sendUpdate = function() { var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); - if (HMD.active){ + if (HMD.active) { tablet.setLandscape(true); } emitJSONScriptEvent({ From 37d694afa0165f7ce5aa15aa2597929a585c528f Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 6 Oct 2020 22:05:39 -0400 Subject: [PATCH 038/127] Minor Code Adjustments Minor Code Adjustments --- .../create/entitySelectionTool/entitySelectionTool.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index 51608a2d87..007f253943 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -319,7 +319,7 @@ SelectionManager = (function() { that.addChildrenEntities(originalEntityID, entitiesToDuplicate, entityHostTypes[i].entityHostType); } - var hasItFailed = false; + var duplicateInterrupted = false; // duplicate entities from above and store their original to new entity mappings and children needing re-parenting for (var i = 0; i < entitiesToDuplicate.length; i++) { var originalEntityID = entitiesToDuplicate[i]; @@ -367,7 +367,7 @@ SelectionManager = (function() { } originalEntityToNewEntityID[originalEntityID] = newEntityID; } else { - hasItFailed = true; + duplicateInterrupted = true; } } @@ -386,10 +386,10 @@ SelectionManager = (function() { } }); - if (!hasItFailed) { - audioFeedback.confirmation(); - } else { + if (duplicateInterrupted) { audioFeedback.rejection(); + } else { + audioFeedback.confirmation(); } return duplicatedEntityIDs; }; From dc554bb8c684c8b7a3907fd5053f3a13fc7b2769 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Wed, 7 Oct 2020 19:37:10 -0400 Subject: [PATCH 039/127] Update some descriptions. --- domain-server/src/DomainServer.cpp | 2 +- interface/src/main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index c3f827234a..187cd340ba 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -340,7 +340,7 @@ DomainServer::DomainServer(int argc, char* argv[]) : void DomainServer::parseCommandLine(int argc, char* argv[]) { QCommandLineParser parser; - parser.setApplicationDescription("High Fidelity Domain Server"); + parser.setApplicationDescription("Vircadia Domain Server"); const QCommandLineOption versionOption = parser.addVersionOption(); const QCommandLineOption helpOption = parser.addHelpOption(); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index bdbafbaeb8..c14d22bdbb 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -81,7 +81,7 @@ int main(int argc, const char* argv[]) { QCommandLineOption noUpdaterOption("no-updater", "Do not show auto-updater"); QCommandLineOption checkMinSpecOption("checkMinSpec", "Check if machine meets minimum specifications"); QCommandLineOption runServerOption("runServer", "Whether to run the server"); - QCommandLineOption serverContentPathOption("serverContentPath", "Where to find server content", "serverContentPath"); + QCommandLineOption serverContentPathOption("serverContentPath", "Where to find server content ", "serverContentPath"); QCommandLineOption allowMultipleInstancesOption("allowMultipleInstances", "Allow multiple instances to run"); QCommandLineOption overrideAppLocalDataPathOption("cache", "set test cache ", "dir"); QCommandLineOption overrideScriptsPathOption(SCRIPTS_SWITCH, "set scripts ", "path"); From 46ddde0bd6384cf5eaa3982b64be39b190f69739 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Wed, 7 Oct 2020 19:42:51 -0400 Subject: [PATCH 040/127] hifi-production tutorials -> vircadia-content --- scripts/developer/tests/scriptableResource/lib.js | 2 +- scripts/tutorials/butterflies.js | 4 ++-- scripts/tutorials/createCow.js | 6 +++--- scripts/tutorials/createDice.js | 12 ++++++------ scripts/tutorials/createFlashlight.js | 4 ++-- scripts/tutorials/createGolfClub.js | 6 +++--- scripts/tutorials/createPictureFrame.js | 4 ++-- scripts/tutorials/createPingPongGun.js | 6 +++--- scripts/tutorials/createPistol.js | 6 +++--- scripts/tutorials/createSoundMaker.js | 4 ++-- scripts/tutorials/entity_scripts/cow.js | 2 +- scripts/tutorials/entity_scripts/golfClub.js | 2 +- scripts/tutorials/entity_scripts/pingPongGun.js | 2 +- scripts/tutorials/entity_scripts/pistol.js | 10 +++++----- scripts/tutorials/entity_scripts/soundMaker.js | 2 +- scripts/tutorials/giveAvatarMagicFingers.js | 2 +- scripts/tutorials/makeAvatarClap.js | 2 +- 17 files changed, 38 insertions(+), 38 deletions(-) diff --git a/scripts/developer/tests/scriptableResource/lib.js b/scripts/developer/tests/scriptableResource/lib.js index a8773bbabb..b874ce4e07 100644 --- a/scripts/developer/tests/scriptableResource/lib.js +++ b/scripts/developer/tests/scriptableResource/lib.js @@ -16,7 +16,7 @@ var FRAME_RATE = 30; // 30 default function getFrame(callback) { // A model exported from blender with a texture named 'Picture' on one face. - var FRAME_URL = "http://hifi-production.s3.amazonaws.com/tutorials/pictureFrame/finalFrame.fbx"; + var FRAME_URL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/pictureFrame/finalFrame.fbx"; var model = ModelCache.prefetch(FRAME_URL); if (model.state === Resource.State.FINISHED) { diff --git a/scripts/tutorials/butterflies.js b/scripts/tutorials/butterflies.js index 9d8d1de52c..5876b04240 100644 --- a/scripts/tutorials/butterflies.js +++ b/scripts/tutorials/butterflies.js @@ -86,13 +86,13 @@ function addButterfly() { dimensions: dimensions, color: color, animation: { - url: "http://hifi-production.s3.amazonaws.com/tutorials/butterflies/butterfly.fbx", + url: "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/butterflies/butterfly.fbx", fps: newFrameRate, loop: true, running: true, startAutomatically:false }, - modelURL: "http://hifi-production.s3.amazonaws.com/tutorials/butterflies/butterfly.fbx" + modelURL: "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/butterflies/butterfly.fbx" }; butterflies.push(Entities.addEntity(properties)); } diff --git a/scripts/tutorials/createCow.js b/scripts/tutorials/createCow.js index 0f034ecefa..c23e2eab1f 100644 --- a/scripts/tutorials/createCow.js +++ b/scripts/tutorials/createCow.js @@ -9,9 +9,9 @@ // // references to our assets. entity scripts need to be served from somewhere that is publically accessible -- so http(s) or atp -var SCRIPT_URL ="http://hifi-production.s3.amazonaws.com/tutorials/entity_scripts/cow.js"; -var MODEL_URL = "http://hifi-production.s3.amazonaws.com/tutorials/cow/cow.fbx"; -var ANIMATION_URL = 'http://hifi-production.s3.amazonaws.com/tutorials/cow/cow.fbx'; +var SCRIPT_URL ="https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/entity_scripts/cow.js"; +var MODEL_URL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/cow/cow.fbx"; +var ANIMATION_URL = 'https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/cow/cow.fbx'; // this part of the code describes how to center the entity in front of your avatar when it is created. var orientation = MyAvatar.orientation; diff --git a/scripts/tutorials/createDice.js b/scripts/tutorials/createDice.js index 46ad0172aa..7b88686c91 100644 --- a/scripts/tutorials/createDice.js +++ b/scripts/tutorials/createDice.js @@ -23,7 +23,7 @@ var DIE_SIZE = 0.20; var madeSound = true; // Set false at start of throw to look for collision -SoundCache.getSound("http://hifi-production.s3.amazonaws.com/tutorials/dice/diceCollide.wav"); +SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/dice/diceCollide.wav"); var INSUFFICIENT_PERMISSIONS_ERROR_MSG = "You do not have the necessary permissions to create new objects." @@ -45,7 +45,7 @@ var toolBar = new ToolBar(0, 0, ToolBar.HORIZONTAL, "highfidelity.toolbars-dice" var offButton = toolBar.addOverlay("image", { width: BUTTON_SIZE, height: BUTTON_SIZE, - imageURL: "http://hifi-production.s3.amazonaws.com/tutorials/dice/close.png", + imageURL: "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/dice/close.png", alpha: 1 }); @@ -54,11 +54,11 @@ var deleteButton = toolBar.addOverlay("image", { y: screenSize.y - (BUTTON_SIZE + PADDING)+BOTTOM_PADDING, width: BUTTON_SIZE, height: BUTTON_SIZE, - imageURL: "http://hifi-production.s3.amazonaws.com/tutorials/dice/delete.png", + imageURL: "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/dice/delete.png", alpha: 1 }); -var diceIconURL = "http://hifi-production.s3.amazonaws.com/tutorials/dice/dice.png" +var diceIconURL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/dice/dice.png" var diceButton = toolBar.addOverlay("image", { x: screenSize.x / 2 + PADDING, y: screenSize.y - (BUTTON_SIZE + PADDING)+BOTTOM_PADDING, @@ -82,7 +82,7 @@ function shootDice(position, velocity) { for (var i = 0; i < NUMBER_OF_DICE; i++) { dice.push(Entities.addEntity({ type: "Model", - modelURL: "http://hifi-production.s3.amazonaws.com/tutorials/dice/goldDie.fbx", + modelURL: "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/dice/goldDie.fbx", position: position, velocity: velocity, rotation: Quat.fromPitchYawRollDegrees(Math.random() * 360, Math.random() * 360, Math.random() * 360), @@ -99,7 +99,7 @@ function shootDice(position, velocity) { lifetime: LIFETIME, shapeType: "box", dynamic: true, - collisionSoundURL: "http://hifi-production.s3.amazonaws.com/tutorials/dice/diceCollide.wav" + collisionSoundURL: "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/dice/diceCollide.wav" })); position = Vec3.sum(position, Vec3.multiply(DIE_SIZE, Vec3.normalize(Quat.getRight(Camera.getOrientation())))); } diff --git a/scripts/tutorials/createFlashlight.js b/scripts/tutorials/createFlashlight.js index 329be56af7..5bbbc52f24 100644 --- a/scripts/tutorials/createFlashlight.js +++ b/scripts/tutorials/createFlashlight.js @@ -9,8 +9,8 @@ // -var SCRIPT_URL = "http://hifi-production.s3.amazonaws.com/tutorials/entity_scripts/flashlight.js"; -var MODEL_URL = "http://hifi-production.s3.amazonaws.com/tutorials/flashlight/flashlight2.fbx"; +var SCRIPT_URL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/entity_scripts/flashlight.js"; +var MODEL_URL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/flashlight/flashlight2.fbx"; var center = Vec3.sum(Vec3.sum(MyAvatar.position, { x: 0, diff --git a/scripts/tutorials/createGolfClub.js b/scripts/tutorials/createGolfClub.js index 4135b6680d..fb2466e0f4 100644 --- a/scripts/tutorials/createGolfClub.js +++ b/scripts/tutorials/createGolfClub.js @@ -17,8 +17,8 @@ orientation.x = 0; orientation = Quat.fromVec3Degrees(orientation); var center = Vec3.sum(MyAvatar.getHeadPosition(), Vec3.multiply(2, Quat.getForward(orientation))); -var CLUB_MODEL = "http://hifi-production.s3.amazonaws.com/tutorials/golfClub/putter_VR.fbx"; -var CLUB_COLLISION_HULL = "http://hifi-production.s3.amazonaws.com/tutorials/golfClub/club_collision_hull.obj"; +var CLUB_MODEL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/golfClub/putter_VR.fbx"; +var CLUB_COLLISION_HULL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/golfClub/club_collision_hull.obj"; var CLUB_DIMENSIONS = { "x": 0.043093059211969376, @@ -34,7 +34,7 @@ var CLUB_ROTATION = { }; -var SCRIPT_URL = "http://hifi-production.s3.amazonaws.com/tutorials/entity_scripts/golfClub.js"; +var SCRIPT_URL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/entity_scripts/golfClub.js"; var golfClubProperties = { position: center, lifetime: 3600, diff --git a/scripts/tutorials/createPictureFrame.js b/scripts/tutorials/createPictureFrame.js index 873b604bfa..ea1e5ae7de 100644 --- a/scripts/tutorials/createPictureFrame.js +++ b/scripts/tutorials/createPictureFrame.js @@ -17,7 +17,7 @@ var center = Vec3.sum(Vec3.sum(MyAvatar.position, { }), Vec3.multiply(1, Quat.getForward(Camera.getOrientation()))); // this is just a model exported from blender with a texture named 'Picture' on one face. also made it emissive so it doesn't require lighting. -var MODEL_URL = "http://hifi-production.s3.amazonaws.com/tutorials/pictureFrame/finalFrame.fbx"; +var MODEL_URL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/pictureFrame/finalFrame.fbx"; //this is where we are going to get our image from. the stuff at the end is our API key. var NASA_API_ENDPOINT = "https://api.nasa.gov/planetary/apod?api_key=XNmgPJvVK8hGroZHB19PaQtlqKZk4q8GorWViuND"; @@ -59,7 +59,7 @@ function makePictureFrame() { } var pictureFrame = Entities.addEntity(pictureFrameProperties); - var OUTER_FRAME_MODEL_URL = "http://hifi-production.s3.amazonaws.com/tutorials/pictureFrame/outer_frame.fbx"; + var OUTER_FRAME_MODEL_URL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/pictureFrame/outer_frame.fbx"; var outerFrameProps = { name: "Tutorial Outer Frame", type: "Model", diff --git a/scripts/tutorials/createPingPongGun.js b/scripts/tutorials/createPingPongGun.js index 927738f29e..b5e397d5ed 100644 --- a/scripts/tutorials/createPingPongGun.js +++ b/scripts/tutorials/createPingPongGun.js @@ -7,9 +7,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var SCRIPT_URL = "http://hifi-production.s3.amazonaws.com/tutorials/entity_scripts/pingPongGun.js"; -var MODEL_URL = 'http://hifi-production.s3.amazonaws.com/tutorials/pingPongGun/Pingpong-Gun-New.fbx'; -var COLLISION_HULL_URL = 'http://hifi-production.s3.amazonaws.com/tutorials/pingPongGun/Pingpong-Gun-New.obj'; +var SCRIPT_URL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/entity_scripts/pingPongGun.js"; +var MODEL_URL = 'https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/pingPongGun/Pingpong-Gun-New.fbx'; +var COLLISION_HULL_URL = 'https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/pingPongGun/Pingpong-Gun-New.obj'; var center = Vec3.sum(Vec3.sum(MyAvatar.position, { x: 0, y: 0.5, diff --git a/scripts/tutorials/createPistol.js b/scripts/tutorials/createPistol.js index 0912645c35..d54621a633 100644 --- a/scripts/tutorials/createPistol.js +++ b/scripts/tutorials/createPistol.js @@ -7,9 +7,9 @@ // var center = Vec3.sum(MyAvatar.position, Vec3.multiply(1.5, Quat.getForward(Camera.getOrientation()))); -var SCRIPT_URL = "http://hifi-production.s3.amazonaws.com/tutorials/entity_scripts/pistol.js"; -var MODEL_URL = "http://hifi-production.s3.amazonaws.com/tutorials/pistol/gun.fbx"; -var COLLISION_SOUND_URL = 'http://hifi-production.s3.amazonaws.com/tutorials/pistol/drop.wav' +var SCRIPT_URL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/entity_scripts/pistol.js"; +var MODEL_URL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/pistol/gun.fbx"; +var COLLISION_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/pistol/drop.wav' var pistolProperties = { type: 'Model', diff --git a/scripts/tutorials/createSoundMaker.js b/scripts/tutorials/createSoundMaker.js index 2d86864982..365dd266fd 100644 --- a/scripts/tutorials/createSoundMaker.js +++ b/scripts/tutorials/createSoundMaker.js @@ -6,8 +6,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var SCRIPT_URL = "http://hifi-production.s3.amazonaws.com/tutorials/entity_scripts/soundMaker.js"; -var MODEL_URL = "http://hifi-production.s3.amazonaws.com/tutorials/soundMaker/Front-Desk-Bell.fbx"; +var SCRIPT_URL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/entity_scripts/soundMaker.js"; +var MODEL_URL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/soundMaker/Front-Desk-Bell.fbx"; var center = Vec3.sum(Vec3.sum(MyAvatar.position, { x: 0, diff --git a/scripts/tutorials/entity_scripts/cow.js b/scripts/tutorials/entity_scripts/cow.js index 117864beb6..992ad3c9d1 100644 --- a/scripts/tutorials/entity_scripts/cow.js +++ b/scripts/tutorials/entity_scripts/cow.js @@ -19,7 +19,7 @@ //set our id so other methods can get it. _this.entityID = entityID; //load the mooing sound - _this.mooSound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/tutorials/cow/moo.wav") + _this.mooSound = SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/cow/moo.wav") _this.mooSoundOptions = { volume: 0.7, loop: false diff --git a/scripts/tutorials/entity_scripts/golfClub.js b/scripts/tutorials/entity_scripts/golfClub.js index 6342838aa4..0d0426c87b 100644 --- a/scripts/tutorials/entity_scripts/golfClub.js +++ b/scripts/tutorials/entity_scripts/golfClub.js @@ -13,7 +13,7 @@ (function() { var ball = null; - var collisionSoundURL = "http://hifi-production.s3.amazonaws.com/tutorials/golfClub/collision1.wav"; + var collisionSoundURL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/golfClub/collision1.wav"; var triggerState = false; var BALL_GRAVITY = -9.8; var BALL_START_VELOCITY = 0.1; diff --git a/scripts/tutorials/entity_scripts/pingPongGun.js b/scripts/tutorials/entity_scripts/pingPongGun.js index 5ba4b15ea7..084e3287ed 100644 --- a/scripts/tutorials/entity_scripts/pingPongGun.js +++ b/scripts/tutorials/entity_scripts/pingPongGun.js @@ -12,7 +12,7 @@ (function() { var _this = this; - var SHOOTING_SOUND_URL = 'http://hifi-production.s3.amazonaws.com/tutorials/pingPongGun/pong_sound.wav'; + var SHOOTING_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/pingPongGun/pong_sound.wav'; function PingPongGun() { return; diff --git a/scripts/tutorials/entity_scripts/pistol.js b/scripts/tutorials/entity_scripts/pistol.js index 62517f486d..52985bb116 100644 --- a/scripts/tutorials/entity_scripts/pistol.js +++ b/scripts/tutorials/entity_scripts/pistol.js @@ -30,8 +30,8 @@ this.forceMultiplier = 1; this.laserLength = 100; - this.fireSound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/tutorials/pistol/GUN-SHOT2.raw"); - this.ricochetSound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/tutorials/pistol/Ricochet.L.wav"); + this.fireSound = SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/pistol/GUN-SHOT2.raw"); + this.ricochetSound = SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/pistol/Ricochet.L.wav"); this.playRichochetSoundChance = 0.1; this.fireVolume = 0.2; this.bulletForce = 10; @@ -220,7 +220,7 @@ "alphaStart": 0, "alphaFinish": 0, "additiveBlending": true, - "textures": "http://hifi-production.s3.amazonaws.com/tutorials/pistol/star.png" + "textures": "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/pistol/star.png" }); Script.setTimeout(function() { @@ -270,7 +270,7 @@ "alphaStart": 0, "alphaFinish": 0, "additiveBlending": 0, - "textures": "http://hifi-production.s3.amazonaws.com/tutorials/pistol/smoke.png" + "textures": "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/pistol/smoke.png" }); Script.setTimeout(function() { Entities.editEntity(smoke, { @@ -333,7 +333,7 @@ "alphaStart": 0, "alphaFinish": 0, "additiveBlending": true, - "textures": "http://hifi-production.s3.amazonaws.com/tutorials/pistol/star.png" + "textures": "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/pistol/star.png" }); Script.setTimeout(function() { Entities.editEntity(flash, { diff --git a/scripts/tutorials/entity_scripts/soundMaker.js b/scripts/tutorials/entity_scripts/soundMaker.js index 950334aee6..f4fb745b7a 100644 --- a/scripts/tutorials/entity_scripts/soundMaker.js +++ b/scripts/tutorials/entity_scripts/soundMaker.js @@ -8,7 +8,7 @@ (function(){ - var soundURL ='http://hifi-production.s3.amazonaws.com/tutorials/soundMaker/bell.wav'; + var soundURL ='https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/soundMaker/bell.wav'; var ringSound; this.preload = function(entityID) { diff --git a/scripts/tutorials/giveAvatarMagicFingers.js b/scripts/tutorials/giveAvatarMagicFingers.js index 23902bdd94..e6fc8ebb0a 100644 --- a/scripts/tutorials/giveAvatarMagicFingers.js +++ b/scripts/tutorials/giveAvatarMagicFingers.js @@ -76,7 +76,7 @@ var particleProperties = { alphaStart: 1, alphaFinish: 0, emitterShouldTrail: true, - textures: 'http://hifi-production.s3.amazonaws.com/tutorials/particleFingers/smoke.png', + textures: 'https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/particleFingers/smoke.png', lifetime: 3600 }; diff --git a/scripts/tutorials/makeAvatarClap.js b/scripts/tutorials/makeAvatarClap.js index c51e7a8d3a..2a593ed3c2 100644 --- a/scripts/tutorials/makeAvatarClap.js +++ b/scripts/tutorials/makeAvatarClap.js @@ -8,7 +8,7 @@ // // An animation of the avatar clapping its hands while standing -var ANIM_URL = "http://hifi-production.s3.amazonaws.com/tutorials/avatarAnimation/clap.fbx"; +var ANIM_URL = "https://cdn-1.vircadia.com/us-e-1/Developer/Tutorials/avatarAnimation/clap.fbx"; // overrideRoleAnimation only replaces a single animation at a time. the rest of the motion is driven normally // @animationRole - name of animation From 60b31000d75dd824329342001c137d8d80a000b5 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Wed, 7 Oct 2020 19:44:14 -0400 Subject: [PATCH 041/127] hifi-production DomainContent -> vircadia-content --- .../entities/src/EntityItemProperties.cpp | 2 +- .../CellScience/backgroundMusicAC.js | 8 +- .../Toybox/AC_scripts/toybox_sounds.js | 14 ++-- .../Toybox/basketball/createHoop.js | 4 +- .../Toybox/basketball/createRack.js | 8 +- .../basketball/createSingleBasketball.js | 4 +- .../Toybox/basketballsResetter.js | 4 +- .../DomainContent/Toybox/bow/bow.js | 10 +-- .../DomainContent/Toybox/bow/createBow.js | 4 +- .../Toybox/bubblewand/createWand.js | 4 +- .../DomainContent/Toybox/bubblewand/wand.js | 2 +- .../DomainContent/Toybox/cat/cat.js | 2 +- .../DomainContent/Toybox/doll/createDoll.js | 2 +- .../DomainContent/Toybox/doll/doll.js | 4 +- .../Toybox/flappyAvatars/flappyAvatars.js | 24 +++--- .../Toybox/flappyAvatars/flappyAvatars.json | 4 +- .../Toybox/flashlight/createFlashlight.js | 2 +- .../Toybox/flashlight/flashlight.js | 4 +- .../Toybox/flowArts/raveStickEntityScript.js | 2 +- .../DomainContent/Toybox/hiddenEntityReset.js | 74 +++++++++---------- .../Toybox/lights/lightSwitch.js | 2 +- .../DomainContent/Toybox/masterReset.js | 74 +++++++++---------- .../Toybox/musicPlayer/musicPlayer.js | 2 +- .../Toybox/ping_pong_gun/createPingPongGun.js | 6 +- .../Toybox/ping_pong_gun/createTargets.js | 4 +- .../Toybox/ping_pong_gun/pingPongGun.js | 4 +- .../Toybox/ping_pong_gun/wallTarget.js | 2 +- .../Toybox/pistol/createPistol.js | 4 +- .../DomainContent/Toybox/pistol/pistol.js | 6 +- .../Toybox/spray_paint/sprayPaintCan.js | 4 +- .../DomainContent/Toybox/targetsResetter.js | 4 +- 31 files changed, 147 insertions(+), 147 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index ac4886db8f..ff55137a03 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1214,7 +1214,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * ], * strokeWidths: [ 0.1, 0.1, 0.1 ], * color: { red: 255, green: 0, blue: 0 }, // Use just the red channel from the image. - * textures: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flowArts/trails.png", + * textures: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flowArts/trails.png", * isUVModeStretch: true, * lifetime: 300 // Delete after 5 minutes. * }); diff --git a/unpublishedScripts/DomainContent/CellScience/backgroundMusicAC.js b/unpublishedScripts/DomainContent/CellScience/backgroundMusicAC.js index 829dfbeae9..5922f382b9 100644 --- a/unpublishedScripts/DomainContent/CellScience/backgroundMusicAC.js +++ b/unpublishedScripts/DomainContent/CellScience/backgroundMusicAC.js @@ -1,6 +1,6 @@ var soundMap = [{ name: 'Cells', - url: "http://hifi-production.s3.amazonaws.com/DomainContent/CellScience/Audio/Cells.wav", + url: "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/Audio/Cells.wav", audioOptions: { position: { x: 15850, @@ -12,7 +12,7 @@ var soundMap = [{ } }, { name: 'Cell Layout', - url: "http://hifi-production.s3.amazonaws.com/DomainContent/CellScience/Audio/CellLayout.wav", + url: "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/Audio/CellLayout.wav", audioOptions: { position: { x: 15950, @@ -24,7 +24,7 @@ var soundMap = [{ } }, { name: 'Ribsome', - url: "http://hifi-production.s3.amazonaws.com/DomainContent/CellScience/Audio/Ribosome.wav", + url: "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/Audio/Ribosome.wav", audioOptions: { position: { x: 15650, @@ -36,7 +36,7 @@ var soundMap = [{ } }, { name: 'Hexokinase', - url: "http://hifi-production.s3.amazonaws.com/DomainContent/CellScience/Audio/Hexokinase.wav", + url: "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/Audio/Hexokinase.wav", audioOptions: { position: { x: 15750, diff --git a/unpublishedScripts/DomainContent/Toybox/AC_scripts/toybox_sounds.js b/unpublishedScripts/DomainContent/Toybox/AC_scripts/toybox_sounds.js index e73630e380..84242d69ab 100644 --- a/unpublishedScripts/DomainContent/Toybox/AC_scripts/toybox_sounds.js +++ b/unpublishedScripts/DomainContent/Toybox/AC_scripts/toybox_sounds.js @@ -10,7 +10,7 @@ var soundMap = [{ name: 'river water', - url: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/sounds/Water_Lap_River_Edge_Gentle.L.wav", + url: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/sounds/Water_Lap_River_Edge_Gentle.L.wav", audioOptions: { position: { x: 580, @@ -22,7 +22,7 @@ var soundMap = [{ } }, { name: 'windmill', - url: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/sounds/WINDMILL_Mono.wav", + url: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/sounds/WINDMILL_Mono.wav", audioOptions: { position: { x: 530, @@ -34,7 +34,7 @@ var soundMap = [{ } }, { name: 'insects', - url: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/sounds/insects3.wav", + url: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/sounds/insects3.wav", audioOptions: { position: { x: 560, @@ -46,7 +46,7 @@ var soundMap = [{ } }, { name: 'fireplace', - url: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/sounds/0619_Fireplace__Tree_B.L.wav", + url: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/sounds/0619_Fireplace__Tree_B.L.wav", audioOptions: { position: { x: 551.61, @@ -58,7 +58,7 @@ var soundMap = [{ } }, { name: 'cat purring', - url: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/sounds/Cat_Purring_Deep_Low_Snor.wav", + url: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/sounds/Cat_Purring_Deep_Low_Snor.wav", audioOptions: { position: { x: 551.48, @@ -70,7 +70,7 @@ var soundMap = [{ } }, { name: 'dogs barking', - url: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/sounds/dogs_barking_1.L.wav", + url: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/sounds/dogs_barking_1.L.wav", audioOptions: { position: { x: 523, @@ -83,7 +83,7 @@ var soundMap = [{ playAtInterval: 60 * 1000 }, { name: 'arcade game', - url: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/sounds/ARCADE_GAMES_VID.L.L.wav", + url: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/sounds/ARCADE_GAMES_VID.L.L.wav", audioOptions: { position: { x: 543.77, diff --git a/unpublishedScripts/DomainContent/Toybox/basketball/createHoop.js b/unpublishedScripts/DomainContent/Toybox/basketball/createHoop.js index 8a3f9bb6d7..cb253ddf0b 100644 --- a/unpublishedScripts/DomainContent/Toybox/basketball/createHoop.js +++ b/unpublishedScripts/DomainContent/Toybox/basketball/createHoop.js @@ -8,8 +8,8 @@ // -var hoopURL ="http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball_hoop.fbx"; -var hoopCollisionHullURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball_hoop_collision_hull.obj"; +var hoopURL ="https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball_hoop.fbx"; +var hoopCollisionHullURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball_hoop_collision_hull.obj"; var hoopStartPosition = Vec3.sum(MyAvatar.position, diff --git a/unpublishedScripts/DomainContent/Toybox/basketball/createRack.js b/unpublishedScripts/DomainContent/Toybox/basketball/createRack.js index 8209a88f33..85bd5b43d1 100644 --- a/unpublishedScripts/DomainContent/Toybox/basketball/createRack.js +++ b/unpublishedScripts/DomainContent/Toybox/basketball/createRack.js @@ -11,10 +11,10 @@ Script.include("../libraries/utils.js"); -var basketballURL ="http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball2.fbx"; -var collisionSoundURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball.wav"; -var rackURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball_rack.fbx"; -var rackCollisionHullURL ="http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/rack_collision_hull.obj"; +var basketballURL ="https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball2.fbx"; +var collisionSoundURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball.wav"; +var rackURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball_rack.fbx"; +var rackCollisionHullURL ="https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/rack_collision_hull.obj"; var NUMBER_OF_BALLS = 4; var DIAMETER = 0.30; var RESET_DISTANCE = 1; diff --git a/unpublishedScripts/DomainContent/Toybox/basketball/createSingleBasketball.js b/unpublishedScripts/DomainContent/Toybox/basketball/createSingleBasketball.js index d70b9a1bd8..1300a26e68 100644 --- a/unpublishedScripts/DomainContent/Toybox/basketball/createSingleBasketball.js +++ b/unpublishedScripts/DomainContent/Toybox/basketball/createSingleBasketball.js @@ -10,8 +10,8 @@ // -var basketballURL ="http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball2.fbx"; -var collisionSoundURL ="http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball.wav"; +var basketballURL ="https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball2.fbx"; +var collisionSoundURL ="https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball.wav"; var basketball = null; diff --git a/unpublishedScripts/DomainContent/Toybox/basketballsResetter.js b/unpublishedScripts/DomainContent/Toybox/basketballsResetter.js index 580453bf24..5dadee868b 100644 --- a/unpublishedScripts/DomainContent/Toybox/basketballsResetter.js +++ b/unpublishedScripts/DomainContent/Toybox/basketballsResetter.js @@ -41,8 +41,8 @@ createBasketballs: function() { var NUMBER_OF_BALLS = 4; var DIAMETER = 0.30; - var basketballURL ="http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball2.fbx"; - var basketballCollisionSoundURL ="http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball.wav"; + var basketballURL ="https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball2.fbx"; + var basketballCollisionSoundURL ="https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball.wav"; var position = { x: 542.86, diff --git a/unpublishedScripts/DomainContent/Toybox/bow/bow.js b/unpublishedScripts/DomainContent/Toybox/bow/bow.js index 47335bcb6d..2bae1dc16e 100644 --- a/unpublishedScripts/DomainContent/Toybox/bow/bow.js +++ b/unpublishedScripts/DomainContent/Toybox/bow/bow.js @@ -13,9 +13,9 @@ Script.include("../libraries/utils.js"); - var NOTCH_ARROW_SOUND_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bow/notch.wav'; - var SHOOT_ARROW_SOUND_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bow/String_release2.L.wav'; - var STRING_PULL_SOUND_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bow/Bow_draw.1.L.wav'; + var NOTCH_ARROW_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/notch.wav'; + var SHOOT_ARROW_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/String_release2.L.wav'; + var STRING_PULL_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/Bow_draw.1.L.wav'; var ARROW_HIT_SOUND_URL = 'https://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bow/Arrow_impact1.L.wav' var ARROW_DIMENSIONS = { @@ -32,9 +32,9 @@ z: 0 }; - var ARROW_MODEL_URL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bow/newarrow_textured.fbx"; + var ARROW_MODEL_URL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/newarrow_textured.fbx"; var ARROW_COLLISION_HULL_URL = - "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bow/newarrow_collision_hull.obj"; + "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/newarrow_collision_hull.obj"; var ARROW_DIMENSIONS = { x: 0.02, diff --git a/unpublishedScripts/DomainContent/Toybox/bow/createBow.js b/unpublishedScripts/DomainContent/Toybox/bow/createBow.js index 5a4275d96a..8de8379c18 100644 --- a/unpublishedScripts/DomainContent/Toybox/bow/createBow.js +++ b/unpublishedScripts/DomainContent/Toybox/bow/createBow.js @@ -15,8 +15,8 @@ Script.include(utilsPath); var SCRIPT_URL = Script.resolvePath('bow.js'); -var MODEL_URL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bow/bow-deadly.fbx"; -var COLLISION_HULL_URL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bow/bow_collision_hull.obj"; +var MODEL_URL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/bow-deadly.fbx"; +var COLLISION_HULL_URL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/bow_collision_hull.obj"; var BOW_DIMENSIONS = { x: 0.04, y: 1.3, diff --git a/unpublishedScripts/DomainContent/Toybox/bubblewand/createWand.js b/unpublishedScripts/DomainContent/Toybox/bubblewand/createWand.js index 0a7d8b7055..5f1e8b072e 100644 --- a/unpublishedScripts/DomainContent/Toybox/bubblewand/createWand.js +++ b/unpublishedScripts/DomainContent/Toybox/bubblewand/createWand.js @@ -12,8 +12,8 @@ Script.include("../libraries/utils.js"); -var WAND_MODEL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bubblewand/wand.fbx'; -var WAND_COLLISION_SHAPE = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bubblewand/wand_collision_hull.obj'; +var WAND_MODEL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bubblewand/wand.fbx'; +var WAND_COLLISION_SHAPE = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bubblewand/wand_collision_hull.obj'; var WAND_SCRIPT_URL = Script.resolvePath("wand.js"); diff --git a/unpublishedScripts/DomainContent/Toybox/bubblewand/wand.js b/unpublishedScripts/DomainContent/Toybox/bubblewand/wand.js index 6f63fe3ec9..0142b610e9 100644 --- a/unpublishedScripts/DomainContent/Toybox/bubblewand/wand.js +++ b/unpublishedScripts/DomainContent/Toybox/bubblewand/wand.js @@ -16,7 +16,7 @@ Script.include("../libraries/utils.js"); - var BUBBLE_MODEL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bubblewand/bubble.fbx"; + var BUBBLE_MODEL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bubblewand/bubble.fbx"; var BUBBLE_INITIAL_DIMENSIONS = { x: 0.01, diff --git a/unpublishedScripts/DomainContent/Toybox/cat/cat.js b/unpublishedScripts/DomainContent/Toybox/cat/cat.js index 78b3a92bc3..90ff34e2e4 100644 --- a/unpublishedScripts/DomainContent/Toybox/cat/cat.js +++ b/unpublishedScripts/DomainContent/Toybox/cat/cat.js @@ -16,7 +16,7 @@ var _this; Cat = function() { _this = this; - this.meowSound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/cat/cat_meow.wav"); + this.meowSound = SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/cat/cat_meow.wav"); }; Cat.prototype = { diff --git a/unpublishedScripts/DomainContent/Toybox/doll/createDoll.js b/unpublishedScripts/DomainContent/Toybox/doll/createDoll.js index 37771fee4a..2e0c2a297d 100644 --- a/unpublishedScripts/DomainContent/Toybox/doll/createDoll.js +++ b/unpublishedScripts/DomainContent/Toybox/doll/createDoll.js @@ -11,7 +11,7 @@ /*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ function createDoll() { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/doll/bboy2.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/doll/bboy2.fbx"; var scriptURL = Script.resolvePath("doll.js"); diff --git a/unpublishedScripts/DomainContent/Toybox/doll/doll.js b/unpublishedScripts/DomainContent/Toybox/doll/doll.js index 654151a0a7..e1c815add9 100644 --- a/unpublishedScripts/DomainContent/Toybox/doll/doll.js +++ b/unpublishedScripts/DomainContent/Toybox/doll/doll.js @@ -18,7 +18,7 @@ // this is the "constructor" for the entity as a JS object we don't do much here var Doll = function() { _this = this; - this.screamSounds = [SoundCache.getSound("http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/doll/KenDoll_1%2303.wav")]; + this.screamSounds = [SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/doll/KenDoll_1%2303.wav")]; }; Doll.prototype = { @@ -31,7 +31,7 @@ Entities.editEntity(this.entityID, { animation: { - url: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/doll/zombie_scream.fbx", + url: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/doll/zombie_scream.fbx", running: true } }); diff --git a/unpublishedScripts/DomainContent/Toybox/flappyAvatars/flappyAvatars.js b/unpublishedScripts/DomainContent/Toybox/flappyAvatars/flappyAvatars.js index deefad3507..f45e6e2131 100644 --- a/unpublishedScripts/DomainContent/Toybox/flappyAvatars/flappyAvatars.js +++ b/unpublishedScripts/DomainContent/Toybox/flappyAvatars/flappyAvatars.js @@ -37,7 +37,7 @@ var yVelocity = 0.0; var yAcceleration = -G; - var airSwipeSound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flappyAvatars/Air%20Swipe%2005.wav"); + var airSwipeSound = SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flappyAvatars/Air%20Swipe%2005.wav"); var injector = null; this.position = function() { @@ -51,7 +51,7 @@ type: "Model", modelURL: MyAvatar.skeletonModelURL, animation: { - url: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flappyAvatars/fly.fbx", + url: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flappyAvatars/fly.fbx", running: true, fps: 30, firstFrame: 1.0, @@ -76,7 +76,7 @@ animation: {running: false} }); - airSwipeSound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flappyAvatars/8bit%20Jump%2003.wav"); + airSwipeSound = SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flappyAvatars/8bit%20Jump%2003.wav"); injector = null; } @@ -132,7 +132,7 @@ var id = entityManager.add({ type: "Model", - modelURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flappyAvatars/coin.fbx", + modelURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flappyAvatars/coin.fbx", angularVelocity: { x: 0, y: 20, z: 0 }, position: to3DPosition(this.position()), dimensions:dimensions @@ -172,14 +172,14 @@ var idUp = entityManager.add({ type: "Model", - modelURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flappyAvatars/greenPipe.fbx", + modelURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flappyAvatars/greenPipe.fbx", rotation: Quat.fromPitchYawRollDegrees(180, 0, 0), position: to3DPosition({ x: xPosition, y: upYPosition }), dimensions: { x: width, y: upHeight, z: width } }); var idDown = entityManager.add({ type: "Model", - modelURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flappyAvatars/greenPipe.fbx", + modelURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flappyAvatars/greenPipe.fbx", position: to3DPosition({ x: xPosition, y: height / 2.0 }), dimensions: { x: width, y: height, z: width } }); @@ -217,7 +217,7 @@ var pipes = new Array(); var coins = new Array(); - var coinsSound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flappyAvatars/Coin.wav"); + var coinsSound = SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flappyAvatars/Coin.wav"); var injector = null; this.update = function(deltaTime, gameTime, startedPlaying) { @@ -325,7 +325,7 @@ var numberDimensions = { x: 0.0660, y: 0.1050, z: 0.0048 }; function numberUrl(number) { - return "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flappyAvatars/" + number + ".fbx" + return "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flappyAvatars/" + number + ".fbx" } function digitPosition(digit) { return Vec3.multiplyQbyV(space.orientation, { x: 0.3778 + digit * (numberDimensions.x + 0.01), y: 0.0, z: 0.0 }); @@ -341,7 +341,7 @@ var bestId = entityManager.add({ type: "Model", - modelURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flappyAvatars/best.fbx", + modelURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flappyAvatars/best.fbx", position: topLeft, rotation: Quat.multiply(space.orientation, Quat.fromPitchYawRollDegrees(90, 0, 0)), dimensions: { x: 0.2781, y: 0.0063, z: 0.1037 } @@ -359,7 +359,7 @@ var scoreId = entityManager.add({ type: "Model", - modelURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flappyAvatars/score.fbx", + modelURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flappyAvatars/score.fbx", position: bottomLeft, rotation: Quat.multiply(space.orientation, Quat.fromPitchYawRollDegrees(90, 0, 0)), dimensions: { x: 0.3678, y: 0.0063, z: 0.1037 } @@ -453,7 +453,7 @@ var pipes = null; var score = null; - var gameOverSound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flappyAvatars/Game%20Over.wav"); + var gameOverSound = SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flappyAvatars/Game%20Over.wav"); var injector = null; var directions = ["UP", "DOWN", "LEFT", "RIGHT"]; @@ -466,7 +466,7 @@ current = 0; } if (current === sequence.length) { - avatar.changeModel("http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flappyAvatars/mario.fbx"); + avatar.changeModel("https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flappyAvatars/mario.fbx"); current = 0; } } diff --git a/unpublishedScripts/DomainContent/Toybox/flappyAvatars/flappyAvatars.json b/unpublishedScripts/DomainContent/Toybox/flappyAvatars/flappyAvatars.json index 90c6e5b13d..26dbecc47f 100644 --- a/unpublishedScripts/DomainContent/Toybox/flappyAvatars/flappyAvatars.json +++ b/unpublishedScripts/DomainContent/Toybox/flappyAvatars/flappyAvatars.json @@ -10,7 +10,7 @@ }, "dynamic": 1, "id": "{ee5b25e6-aca2-4dc7-9462-51537d89c126}", - "modelURL": "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flappyAvatars/cube.fbx", + "modelURL": "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flappyAvatars/cube.fbx", "queryAACube": { "scale": 0.5974045991897583, "x": -5.1575918197631836, @@ -23,7 +23,7 @@ "y": -0.13279926776885986, "z": 0.34688329696655273 }, - "script": "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flappyAvatars/flappyAvatars.js", + "script": "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flappyAvatars/flappyAvatars.js", "scriptTimestamp": 1457031937425, "shapeType": "box", "type": "Model", diff --git a/unpublishedScripts/DomainContent/Toybox/flashlight/createFlashlight.js b/unpublishedScripts/DomainContent/Toybox/flashlight/createFlashlight.js index 9bcc6dae58..c57c3a0cd3 100644 --- a/unpublishedScripts/DomainContent/Toybox/flashlight/createFlashlight.js +++ b/unpublishedScripts/DomainContent/Toybox/flashlight/createFlashlight.js @@ -16,7 +16,7 @@ Script.include("../libraries/utils.js"); var scriptURL = Script.resolvePath('flashlight.js'); -var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flashlight/flashlight.fbx"; +var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flashlight/flashlight.fbx"; var center = Vec3.sum(Vec3.sum(MyAvatar.position, { x: 0, diff --git a/unpublishedScripts/DomainContent/Toybox/flashlight/flashlight.js b/unpublishedScripts/DomainContent/Toybox/flashlight/flashlight.js index 82a354c767..08d98a80fe 100644 --- a/unpublishedScripts/DomainContent/Toybox/flashlight/flashlight.js +++ b/unpublishedScripts/DomainContent/Toybox/flashlight/flashlight.js @@ -19,8 +19,8 @@ Script.include("../libraries/utils.js"); - var ON_SOUND_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flashlight/flashlight_on.wav'; - var OFF_SOUND_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flashlight/flashlight_off.wav'; + var ON_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flashlight/flashlight_on.wav'; + var OFF_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flashlight/flashlight_off.wav'; //we are creating lights that we don't want to get stranded so lets make sure that we can get rid of them var startTime = Date.now(); diff --git a/unpublishedScripts/DomainContent/Toybox/flowArts/raveStickEntityScript.js b/unpublishedScripts/DomainContent/Toybox/flowArts/raveStickEntityScript.js index 03e15d66db..2cbe9c00b9 100644 --- a/unpublishedScripts/DomainContent/Toybox/flowArts/raveStickEntityScript.js +++ b/unpublishedScripts/DomainContent/Toybox/flowArts/raveStickEntityScript.js @@ -30,7 +30,7 @@ green: 10, blue: 40 }]; - var texture = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flowArts/trails.png"; + var texture = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flowArts/trails.png"; this.trail = Entities.addEntity({ type: "PolyLine", dimensions: { diff --git a/unpublishedScripts/DomainContent/Toybox/hiddenEntityReset.js b/unpublishedScripts/DomainContent/Toybox/hiddenEntityReset.js index fe514f6dfc..c4607c1a01 100644 --- a/unpublishedScripts/DomainContent/Toybox/hiddenEntityReset.js +++ b/unpublishedScripts/DomainContent/Toybox/hiddenEntityReset.js @@ -170,7 +170,7 @@ } function createRaveStick(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flowArts/raveStick.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flowArts/raveStick.fbx"; var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); var stick = Entities.addEntity({ type: "Model", @@ -260,7 +260,7 @@ alphaSpread: 0.1, alphaStart: 0.1, alphaFinish: 0.1, - textures: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flowArts/beamParticle.png", + textures: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flowArts/beamParticle.png", emitterShouldTrail: false, userData: JSON.stringify({ resetMe: { @@ -272,7 +272,7 @@ } function createGun(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/pistol/gun.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/pistol/gun.fbx"; var pistol = Entities.addEntity({ type: 'Model', @@ -281,7 +281,7 @@ position: position, restitution: 0, damping: 0.5, - collisionSoundURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/pistol/drop.wav", + collisionSoundURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/pistol/drop.wav", dimensions: { x: 0.05, y: 0.23, @@ -345,8 +345,8 @@ var SCRIPT_URL = Script.resolvePath('bow.js'); var BOW_ROTATION = Quat.fromPitchYawRollDegrees(-103.05, -178.60, -87.27); - var MODEL_URL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bow/bow-deadly.fbx"; - var COLLISION_HULL_URL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bow/bow_collision_hull.obj"; + var MODEL_URL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/bow-deadly.fbx"; + var COLLISION_HULL_URL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/bow_collision_hull.obj"; var BOW_DIMENSIONS = { x: 0.04, @@ -497,7 +497,7 @@ type: "ParticleEffect", name: "fire", animationSettings: animationSettings, - textures: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/fire/Particle-Sprite-Smoke-1.png", + textures: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/fire/Particle-Sprite-Smoke-1.png", position: { x: 551.45, y: 494.82, @@ -560,10 +560,10 @@ var DIAMETER = 0.30; var RESET_DISTANCE = 1; var MINIMUM_MOVE_LENGTH = 0.05; - var basketballURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball2.fbx"; - var basketballCollisionSoundURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball.wav"; - var rackURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball_rack.fbx"; - var rackCollisionHullURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/rack_collision_hull.obj"; + var basketballURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball2.fbx"; + var basketballCollisionSoundURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball.wav"; + var rackURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball_rack.fbx"; + var rackCollisionHullURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/rack_collision_hull.obj"; var rackRotation = Quat.fromPitchYawRollDegrees(0, -90, 0); @@ -639,7 +639,7 @@ z: 0 }, dynamic: true, - collisionSoundURL: 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball.wav', + collisionSoundURL: 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball.wav', collisionless: false, modelURL: basketballURL, userData: JSON.stringify({ @@ -734,8 +734,8 @@ function createTargets() { - var MODEL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/target.fbx'; - var COLLISION_HULL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/target_collision_hull.obj'; + var MODEL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/target.fbx'; + var COLLISION_HULL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/target_collision_hull.obj'; var MINIMUM_MOVE_LENGTH = 0.05; var RESET_DISTANCE = 0.5; @@ -814,8 +814,8 @@ function createCat(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/cat/Dark_Cat.fbx"; - var animationURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/cat/sleeping.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/cat/Dark_Cat.fbx"; + var animationURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/cat/sleeping.fbx"; var animationSettings = JSON.stringify({ running: true }); @@ -851,7 +851,7 @@ } function createFlashlight(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flashlight/flashlight.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flashlight/flashlight.fbx"; var flashlight = Entities.addEntity({ type: "Model", @@ -865,7 +865,7 @@ z: 0.08 }, dynamic: true, - collisionSoundURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flashlight/flashlight_drop.L.wav", + collisionSoundURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flashlight/flashlight_drop.L.wav", gravity: { x: 0, y: -3.5, @@ -916,7 +916,7 @@ } function createLights() { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/lights/lightswitch.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/lights/lightswitch.fbx"; var rotation = { @@ -1164,8 +1164,8 @@ function createDice() { var diceProps = { type: "Model", - modelURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/dice/goldDie.fbx", - collisionSoundURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/dice/diceCollide.wav", + modelURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/dice/goldDie.fbx", + collisionSoundURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/dice/diceCollide.wav", name: "dice", position: { x: 541.61, @@ -1212,7 +1212,7 @@ } function createGates() { - var MODEL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/gates/fence.fbx'; + var MODEL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/gates/fence.fbx'; var rotation = Quat.fromPitchYawRollDegrees(0, -16, 0); var gate = Entities.addEntity({ @@ -1253,9 +1253,9 @@ function createPingPongBallGun() { - var MODEL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/Pingpong-Gun-New.fbx'; - var COLLISION_HULL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/Pingpong-Gun-New.obj'; - var COLLISION_SOUND_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/plastic_impact.L.wav'; + var MODEL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/Pingpong-Gun-New.fbx'; + var COLLISION_HULL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/Pingpong-Gun-New.obj'; + var COLLISION_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/plastic_impact.L.wav'; var position = { x: 548.6, y: 495.4, @@ -1321,8 +1321,8 @@ } function createWand(position) { - var WAND_MODEL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bubblewand/wand.fbx'; - var WAND_COLLISION_SHAPE = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bubblewand/wand_collision_hull.obj'; + var WAND_MODEL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bubblewand/wand.fbx'; + var WAND_COLLISION_SHAPE = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bubblewand/wand_collision_hull.obj'; var wand = Entities.addEntity({ name: 'Bubble Wand', @@ -1382,7 +1382,7 @@ function createBasketBall(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball2.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball2.fbx"; var entity = Entities.addEntity({ type: "Model", @@ -1408,7 +1408,7 @@ y: -0.01, z: 0 }, - collisionSoundURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball.wav", + collisionSoundURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball.wav", userData: JSON.stringify({ resetMe: { resetMe: true @@ -1422,7 +1422,7 @@ } function createDoll(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/doll/bboy2.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/doll/bboy2.fbx"; var naturalDimensions = { x: 1.63, @@ -1463,7 +1463,7 @@ function createSprayCan(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/spray_paint/paintcan.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/spray_paint/paintcan.fbx"; var entity = Entities.addEntity({ type: "Model", @@ -1477,7 +1477,7 @@ z: 0.07 }, dynamic: true, - collisionSoundURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/spray_paint/SpryPntCnDrp1.L.wav", + collisionSoundURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/spray_paint/SpryPntCnDrp1.L.wav", shapeType: 'box', restitution: 0, gravity: { @@ -1503,7 +1503,7 @@ } function createPottedPlant(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/potted_plant/potted_plant.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/potted_plant/potted_plant.fbx"; var entity = Entities.addEntity({ type: "Model", @@ -1541,8 +1541,8 @@ function createCombinedArmChair(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/armchair/combined_chair.fbx"; - var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/armchair/red_arm_chair_collision_hull.obj"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/armchair/combined_chair.fbx"; + var RED_ARM_CHAIR_COLLISION_HULL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/armchair/red_arm_chair_collision_hull.obj"; var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); @@ -1584,8 +1584,8 @@ } function createBlocks(position) { - var baseURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/planky/"; - var collisionSoundURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/planky/ToyWoodBlock.L.wav"; + var baseURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/planky/"; + var collisionSoundURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/planky/ToyWoodBlock.L.wav"; var NUM_BLOCKS_PER_COLOR = 4; var i, j; diff --git a/unpublishedScripts/DomainContent/Toybox/lights/lightSwitch.js b/unpublishedScripts/DomainContent/Toybox/lights/lightSwitch.js index 2a1ef04ed3..34228184bd 100644 --- a/unpublishedScripts/DomainContent/Toybox/lights/lightSwitch.js +++ b/unpublishedScripts/DomainContent/Toybox/lights/lightSwitch.js @@ -21,7 +21,7 @@ Script.include(utilitiesScript); LightSwitch = function() { _this = this; - this.switchSound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/lights/lamp_switch_2.wav"); + this.switchSound = SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/lights/lamp_switch_2.wav"); }; LightSwitch.prototype = { diff --git a/unpublishedScripts/DomainContent/Toybox/masterReset.js b/unpublishedScripts/DomainContent/Toybox/masterReset.js index b621544621..7bbbdf616d 100644 --- a/unpublishedScripts/DomainContent/Toybox/masterReset.js +++ b/unpublishedScripts/DomainContent/Toybox/masterReset.js @@ -143,7 +143,7 @@ MasterReset = function() { } function createRaveStick(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flowArts/raveStick.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flowArts/raveStick.fbx"; var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); var stick = Entities.addEntity({ type: "Model", @@ -238,7 +238,7 @@ MasterReset = function() { alphaSpread: 0.1, alphaStart: 0.1, alphaFinish: 0.1, - textures: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flowArts/beamParticle.png", + textures: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flowArts/beamParticle.png", emitterShouldTrail: false, userData: JSON.stringify({ resetMe: { @@ -249,7 +249,7 @@ MasterReset = function() { } function createGun(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/pistol/gun.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/pistol/gun.fbx"; var pistol = Entities.addEntity({ @@ -277,7 +277,7 @@ MasterReset = function() { restitution: 0, dynamic: true, damping: 0.5, - collisionSoundURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/pistol/drop.wav", + collisionSoundURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/pistol/drop.wav", userData: JSON.stringify({ "wearable": { "joints": { @@ -323,8 +323,8 @@ MasterReset = function() { var SCRIPT_URL = Script.resolvePath('bow.js'); var BOW_ROTATION = Quat.fromPitchYawRollDegrees(-103.05, -178.60, -87.27); - var MODEL_URL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bow/bow-deadly.fbx"; - var COLLISION_HULL_URL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bow/bow_collision_hull.obj"; + var MODEL_URL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/bow-deadly.fbx"; + var COLLISION_HULL_URL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/bow_collision_hull.obj"; var BOW_DIMENSIONS = { x: 0.04, y: 1.3, @@ -474,7 +474,7 @@ MasterReset = function() { type: "ParticleEffect", name: "fire", animationSettings: animationSettings, - textures: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/fire/Particle-Sprite-Smoke-1.png", + textures: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/fire/Particle-Sprite-Smoke-1.png", position: { x: 551.45, y: 494.82, @@ -538,10 +538,10 @@ MasterReset = function() { var DIAMETER = 0.30; var RESET_DISTANCE = 1; var MINIMUM_MOVE_LENGTH = 0.05; - var basketballURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball2.fbx"; - var basketballCollisionSoundURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball.wav"; - var rackURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball_rack.fbx"; - var rackCollisionHullURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/rack_collision_hull.obj"; + var basketballURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball2.fbx"; + var basketballCollisionSoundURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball.wav"; + var rackURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball_rack.fbx"; + var rackCollisionHullURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/rack_collision_hull.obj"; var rackRotation = Quat.fromPitchYawRollDegrees(0, -90, 0); @@ -618,7 +618,7 @@ MasterReset = function() { z: 0 }, dynamic: true, - collisionSoundURL: 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball.wav', + collisionSoundURL: 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball.wav', collisionless: false, modelURL: basketballURL, userData: JSON.stringify({ @@ -715,8 +715,8 @@ MasterReset = function() { function createTargets() { - var MODEL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/target.fbx'; - var COLLISION_HULL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/target_collision_hull.obj'; + var MODEL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/target.fbx'; + var COLLISION_HULL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/target_collision_hull.obj'; var MINIMUM_MOVE_LENGTH = 0.05; var RESET_DISTANCE = 0.5; @@ -795,8 +795,8 @@ MasterReset = function() { function createCat(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/cat/Dark_Cat.fbx"; - var animationURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/cat/sleeping.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/cat/Dark_Cat.fbx"; + var animationURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/cat/sleeping.fbx"; var animationSettings = JSON.stringify({ running: true }); @@ -832,7 +832,7 @@ MasterReset = function() { } function createFlashlight(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flashlight/flashlight.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flashlight/flashlight.fbx"; var flashlight = Entities.addEntity({ type: "Model", @@ -846,7 +846,7 @@ MasterReset = function() { z: 0.08 }, dynamic: true, - collisionSoundURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flashlight/flashlight_drop.L.wav", + collisionSoundURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/flashlight/flashlight_drop.L.wav", gravity: { x: 0, y: -3.5, @@ -897,7 +897,7 @@ MasterReset = function() { } function createLights() { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/lights/lightswitch.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/lights/lightswitch.fbx"; var rotation = { w: 0.63280689716339111, @@ -1144,8 +1144,8 @@ MasterReset = function() { function createDice() { var diceProps = { type: "Model", - modelURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/dice/goldDie.fbx", - collisionSoundURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/dice/diceCollide.wav", + modelURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/dice/goldDie.fbx", + collisionSoundURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/dice/diceCollide.wav", name: "dice", position: { x: 541.61, @@ -1192,7 +1192,7 @@ MasterReset = function() { } function createGates() { - var MODEL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/gates/fence.fbx'; + var MODEL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/gates/fence.fbx'; var rotation = Quat.fromPitchYawRollDegrees(0, -16, 0); var gate = Entities.addEntity({ name: 'Front Door Fence', @@ -1231,9 +1231,9 @@ MasterReset = function() { } function createPingPongBallGun() { - var MODEL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/Pingpong-Gun-New.fbx'; - var COLLISION_HULL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/Pingpong-Gun-New.obj'; - var COLLISION_SOUND_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/plastic_impact.L.wav'; + var MODEL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/Pingpong-Gun-New.fbx'; + var COLLISION_HULL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/Pingpong-Gun-New.obj'; + var COLLISION_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/plastic_impact.L.wav'; var position = { x: 548.6, y: 495.4, @@ -1299,8 +1299,8 @@ MasterReset = function() { } function createWand(position) { - var WAND_MODEL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bubblewand/wand.fbx'; - var WAND_COLLISION_SHAPE = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bubblewand/wand_collision_hull.obj'; + var WAND_MODEL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bubblewand/wand.fbx'; + var WAND_COLLISION_SHAPE = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bubblewand/wand_collision_hull.obj'; var wand = Entities.addEntity({ name: 'Bubble Wand', @@ -1360,7 +1360,7 @@ MasterReset = function() { function createBasketBall(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball2.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball2.fbx"; var entity = Entities.addEntity({ type: "Model", @@ -1386,7 +1386,7 @@ MasterReset = function() { y: -0.01, z: 0 }, - collisionSoundURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/basketball/basketball.wav", + collisionSoundURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/basketball/basketball.wav", userData: JSON.stringify({ resetMe: { resetMe: true @@ -1400,7 +1400,7 @@ MasterReset = function() { } function createDoll(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/doll/bboy2.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/doll/bboy2.fbx"; var naturalDimensions = { x: 1.63, @@ -1442,7 +1442,7 @@ MasterReset = function() { function createSprayCan(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/spray_paint/paintcan.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/spray_paint/paintcan.fbx"; var entity = Entities.addEntity({ type: "Model", @@ -1456,7 +1456,7 @@ MasterReset = function() { z: 0.07 }, dynamic: true, - collisionSoundURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/spray_paint/SpryPntCnDrp1.L.wav", + collisionSoundURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/spray_paint/SpryPntCnDrp1.L.wav", shapeType: 'box', gravity: { x: 0, @@ -1482,7 +1482,7 @@ MasterReset = function() { } function createPottedPlant(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/potted_plant/potted_plant.fbx"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/potted_plant/potted_plant.fbx"; var entity = Entities.addEntity({ type: "Model", @@ -1520,8 +1520,8 @@ MasterReset = function() { function createCombinedArmChair(position) { - var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/armchair/combined_chair.fbx"; - var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/armchair/red_arm_chair_collision_hull.obj"; + var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/armchair/combined_chair.fbx"; + var RED_ARM_CHAIR_COLLISION_HULL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/armchair/red_arm_chair_collision_hull.obj"; var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); @@ -1563,8 +1563,8 @@ MasterReset = function() { } function createBlocks(position) { - var baseURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/planky/"; - var collisionSoundURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/planky/ToyWoodBlock.L.wav"; + var baseURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/planky/"; + var collisionSoundURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/planky/ToyWoodBlock.L.wav"; var NUM_BLOCKS_PER_COLOR = 4; var i, j; diff --git a/unpublishedScripts/DomainContent/Toybox/musicPlayer/musicPlayer.js b/unpublishedScripts/DomainContent/Toybox/musicPlayer/musicPlayer.js index e3280e8f9c..2bc8584c89 100644 --- a/unpublishedScripts/DomainContent/Toybox/musicPlayer/musicPlayer.js +++ b/unpublishedScripts/DomainContent/Toybox/musicPlayer/musicPlayer.js @@ -19,7 +19,7 @@ var PLAYLIST_URL = "https://spreadsheets.google.com/feeds/cells/1x-ceGPGHldkHadARABFWfujLPTOWzXJPhrf2bTwg2cQ/od6/public/basic?alt=json"; var SONG_VOLUME = 0.1; var HEADPHONES_ATTACHMENT = { - modelURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/musicPlayer/headphones2-v2.fbx", + modelURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/musicPlayer/headphones2-v2.fbx", jointName: "Head", translation: {"x": 0, "y": 0.19, "z": 0.06}, rotation: {"x":0,"y":0.7071067690849304,"z":0.7071067690849304,"w":0}, diff --git a/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/createPingPongGun.js b/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/createPingPongGun.js index 22812c1206..2785dae573 100644 --- a/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/createPingPongGun.js +++ b/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/createPingPongGun.js @@ -13,9 +13,9 @@ Script.include("../libraries/utils.js"); var scriptURL = Script.resolvePath('pingPongGun.js'); -var MODEL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/Pingpong-Gun-New.fbx' -var COLLISION_HULL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/Pingpong-Gun-New.obj'; -var COLLISION_SOUND_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/plastic_impact.L.wav'; +var MODEL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/Pingpong-Gun-New.fbx' +var COLLISION_HULL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/Pingpong-Gun-New.obj'; +var COLLISION_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/plastic_impact.L.wav'; var center = Vec3.sum(Vec3.sum(MyAvatar.position, { x: 0, y: 0.5, diff --git a/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/createTargets.js b/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/createTargets.js index c52d2bff32..1e47a921fe 100644 --- a/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/createTargets.js +++ b/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/createTargets.js @@ -14,8 +14,8 @@ Script.include("../libraries/utils.js"); var scriptURL = Script.resolvePath('wallTarget.js'); -var MODEL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/target.fbx'; -var COLLISION_HULL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/target_collision_hull.obj'; +var MODEL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/target.fbx'; +var COLLISION_HULL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/target_collision_hull.obj'; var MINIMUM_MOVE_LENGTH = 0.05; var RESET_DISTANCE = 0.5; diff --git a/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/pingPongGun.js b/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/pingPongGun.js index 81a293a830..b1a91084d4 100644 --- a/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/pingPongGun.js +++ b/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/pingPongGun.js @@ -13,8 +13,8 @@ Script.include("../libraries/utils.js"); - var SHOOTING_SOUND_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/pong_sound.wav'; - var PING_PONG_BALL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/ping_pong_ball.fbx'; + var SHOOTING_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/pong_sound.wav'; + var PING_PONG_BALL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/ping_pong_ball.fbx'; function PingPongGun() { return; diff --git a/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/wallTarget.js b/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/wallTarget.js index 267faff4ed..1e3b21a06d 100644 --- a/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/wallTarget.js +++ b/unpublishedScripts/DomainContent/Toybox/ping_pong_gun/wallTarget.js @@ -20,7 +20,7 @@ hasBecomeActive: false, preload: function(entityID) { this.entityID = entityID; - var SOUND_URL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/Clay_Pigeon_02.L.wav"; + var SOUND_URL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/Clay_Pigeon_02.L.wav"; this.hitSound = SoundCache.getSound(SOUND_URL); }, collisionWithEntity: function(me, otherEntity) { diff --git a/unpublishedScripts/DomainContent/Toybox/pistol/createPistol.js b/unpublishedScripts/DomainContent/Toybox/pistol/createPistol.js index c3069547cb..358aa19221 100644 --- a/unpublishedScripts/DomainContent/Toybox/pistol/createPistol.js +++ b/unpublishedScripts/DomainContent/Toybox/pistol/createPistol.js @@ -1,6 +1,6 @@ var center = Vec3.sum(MyAvatar.position, Vec3.multiply(1.5, Quat.getFront(Camera.getOrientation()))); var scriptURL = Script.resolvePath('pistol.js'); -var modelURL = "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/pistol/gun.fbx"; +var modelURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/pistol/gun.fbx"; var pistol = Entities.addEntity({ @@ -27,7 +27,7 @@ var pistol = Entities.addEntity({ }, restitution: 0, damping:0.5, - collisionSoundURL: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/pistol/drop.wav", + collisionSoundURL: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/pistol/drop.wav", userData: JSON.stringify({ grabbableKey: { invertSolidWhileHeld: true diff --git a/unpublishedScripts/DomainContent/Toybox/pistol/pistol.js b/unpublishedScripts/DomainContent/Toybox/pistol/pistol.js index d86ffd753a..22d709b9bd 100644 --- a/unpublishedScripts/DomainContent/Toybox/pistol/pistol.js +++ b/unpublishedScripts/DomainContent/Toybox/pistol/pistol.js @@ -27,8 +27,8 @@ this.forceMultiplier = 1; this.laserLength = 100; - this.fireSound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/pistol/GUN-SHOT2.raw"); - this.ricochetSound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/pistol/Ricochet.L.wav"); + this.fireSound = SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/pistol/GUN-SHOT2.raw"); + this.ricochetSound = SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/pistol/Ricochet.L.wav"); this.playRichochetSoundChance = 0.1; this.fireVolume = 0.2; this.bulletForce = 10; @@ -216,7 +216,7 @@ "alphaStart": 0, "alphaFinish": 0, "additiveBlending": true, - "textures": "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/pistol/star.png" + "textures": "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/pistol/star.png" }); Script.setTimeout(function() { diff --git a/unpublishedScripts/DomainContent/Toybox/spray_paint/sprayPaintCan.js b/unpublishedScripts/DomainContent/Toybox/spray_paint/sprayPaintCan.js index 54534ef656..09b8080bd4 100644 --- a/unpublishedScripts/DomainContent/Toybox/spray_paint/sprayPaintCan.js +++ b/unpublishedScripts/DomainContent/Toybox/spray_paint/sprayPaintCan.js @@ -12,7 +12,7 @@ (function () { Script.include("../libraries/utils.js"); - this.spraySound = SoundCache.getSound("http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/spray_paint/spray_paint.wav"); + this.spraySound = SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/spray_paint/spray_paint.wav"); var TIP_OFFSET_Z = 0.02; var TIP_OFFSET_Y = 0.08; @@ -60,7 +60,7 @@ name: "streamEffect", isEmitting: true, position: position, - textures: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/spray_paint/smokeparticle.png", + textures: "https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/spray_paint/smokeparticle.png", emitSpeed: 3, speedSpread: 0.02, emitAcceleration: ZERO_VEC, diff --git a/unpublishedScripts/DomainContent/Toybox/targetsResetter.js b/unpublishedScripts/DomainContent/Toybox/targetsResetter.js index d8253fc48a..347fe89ac6 100644 --- a/unpublishedScripts/DomainContent/Toybox/targetsResetter.js +++ b/unpublishedScripts/DomainContent/Toybox/targetsResetter.js @@ -44,8 +44,8 @@ createTargets: function() { - var MODEL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/target.fbx'; - var COLLISION_HULL_URL = 'http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/ping_pong_gun/target_collision_hull.obj'; + var MODEL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/target.fbx'; + var COLLISION_HULL_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/ping_pong_gun/target_collision_hull.obj'; var MINIMUM_MOVE_LENGTH = 0.05; var RESET_DISTANCE = 0.5; From 97d578a36fe8abf34501c65f8f59808671d545f7 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Wed, 7 Oct 2020 19:45:10 -0400 Subject: [PATCH 042/127] https hifi-production DomainContent -> vircadia-content --- .../DomainContent/CellScience/Scripts/billboard.js | 2 +- .../DomainContent/CellScience/Scripts/clickToRideAndLook.js | 2 +- .../DomainContent/CellScience/Scripts/nav_button_cells.js | 2 +- .../DomainContent/CellScience/Scripts/nav_button_hexokinase.js | 2 +- .../CellScience/Scripts/nav_button_inside_the_cell.js | 2 +- .../DomainContent/CellScience/Scripts/nav_button_ribosome.js | 2 +- .../DomainContent/CellScience/Scripts/navigationButton.js | 2 +- .../DomainContent/CellScience/Scripts/showButtonToPlaySound.js | 2 +- .../DomainContent/CellScience/Scripts/showIdentification.js | 2 +- unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js | 2 +- unpublishedScripts/DomainContent/CellScience/importNow.js | 2 +- .../DomainContent/CellScience/motorProteinControllerAC.js | 2 +- unpublishedScripts/DomainContent/Toybox/bow/bow.js | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/billboard.js b/unpublishedScripts/DomainContent/CellScience/Scripts/billboard.js index b5e725cfcf..0e552e2107 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/billboard.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/billboard.js @@ -6,7 +6,7 @@ // -var spriteURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/Sprites/nucleosomes_sprite.fbx"; +var spriteURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/Sprites/nucleosomes_sprite.fbx"; var spriteDimensions = { x: 10, y: 10, diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/clickToRideAndLook.js b/unpublishedScripts/DomainContent/CellScience/Scripts/clickToRideAndLook.js index 61ccec9f9b..ed0fe770a4 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/clickToRideAndLook.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/clickToRideAndLook.js @@ -13,7 +13,7 @@ z: -1 } - var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/"; + var baseURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/"; var self = this; diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_cells.js b/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_cells.js index 2253bb8068..b33e081e5d 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_cells.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_cells.js @@ -9,7 +9,7 @@ var version = 13; - var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/"; + var baseURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/"; var button; var _this; diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_hexokinase.js b/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_hexokinase.js index 7ca8de64a6..cda2018a93 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_hexokinase.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_hexokinase.js @@ -15,7 +15,7 @@ var version = 13; - var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/"; + var baseURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/"; var button; var _this; diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_inside_the_cell.js b/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_inside_the_cell.js index 47cffa1a52..81f8494a36 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_inside_the_cell.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_inside_the_cell.js @@ -9,7 +9,7 @@ var version = 13; - var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/"; + var baseURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/"; var button; var _this; diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_ribosome.js b/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_ribosome.js index 95ec29a479..b4adebe865 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_ribosome.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/nav_button_ribosome.js @@ -8,7 +8,7 @@ var version = 13; - var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/"; + var baseURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/"; var button; var _this; diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/navigationButton.js b/unpublishedScripts/DomainContent/CellScience/Scripts/navigationButton.js index 9992c13acb..cd5f954525 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/navigationButton.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/navigationButton.js @@ -14,7 +14,7 @@ Script.include(utilsScript); var self = this; - var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/"; + var baseURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/"; this.preload = function(entityId) { this.entityId = entityId; diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/showButtonToPlaySound.js b/unpublishedScripts/DomainContent/CellScience/Scripts/showButtonToPlaySound.js index 6c1533371b..080f985908 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/showButtonToPlaySound.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/showButtonToPlaySound.js @@ -6,7 +6,7 @@ // (function() { - var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/"; + var baseURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/"; var self = this; this.buttonImageURL = baseURL + "GUI/play_audio.svg?2"; diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/showIdentification.js b/unpublishedScripts/DomainContent/CellScience/Scripts/showIdentification.js index c33caf8b37..f012fb00ba 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/showIdentification.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/showIdentification.js @@ -8,7 +8,7 @@ (function() { var self = this; - var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/"; + var baseURL = "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/"; var version = 3; this.preload = function(entityId) { diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js b/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js index 156774f8e3..f1c5ba592a 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js @@ -44,7 +44,7 @@ volume: 0.5 }; - self.teleportSound = SoundCache.getSound("https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/Audio/whoosh.wav"); + self.teleportSound = SoundCache.getSound("https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/Audio/whoosh.wav"); // print(" portal destination is " + self.portalDestination); } } diff --git a/unpublishedScripts/DomainContent/CellScience/importNow.js b/unpublishedScripts/DomainContent/CellScience/importNow.js index 0d06e60954..b6eb98d23e 100644 --- a/unpublishedScripts/DomainContent/CellScience/importNow.js +++ b/unpublishedScripts/DomainContent/CellScience/importNow.js @@ -38,7 +38,7 @@ function transformToSmallerWorld(vector) { } var cellLayout; -var baseLocation = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/"; +var baseLocation = "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/"; var utilsScript = Script.resolvePath('Scripts/utils.js'); Script.include(utilsScript); diff --git a/unpublishedScripts/DomainContent/CellScience/motorProteinControllerAC.js b/unpublishedScripts/DomainContent/CellScience/motorProteinControllerAC.js index 54f8d8a924..724effdc85 100644 --- a/unpublishedScripts/DomainContent/CellScience/motorProteinControllerAC.js +++ b/unpublishedScripts/DomainContent/CellScience/motorProteinControllerAC.js @@ -10,7 +10,7 @@ var numKinesin = 2; var percentOnMainMT = 100; -baseLocation = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/" +baseLocation = "https://cdn-1.vircadia.com/us-e-1/DomainContent/CellScience/" var WORLD_OFFSET = { x: 0, diff --git a/unpublishedScripts/DomainContent/Toybox/bow/bow.js b/unpublishedScripts/DomainContent/Toybox/bow/bow.js index 2bae1dc16e..5e39c2141d 100644 --- a/unpublishedScripts/DomainContent/Toybox/bow/bow.js +++ b/unpublishedScripts/DomainContent/Toybox/bow/bow.js @@ -16,7 +16,7 @@ var NOTCH_ARROW_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/notch.wav'; var SHOOT_ARROW_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/String_release2.L.wav'; var STRING_PULL_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/Bow_draw.1.L.wav'; - var ARROW_HIT_SOUND_URL = 'https://hifi-production.s3.amazonaws.com/DomainContent/Toybox/bow/Arrow_impact1.L.wav' + var ARROW_HIT_SOUND_URL = 'https://cdn-1.vircadia.com/us-e-1/DomainContent/Toybox/bow/Arrow_impact1.L.wav' var ARROW_DIMENSIONS = { x: 0.02, From fbae2d902b82d6838d36775b9f946d9a646ce451 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Wed, 7 Oct 2020 20:40:29 -0400 Subject: [PATCH 043/127] Update API docs to specify entity-server-script findEntities caveat. --- libraries/entities/src/EntityScriptingInterface.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index a8770bbd33..1954802828 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -709,6 +709,8 @@ public slots: /**jsdoc * Finds all domain and avatar entities that intersect a sphere. + *

    Note: Entity Server Scripts will only find entities that have a server script + * running on them. You can apply a dummy script to entities that you would like found in a search.

    * @function Entities.findEntities * @param {Vec3} center - The point about which to search. * @param {number} radius - The radius within which to search. @@ -723,6 +725,8 @@ public slots: /**jsdoc * Finds all domain and avatar entities whose axis-aligned boxes intersect a search axis-aligned box. + *

    Note: Entity Server Scripts will only find entities that have a server script + * running on them. You can apply a dummy script to entities that you would like found in a search.

    * @function Entities.findEntitiesInBox * @param {Vec3} corner - The corner of the search AA box with minimum co-ordinate values. * @param {Vec3} dimensions - The dimensions of the search AA box. @@ -734,6 +738,8 @@ public slots: /**jsdoc * Finds all domain and avatar entities whose axis-aligned boxes intersect a search frustum. + *

    Note: Entity Server Scripts will only find entities that have a server script + * running on them. You can apply a dummy script to entities that you would like found in a search.

    * @function Entities.findEntitiesInFrustum * @param {ViewFrustum} frustum - The frustum to search in. The position, orientation, * projection, and centerRadius properties must be specified. The fieldOfView @@ -749,6 +755,8 @@ public slots: /**jsdoc * Finds all domain and avatar entities of a particular type that intersect a sphere. + *

    Note: Entity Server Scripts will only find entities that have a server script + * running on them. You can apply a dummy script to entities that you would like found in a search.

    * @function Entities.findEntitiesByType * @param {Entities.EntityType} entityType - The type of entity to search for. * @param {Vec3} center - The point about which to search. @@ -764,6 +772,8 @@ public slots: /**jsdoc * Finds all domain and avatar entities with a particular name that intersect a sphere. + *

    Note: Entity Server Scripts will only find entities that have a server script + * running on them. You can apply a dummy script to entities that you would like found in a search.

    * @function Entities.findEntitiesByName * @param {string} entityName - The name of the entity to search for. * @param {Vec3} center - The point about which to search. From 114b255668d4bfb4e4d542c4458e55832374715e Mon Sep 17 00:00:00 2001 From: kasenvr <52365539+kasenvr@users.noreply.github.com> Date: Fri, 9 Oct 2020 00:41:59 -0400 Subject: [PATCH 044/127] Update libraries/entities/src/EntityScriptingInterface.h Co-authored-by: David Rowe --- libraries/entities/src/EntityScriptingInterface.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 1954802828..07e2f0e5a2 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -709,8 +709,8 @@ public slots: /**jsdoc * Finds all domain and avatar entities that intersect a sphere. - *

    Note: Entity Server Scripts will only find entities that have a server script - * running on them. You can apply a dummy script to entities that you would like found in a search.

    + *

    Note: Server entity scripts only find entities that have a server entity script + * running in them or a parent entity. You can apply a dummy script to entities that you want found in a search.

    * @function Entities.findEntities * @param {Vec3} center - The point about which to search. * @param {number} radius - The radius within which to search. From af8ee9980cac18e43e692f2185d8cc784cdb4b98 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Fri, 9 Oct 2020 00:43:05 -0400 Subject: [PATCH 045/127] CR --- .../entities/src/EntityScriptingInterface.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 07e2f0e5a2..fca0dad871 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -725,8 +725,8 @@ public slots: /**jsdoc * Finds all domain and avatar entities whose axis-aligned boxes intersect a search axis-aligned box. - *

    Note: Entity Server Scripts will only find entities that have a server script - * running on them. You can apply a dummy script to entities that you would like found in a search.

    + *

    Note: Server entity scripts only find entities that have a server entity script + * running in them or a parent entity. You can apply a dummy script to entities that you want found in a search.

    * @function Entities.findEntitiesInBox * @param {Vec3} corner - The corner of the search AA box with minimum co-ordinate values. * @param {Vec3} dimensions - The dimensions of the search AA box. @@ -738,8 +738,8 @@ public slots: /**jsdoc * Finds all domain and avatar entities whose axis-aligned boxes intersect a search frustum. - *

    Note: Entity Server Scripts will only find entities that have a server script - * running on them. You can apply a dummy script to entities that you would like found in a search.

    + *

    Note: Server entity scripts only find entities that have a server entity script + * running in them or a parent entity. You can apply a dummy script to entities that you want found in a search.

    * @function Entities.findEntitiesInFrustum * @param {ViewFrustum} frustum - The frustum to search in. The position, orientation, * projection, and centerRadius properties must be specified. The fieldOfView @@ -755,8 +755,8 @@ public slots: /**jsdoc * Finds all domain and avatar entities of a particular type that intersect a sphere. - *

    Note: Entity Server Scripts will only find entities that have a server script - * running on them. You can apply a dummy script to entities that you would like found in a search.

    + *

    Note: Server entity scripts only find entities that have a server entity script + * running in them or a parent entity. You can apply a dummy script to entities that you want found in a search.

    * @function Entities.findEntitiesByType * @param {Entities.EntityType} entityType - The type of entity to search for. * @param {Vec3} center - The point about which to search. @@ -772,8 +772,8 @@ public slots: /**jsdoc * Finds all domain and avatar entities with a particular name that intersect a sphere. - *

    Note: Entity Server Scripts will only find entities that have a server script - * running on them. You can apply a dummy script to entities that you would like found in a search.

    + *

    Note: Server entity scripts only find entities that have a server entity script + * running in them or a parent entity. You can apply a dummy script to entities that you want found in a search.

    * @function Entities.findEntitiesByName * @param {string} entityName - The name of the entity to search for. * @param {Vec3} center - The point about which to search. From e028943645b2616662d24fe29259c50ec76604e1 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Fri, 9 Oct 2020 13:33:48 -0700 Subject: [PATCH 046/127] CR --- interface/src/Application.cpp | 2 +- interface/src/FancyCamera.h | 4 ++++ libraries/shared/src/shared/Camera.h | 25 +++++++++++++------------ 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d8c4dde1a8..866d9ffe66 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2413,7 +2413,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo updateSystemTabletMode(); connect(&_myCamera, &Camera::modeUpdated, this, &Application::cameraModeChanged); - connect(&_myCamera, &Camera::captureMouseUpdated, this, &Application::captureMouseChanged); + connect(&_myCamera, &Camera::captureMouseChanged, this, &Application::captureMouseChanged); DependencyManager::get()->setShouldPickHUDOperator([]() { return DependencyManager::get()->isHMDMode(); }); DependencyManager::get()->setCalculatePos2DFromHUDOperator([this](const glm::vec3& intersection) { diff --git a/interface/src/FancyCamera.h b/interface/src/FancyCamera.h index 2a131d991f..afcd5197ff 100644 --- a/interface/src/FancyCamera.h +++ b/interface/src/FancyCamera.h @@ -36,6 +36,10 @@ class FancyCamera : public Camera { * @property {ViewFrustum} frustum - The camera frustum. * @property {Uuid} cameraEntity - The ID of the entity that is used for the camera position and orientation when the * camera is in entity mode. + * @property {boolean} captureMouse - The mouse capture state. When true, the mouse is invisible and cannot leave the bounds of + * Interface, as long as Interface is the active window and no menu item is selected. When false, the mouse + * behaves normally. + * @property {number} sensitivity - The current camera sensitivity. Must be positive. */ Q_PROPERTY(QUuid cameraEntity READ getCameraEntity WRITE setCameraEntity) diff --git a/libraries/shared/src/shared/Camera.h b/libraries/shared/src/shared/Camera.h index f6ce9be2d8..f494318c73 100644 --- a/libraries/shared/src/shared/Camera.h +++ b/libraries/shared/src/shared/Camera.h @@ -44,7 +44,7 @@ class Camera : public QObject { Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation) Q_PROPERTY(QString mode READ getModeString WRITE setModeString NOTIFY modeUpdated) Q_PROPERTY(QVariantMap frustum READ getViewFrustum CONSTANT) - Q_PROPERTY(bool captureMouse READ getCaptureMouse WRITE setCaptureMouse NOTIFY captureMouseUpdated) + Q_PROPERTY(bool captureMouse READ getCaptureMouse WRITE setCaptureMouse NOTIFY captureMouseChanged) Q_PROPERTY(float sensitivity READ getSensitivity WRITE setSensitivity) public: @@ -115,31 +115,32 @@ public slots: /**jsdoc * Gets the current mouse capture state. - * @function Camera.getMouseCapture - * @returns {boolean} The current mouse capture state. + * @function Camera.getCaptureMouse + * @returns {boolean} true if the mouse is captured (is invisible and cannot leave the bounds of Interface, + * if Interface is the active window and no menu item is selected), false if the mouse is behaving normally. */ bool getCaptureMouse() const { return _captureMouse; } /**jsdoc - * Sets the mouse capture state. When true, the mouse will be invisible and cannot leave the bounds of + * Sets the mouse capture state. When true, the mouse is invisible and cannot leave the bounds of * Interface, as long as Interface is the active window and no menu item is selected. When false, the mouse - * will behave normally. + * behaves normally. * @function Camera.setCaptureMouse * @param {boolean} captureMouse - true to capture the mouse, false to release the mouse. */ - void setCaptureMouse(bool captureMouse) { _captureMouse = captureMouse; emit captureMouseUpdated(captureMouse); } + void setCaptureMouse(bool captureMouse) { _captureMouse = captureMouse; emit captureMouseChanged(captureMouse); } /**jsdoc * Gets the current camera sensitivity. * @function Camera.getSensitivity - * @returns {boolean} The current camera sensitivity. + * @returns {number} The current camera sensitivity. Must be positive. */ float getSensitivity() const { return _sensitivity; } /**jsdoc * Sets the camera sensitivity. Higher values mean that the camera will be more sensitive to mouse movements. * @function Camera.setSensitivity - * @param {boolean} sensitivity - The desired camera sensitivity. + * @param {number} sensitivity - The desired camera sensitivity. Must be positive. */ void setSensitivity(float sensitivity) { _sensitivity = glm::max(0.0f, sensitivity); } @@ -216,17 +217,17 @@ signals: /**jsdoc * Triggered when the camera mouse capture state changes. - * @function Camera.captureMouseUpdated + * @function Camera.captureMouseChanged * @param {boolean} newCaptureMouse - The new mouse capture state. * @returns {Signal} * @example Report mouse capture state changes. - * function onCaptureMouseUpdated(newCaptureMouse) { + * function onCaptureMouseChanged(newCaptureMouse) { * print("The mouse capture has changed to " + newCaptureMouse); * } * - * Camera.captureMouseUpdated.connect(onCaptureMouseUpdated); + * Camera.captureMouseChanged.connect(onCaptureMouseChanged); */ - void captureMouseUpdated(bool newCaptureMouse); + void captureMouseChanged(bool newCaptureMouse); private: void recompose(); From adf6652e24cf5ba3237fd319653e618f22556418 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Fri, 9 Oct 2020 22:14:53 -0400 Subject: [PATCH 047/127] Put "Cut" before Copy" to be standard Put "Cut" before Copy" to be standard --- scripts/system/create/entityList/html/entityList.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index 26b6ec6f00..824ca380ec 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -32,8 +32,8 @@
  • - +
    From 2e75166e0de4c08c8b30a6463a3e62fa8c2c4365 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Sun, 11 Oct 2020 21:10:24 -0400 Subject: [PATCH 048/127] Hide temp place name button, hide places table, hide places wizard step. --- domain-server/resources/web/settings/js/settings.js | 13 ++++++++----- domain-server/resources/web/wizard/index.shtml | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/domain-server/resources/web/settings/js/settings.js b/domain-server/resources/web/settings/js/settings.js index 8a9971d520..18d07fa6ef 100644 --- a/domain-server/resources/web/settings/js/settings.js +++ b/domain-server/resources/web/settings/js/settings.js @@ -40,6 +40,8 @@ $(document).ready(function(){ // call our method to setup the place names table setupPlacesTable(); + // hide the places table for now because we do not want that interacted with from the domain-server + $('#' + Settings.PLACES_TABLE_ID).hide(); setupDomainNetworkingSettings(); // setupDomainLabelSetting(); @@ -711,8 +713,8 @@ $(document).ready(function(){ name: 'places', label: 'Places', html_id: Settings.PLACES_TABLE_ID, - help: "The following places currently point to this domain.
    To point places to this domain, " - + " go to the
    My Places " + help: "To point places to this domain, " + + " go to the Places " + "page in your Metaverse account.", read_only: true, can_add_new_rows: false, @@ -745,9 +747,10 @@ $(document).ready(function(){ var errorEl = createDomainLoadingError("There was an error retrieving your places."); $("#" + Settings.PLACES_TABLE_ID).after(errorEl); - var temporaryPlaceButton = dynamicButton(Settings.GET_TEMPORARY_NAME_BTN_ID, 'Get a temporary place name'); - temporaryPlaceButton.hide(); - $('#' + Settings.PLACES_TABLE_ID).after(temporaryPlaceButton); + // DISABLE TEMP PLACE NAME BUTTON... + // var temporaryPlaceButton = dynamicButton(Settings.GET_TEMPORARY_NAME_BTN_ID, 'Get a temporary place name'); + // temporaryPlaceButton.hide(); + // $('#' + Settings.PLACES_TABLE_ID).after(temporaryPlaceButton); if (accessTokenIsSet()) { appendAddButtonToPlacesTable(); } diff --git a/domain-server/resources/web/wizard/index.shtml b/domain-server/resources/web/wizard/index.shtml index 4093eda39a..c15b4169ed 100644 --- a/domain-server/resources/web/wizard/index.shtml +++ b/domain-server/resources/web/wizard/index.shtml @@ -19,7 +19,7 @@
    -
    @@ -102,5 +91,97 @@
    +
    + + + + + + + + + + + +
    +
    + + + + + + +
    + From 9004251bcffbfdd83828bfe559d2b8a8c9b793a9 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 18 Oct 2020 21:59:14 -0400 Subject: [PATCH 077/127] Add "Actions" and "Selection" menu Add "Actions" and "Selection" menu in the Create App. (HMD/Desktop compliant) --- .../create/entityList/html/js/entityList.js | 128 ++++++++++++++++-- 1 file changed, 115 insertions(+), 13 deletions(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index aa40d5286f..949b8684c8 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -200,7 +200,10 @@ let elEntityTable, elRefresh, elToggleLocked, elToggleVisible, - elHmdMultiSelect, + elActionsMenu, + elSelectionMenu, + elMenuBackgroundOverlay, + elHmdMultiSelect, elHmdCopy, elHmdCut, elHmdPaste, @@ -210,6 +213,11 @@ let elEntityTable, elParent, elUnparent, elDelete, + elSelectAll, + elSelectInverse, + elSelectNone, + elSelectAllInBox, + elSelectAllTouchingBox, elFilterTypeMultiselectBox, elFilterTypeText, elFilterTypeOptions, @@ -252,8 +260,11 @@ function loaded() { elEntityTableScroll = document.getElementById("entity-table-scroll"); elRefresh = document.getElementById("refresh"); elToggleLocked = document.getElementById("locked"); - elToggleVisible = document.getElementById("visible"); + elToggleVisible = document.getElementById("visible"); elHmdMultiSelect = document.getElementById("hmdmultiselect"); + elActionsMenu = document.getElementById("actions"); + elSelectionMenu = document.getElementById("selection"); + elMenuBackgroundOverlay = document.getElementById("menuBackgroundOverlay"); elHmdCopy = document.getElementById("hmdcopy"); elHmdCut = document.getElementById("hmdcut"); elHmdPaste = document.getElementById("hmdpaste"); @@ -263,6 +274,11 @@ function loaded() { elParent = document.getElementById("parent"); elUnparent = document.getElementById("unparent"); elDelete = document.getElementById("delete"); + elSelectAll = document.getElementById("selectall"); + elSelectInverse = document.getElementById("selectinverse"); + elSelectNone = document.getElementById("selectnone"); + elSelectAllInBox = document.getElementById("selectallinbox"); + elSelectAllTouchingBox = document.getElementById("selectalltouchingbox"); elFilterTypeMultiselectBox = document.getElementById("filter-type-multiselect-box"); elFilterTypeText = document.getElementById("filter-type-text"); elFilterTypeOptions = document.getElementById("filter-type-options"); @@ -300,32 +316,119 @@ function loaded() { } EventBridge.emitWebEvent(JSON.stringify({ type: 'hmdMultiSelectMode', value: hmdMultiSelectMode })); }; + elActionsMenu.onclick = function() { + + document.getElementById("menuBackgroundOverlay").style.display = "block"; + document.getElementById("actions-menu").style.display = "block"; + }; + elSelectionMenu.onclick = function() { + document.getElementById("menuBackgroundOverlay").style.display = "block"; + document.getElementById("selection-menu").style.display = "block"; + }; + elMenuBackgroundOverlay.onclick = function() { + closeAllEntityListMenu(); + }; elHmdCopy.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'copy' })); + closeAllEntityListMenu(); }; elHmdCut.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'cut' })); + closeAllEntityListMenu(); }; elHmdPaste.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'paste' })); + closeAllEntityListMenu(); }; elHmdDuplicate.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'duplicate' })); + closeAllEntityListMenu(); }; elParent.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'parent' })); + closeAllEntityListMenu(); }; elUnparent.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'unparent' })); + closeAllEntityListMenu(); }; elUndo.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'undo' })); + closeAllEntityListMenu(); }; elRedo.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'redo' })); + closeAllEntityListMenu(); }; elDelete.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); + closeAllEntityListMenu(); + }; + elSelectAll.onclick = function() { + + let visibleEntityIDs = visibleEntities.map(visibleEntity => visibleEntity.id); + let selectionIncludesAllVisibleEntityIDs = visibleEntityIDs.every(visibleEntityID => { + return selectedEntities.includes(visibleEntityID); + }); + + let selection = []; + + if (!selectionIncludesAllVisibleEntityIDs) { + selection = visibleEntityIDs; + } + + updateSelectedEntities(selection, false); + + EventBridge.emitWebEvent(JSON.stringify({ + "type": "selectionUpdate", + "focus": false, + "entityIds": selection + })); + + closeAllEntityListMenu(); + }; + elSelectInverse.onclick = function() { + let visibleEntityIDs = visibleEntities.map(visibleEntity => visibleEntity.id); + let selectionIncludesAllVisibleEntityIDs = visibleEntityIDs.every(visibleEntityID => { + return selectedEntities.includes(visibleEntityID); + }); + + let selection = []; + + if (!selectionIncludesAllVisibleEntityIDs) { + visibleEntityIDs.forEach(function(id) { + if (!selectedEntities.includes(id)) { + selection.push(id); + } + }); + } + + updateSelectedEntities(selection, false); + + EventBridge.emitWebEvent(JSON.stringify({ + "type": "selectionUpdate", + "focus": false, + "entityIds": selection + })); + + closeAllEntityListMenu(); + }; + elSelectNone.onclick = function() { + updateSelectedEntities([], false); + EventBridge.emitWebEvent(JSON.stringify({ + "type": "selectionUpdate", + "focus": false, + "entityIds": [] + })); + closeAllEntityListMenu(); + }; + elSelectAllInBox.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'selectAllInBox' })); + closeAllEntityListMenu(); + }; + elSelectAllTouchingBox.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'selectAllTouchingBox' })); + closeAllEntityListMenu(); }; elToggleSpaceMode.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleSpaceMode' })); @@ -871,7 +974,7 @@ function loaded() { function updateSelectedEntities(selectedIDs, autoScroll) { let notFound = false; - + // reset all currently selected entities and their rows first selectedEntities.forEach(function(id) { let entity = entitiesByID[id]; @@ -882,7 +985,7 @@ function loaded() { } } }); - + // then reset selected entities list with newly selected entities and set them selected selectedEntities = []; selectedIDs.forEach(function(id) { @@ -1454,16 +1557,8 @@ function loaded() { } else if (data.type === "confirmHMDstate") { if (data.isHmd) { document.getElementById("hmdmultiselect").style.display = "inline"; - document.getElementById("hmdcopy").style.display = "inline"; - document.getElementById("hmdcut").style.display = "inline"; - document.getElementById("hmdpaste").style.display = "inline"; - document.getElementById("hmdduplicate").style.display = "inline"; } else { - document.getElementById("hmdmultiselect").style.display = "none"; - document.getElementById("hmdcopy").style.display = "none"; - document.getElementById("hmdcut").style.display = "none"; - document.getElementById("hmdpaste").style.display = "none"; - document.getElementById("hmdduplicate").style.display = "none"; + document.getElementById("hmdmultiselect").style.display = "none"; } } }); @@ -1489,4 +1584,11 @@ function loaded() { $(window).blur(function() { entityListContextMenu.close(); }); + + function closeAllEntityListMenu() { + document.getElementById("menuBackgroundOverlay").style.display = "none"; + document.getElementById("selection-menu").style.display = "none"; + document.getElementById("actions-menu").style.display = "none"; + } + } From 3241ea7c1f3ec4973ba746dedd3cafa2ebe6e11b Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 18 Oct 2020 22:59:08 -0400 Subject: [PATCH 078/127] Add support for teleportToEntity Add support for teleportToEntity --- .../create/entitySelectionTool/entitySelectionTool.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index 0250ead0a9..b218d8b986 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -636,6 +636,16 @@ SelectionManager = (function() { } }; + that.teleportToEntity = function() { + if (SelectionManager.hasSelection()) { + var distanceFromTarget = 3 + Math.max(Math.max(SelectionManager.worldDimensions.x, SelectionManager.worldDimensions.y), SelectionManager.worldDimensions.z); + var teleportTargetPosition = Vec3.sum(SelectionManager.worldPosition, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: distanceFromTarget })); + MyAvatar.goToLocation(teleportTargetPosition, false); + } else { + audioFeedback.rejection(); + } + }; + return that; })(); From 8c94d20177983fa06ef7dcbbb8a4bbe45976ce3f Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 18 Oct 2020 23:00:31 -0400 Subject: [PATCH 079/127] Add support for teleportToEntity Add support for teleportToEntity --- scripts/system/create/entityList/entityList.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 80cf2cbdc8..3835e448ec 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -327,6 +327,8 @@ EntityListTool = function(shouldUseEditTabletApp) { selectAllEntitiesInCurrentSelectionBox(false); } else if (data.type === 'selectAllTouchingBox') { selectAllEntitiesInCurrentSelectionBox(true); + } else if (data.type === 'teleportToEntity') { + SelectionManager.teleportToEntity(); } }; From 943ae9aa4cf4eebdd3026c04a14c0a3af068a7f6 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 18 Oct 2020 23:01:10 -0400 Subject: [PATCH 080/127] Add support for teleportToEntity Add support for teleportToEntity --- scripts/system/create/entityList/html/entityList.html | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index f06dc86855..e2ac043039 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -180,7 +180,14 @@ - + + + From 4c74d5a63006473492fb508528c4ddb57c651a7d Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 18 Oct 2020 23:01:55 -0400 Subject: [PATCH 081/127] Add support for teleportToEntity Add support for teleportToEntity --- scripts/system/create/entityList/html/js/entityList.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index 949b8684c8..c40b4e67a8 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -218,6 +218,7 @@ let elEntityTable, elSelectNone, elSelectAllInBox, elSelectAllTouchingBox, + elTeleportToEntity, elFilterTypeMultiselectBox, elFilterTypeText, elFilterTypeOptions, @@ -278,7 +279,8 @@ function loaded() { elSelectInverse = document.getElementById("selectinverse"); elSelectNone = document.getElementById("selectnone"); elSelectAllInBox = document.getElementById("selectallinbox"); - elSelectAllTouchingBox = document.getElementById("selectalltouchingbox"); + elSelectAllTouchingBox = document.getElementById("selectalltouchingbox"); + elTeleportToEntity = document.getElementById("teleport-to-entity"); elFilterTypeMultiselectBox = document.getElementById("filter-type-multiselect-box"); elFilterTypeText = document.getElementById("filter-type-text"); elFilterTypeOptions = document.getElementById("filter-type-options"); @@ -430,6 +432,10 @@ function loaded() { EventBridge.emitWebEvent(JSON.stringify({ type: 'selectAllTouchingBox' })); closeAllEntityListMenu(); }; + elTeleportToEntity.onclick = function () { + EventBridge.emitWebEvent(JSON.stringify({ type: "teleportToEntity" })); + closeAllEntityListMenu(); + }; elToggleSpaceMode.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleSpaceMode' })); }; From d0de5154fed211a7b7c3aef157345f99efed2f9e Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 18 Oct 2020 23:22:17 -0400 Subject: [PATCH 082/127] Fix for Issue #711 Fix for Issue: #711 Add error dialogue if an unsupported filetype is added as a model URL in the create app. As agreed, the label "Model URL" will indicate now: "Model URL (.fbx, .fst, .glb, .gltf, .obj, .gz)" The list of file type has been set in Italic. And the label for Material dialog has been adjust to have the same standard "(Optional)" is also in italic. --- scripts/system/create/qml/NewMaterialDialog.qml | 2 +- scripts/system/create/qml/NewModelDialog.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/qml/NewMaterialDialog.qml b/scripts/system/create/qml/NewMaterialDialog.qml index 3cc619e176..e08ca868b6 100644 --- a/scripts/system/create/qml/NewMaterialDialog.qml +++ b/scripts/system/create/qml/NewMaterialDialog.qml @@ -55,7 +55,7 @@ Rectangle { Text { id: text1 - text: qsTr("Material URL (Optional)") + text: qsTr("Material URL (Optional)") color: "#ffffff" font.pixelSize: 12 } diff --git a/scripts/system/create/qml/NewModelDialog.qml b/scripts/system/create/qml/NewModelDialog.qml index dd4ef3c8ad..758706a79b 100644 --- a/scripts/system/create/qml/NewModelDialog.qml +++ b/scripts/system/create/qml/NewModelDialog.qml @@ -55,7 +55,7 @@ Rectangle { Text { id: text1 - text: qsTr("Model URL") + text: qsTr("Model URL (.fbx, .fst, .glb, .gltf, .obj, .gz)") color: "#ffffff" font.pixelSize: 12 } From 1aa09f59c33c1ec8d3ffce7cfa1366ab8a97eee1 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 18 Oct 2020 23:34:36 -0400 Subject: [PATCH 083/127] Increase the precison of Angular Velocity Increase the precison of Angular Velocity to make more comfortable the Issue #798 Angular Velocity can't go below 0.4 something (round to 0.5) But this won't solve the trouble. For this it would require a fixed for issue #76 Rotations that are transmitted over server lose precision --- .../system/create/entityProperties/html/js/entityProperties.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityProperties/html/js/entityProperties.js b/scripts/system/create/entityProperties/html/js/entityProperties.js index 8364d5b155..f3f92a887e 100644 --- a/scripts/system/create/entityProperties/html/js/entityProperties.js +++ b/scripts/system/create/entityProperties/html/js/entityProperties.js @@ -1618,7 +1618,8 @@ const GROUPS = [ type: "vec3", vec3Type: "pyr", multiplier: DEGREES_TO_RADIANS, - decimals: 4, + decimals: 6, + step: 1, subLabels: [ "x", "y", "z" ], unit: "deg/s", propertyID: "localAngularVelocity", From 413c21f4827032b56e8f2d2d9883bd30940bed06 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Mon, 19 Oct 2020 01:07:07 -0400 Subject: [PATCH 084/127] Append Vircadia to the environment variable for the metadata exporter port. --- libraries/networking/src/DomainHandler.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index f77ff2bb5b..56d32d8609 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -76,9 +76,9 @@ const quint16 DOMAIN_SERVER_EXPORTER_PORT = const quint16 DOMAIN_SERVER_METADATA_EXPORTER_PORT = QProcessEnvironment::systemEnvironment() - .contains("DOMAIN_SERVER_METADATA_EXPORTER_PORT") + .contains("VIRCADIA_DOMAIN_SERVER_METADATA_EXPORTER_PORT") ? QProcessEnvironment::systemEnvironment() - .value("DOMAIN_SERVER_METADATA_EXPORTER_PORT") + .value("VIRCADIA_DOMAIN_SERVER_METADATA_EXPORTER_PORT") .toUInt() : 9704; From c3719a753880bd86ce835548fdcd3b21e099b739 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 20 Oct 2020 00:15:40 -0400 Subject: [PATCH 085/127] Add "Move Selected Entity To Avatar" Add "Move Selected Entity To Avatar" --- .../entitySelectionTool.js | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index b218d8b986..685eadae90 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -637,15 +637,42 @@ SelectionManager = (function() { }; that.teleportToEntity = function() { - if (SelectionManager.hasSelection()) { - var distanceFromTarget = 3 + Math.max(Math.max(SelectionManager.worldDimensions.x, SelectionManager.worldDimensions.y), SelectionManager.worldDimensions.z); - var teleportTargetPosition = Vec3.sum(SelectionManager.worldPosition, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: distanceFromTarget })); + if (that.hasSelection()) { + var distanceFromTarget = 3 + Math.max(Math.max(that.worldDimensions.x, that.worldDimensions.y), that.worldDimensions.z); + var teleportTargetPosition = Vec3.sum(that.worldPosition, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: distanceFromTarget })); MyAvatar.goToLocation(teleportTargetPosition, false); } else { audioFeedback.rejection(); } }; + that.moveEntitiesSelectionToAvatar = function() { + if (that.hasSelection()) { + that.saveProperties(); + var distanceFromTarget = 3 + Math.max(Math.max(that.worldDimensions.x, that.worldDimensions.y), that.worldDimensions.z); + var targetPosition = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -distanceFromTarget })); + // editing a parent will cause all the children to automatically follow along, so don't + // edit any entity who has an ancestor in that.selections + var toMove = that.selections.filter(function (selection) { + if (that.selections.indexOf(that.savedProperties[selection].parentID) >= 0) { + return false; // a parent is also being moved, so don't issue an edit for this entity + } else { + return true; + } + }); + for (var i = 0; i < toMove.length; i++) { + var id = toMove[i]; + var properties = that.savedProperties[id]; + var relativePosition = Vec3.subtract(properties.position, that.worldPosition); + var newPosition = Vec3.sum(relativePosition, targetPosition); + Entities.editEntity(id, { "position": newPosition }); + } + that._update(false, this); + } else { + audioFeedback.rejection(); + } + }; + return that; })(); From 6d7d9a3dde67a008033864d3b7230e6521ef025b Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 20 Oct 2020 00:16:38 -0400 Subject: [PATCH 086/127] Add "Move Selected Entity To Avatar" Add "Move Selected Entity To Avatar" --- scripts/system/create/entityList/entityList.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 3835e448ec..20434484a1 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -329,6 +329,8 @@ EntityListTool = function(shouldUseEditTabletApp) { selectAllEntitiesInCurrentSelectionBox(true); } else if (data.type === 'teleportToEntity') { SelectionManager.teleportToEntity(); + } else if (data.type === 'moveEntitySelectionToAvatar') { + SelectionManager.moveEntitiesSelectionToAvatar(); } }; From 5924a65eebd817dfcfb2c1ad083d822f77b67cd8 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Tue, 20 Oct 2020 00:17:11 -0400 Subject: [PATCH 087/127] Add "Move Selected Entity To Avatar" Add "Move Selected Entity To Avatar" --- scripts/system/create/entityList/html/entityList.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index e2ac043039..df8652ddd6 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -148,6 +148,13 @@ + +
    - - + +
    From fdae7877e1f1c26c5efdaca26665b0da2345aba3 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 00:46:15 -0400 Subject: [PATCH 090/127] Add Hierarchy display in List and Selection Add Hierarchy display in List and Selection --- scripts/system/html/css/edit-style.css | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 842a4e27f1..2ba68e505b 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -1456,6 +1456,11 @@ input[type=button]#export { font-size: 15px; } +#entity-table-scroll .vglyph { + font-family: Vircadia-Glyphs; + font-size: 15px; +} + #entity-table { margin-top: -28px; margin-bottom: -18px; @@ -1468,7 +1473,7 @@ input[type=button]#export { background: none; } -#entity-table .glyph { +#entity-table .glyph .vglyph { margin: 0 -2px 0 -2px; vertical-align: middle; } @@ -1501,11 +1506,11 @@ input[type=button]#export { outline: none; } -#entity-table th .glyph { +#entity-table th .glyph .vglyph { position: relative; left: 4px; } -#entity-table th .glyph + .sort-order { +#entity-table th .glyph .vglyph + .sort-order { position: relative; left: 4px; } @@ -1532,7 +1537,7 @@ input[type=button]#export { #entity-table td { box-sizing: border-box; } -#entity-table td.glyph { +#entity-table td .glyph .vglyph { text-align: center; padding: 0; } @@ -1877,7 +1882,7 @@ div.multiZoneSelToolbar { left:0; right:0; bottom:0; - display:block; + display:none; } div.entity-list-menu { From 8afa9781225998553a3a8af5f05129f2f854e13e Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 00:47:10 -0400 Subject: [PATCH 091/127] Add Hierarchy display in List and Selection Add Hierarchy display in List and Selection --- scripts/system/create/edit.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index 5c488a71ee..35bcd45786 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -1720,6 +1720,9 @@ function unparentSelectedEntities() { } else { Window.notify("Entity unparented"); } + //Refresh + entityListTool.sendUpdate(); + selectionManager._update(false, this); } else { audioFeedback.rejection(); if (selectedEntities.length > 1) { @@ -1756,6 +1759,9 @@ function parentSelectedEntities() { if (parentCheck) { audioFeedback.confirmation(); Window.notify("Entities parented"); + //Refresh + entityListTool.sendUpdate(); + selectionManager._update(false, this); } else { audioFeedback.rejection(); Window.notify("Entities are already parented to last"); @@ -2963,4 +2969,22 @@ function zoneSortOrder(a, b) { return 0; } +function getParentState(id) { + var state = "NONE"; + var properties = Entities.getEntityProperties(id, ["parentID"]); + var children = Entities.getChildrenIDs(id); + if (properties.parentID !== Uuid.NULL) { + if (children.length > 0) { + state = "PARENT_CHILDREN"; + } else { + state = "CHILDREN"; + } + } else { + if (children.length > 0) { + state = "PARENT"; + } + } + return state; +} + }()); // END LOCAL_SCOPE From 48bd101d08cad848b012b47b9bc6c2018b8e64bc Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 00:47:55 -0400 Subject: [PATCH 092/127] Add Hierarchy display in List and Selection Add Hierarchy display in List and Selection --- .../entitySelectionTool.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index 685eadae90..0f8c8cc8bf 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -697,8 +697,10 @@ SelectionDisplay = (function() { const COLOR_HOVER = { red: 255, green: 220, blue: 82 }; const COLOR_DUPLICATOR = { red: 162, green: 0, blue: 255 }; const COLOR_ROTATE_CURRENT_RING = { red: 255, green: 99, blue: 9 }; - const COLOR_BOUNDING_EDGE = { red: 128, green: 128, blue: 128 }; - const COLOR_SCALE_CUBE = { red: 160, green: 160, blue: 160 }; + const COLOR_BOUNDING_EDGE = { red: 160, green: 160, blue: 160 }; + const COLOR_BOUNDING_EDGE_PARENT = { red: 194, green: 123, blue: 0 }; //{ red: 255, green: 160, blue: 0 }; + const COLOR_BOUNDING_EDGE_CHILDREN = { red: 0, green: 168, blue: 214 }; // { red: 0, green: 200, blue: 255 } + const COLOR_SCALE_CUBE = { red: 192, green: 192, blue: 192 }; const COLOR_DEBUG_PICK_PLANE = { red: 255, green: 255, blue: 255 }; const COLOR_DEBUG_PICK_PLANE_HIT = { red: 255, green: 165, blue: 0 }; @@ -1828,6 +1830,18 @@ SelectionDisplay = (function() { var rotationZ = Quat.multiply(rotation, localRotationZ); worldRotationZ = rotationZ; + var handleBoundingBoxColor = COLOR_BOUNDING_EDGE; + if (SelectionManager.selections.length === 1) { + var parentState = getParentState(SelectionManager.selections[0]); + if (parentState === "CHILDREN") { + handleBoundingBoxColor = COLOR_BOUNDING_EDGE_CHILDREN; + } else { + if (parentState === "PARENT" || parentState === "PARENT_CHILDREN") { + handleBoundingBoxColor = COLOR_BOUNDING_EDGE_PARENT; + } + } + } + var selectionBoxGeometry = { position: position, rotation: rotation, @@ -1949,6 +1963,7 @@ SelectionDisplay = (function() { Entities.editEntity(handleBoundingBox, { position: position, rotation: rotation, + color: handleBoundingBoxColor, dimensions: dimensions }); From cfec2c492b15dd7ef6128155180c4a7ce16c80fe Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 00:48:49 -0400 Subject: [PATCH 093/127] Add Hierarchy display in List and Selection Add Hierarchy display in List and Selection --- scripts/system/create/entityList/entityList.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 20434484a1..cb6beeaa4a 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -203,6 +203,17 @@ EntityListTool = function(shouldUseEditTabletApp) { } else if (properties.type === "Image") { url = properties.imageURL; } + + var parentStatus = getParentState(ids[i]); + var parentState = ""; + if (parentStatus === "PARENT") { + parentState = "N"; + } else if (parentStatus === "CHILDREN") { + parentState = "O"; + } else if (parentStatus === "PARENT_CHILDREN") { + parentState = "M"; + } + entities.push({ id: ids[i], name: properties.name, @@ -222,7 +233,8 @@ EntityListTool = function(shouldUseEditTabletApp) { isBaked: entityIsBaked(properties), drawCalls: (properties.renderInfo !== undefined ? valueIfDefined(properties.renderInfo.drawCalls) : ""), - hasScript: properties.script !== "" + hasScript: properties.script !== "", + parentState: parentState }); } } From 46bb29bded2c21498836d08ee19da64c7f63692d Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 00:49:36 -0400 Subject: [PATCH 094/127] Add Hierarchy display in List and Selection Add Hierarchy display in List and Selection From 8baebbdd16aed3ed5d35524b8c4dd839d07dc688 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 00:50:28 -0400 Subject: [PATCH 095/127] Add Hierarchy display in List and Selection Add Hierarchy display in List and Selection --- .../create/entityList/html/js/entityList.js | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index 74112047f1..b6e682e0c2 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -134,6 +134,14 @@ const COLUMNS = { initialWidth: 0.06, defaultSortOrder: DESCENDING_SORT, }, + parentState: { + columnHeader: "M", + vglyph: true, + dropdownLabel: "Hierarchy", + propertyID: "parentState", + initialWidth: 0.04, + defaultSortOrder: DESCENDING_SORT, + }, }; const FILTER_TYPES = [ @@ -499,9 +507,12 @@ function loaded() { elTh.setAttribute("id", thID); elTh.setAttribute("columnIndex", columnIndex); elTh.setAttribute("columnID", columnID); - if (columnData.glyph) { + if (columnData.glyph || columnData.vglyph) { let elGlyph = document.createElement("span"); elGlyph.className = "glyph"; + if (columnData.vglyph) { + elGlyph.className = "vglyph"; + } elGlyph.innerHTML = columnData.columnHeader; elTh.appendChild(elGlyph); } else { @@ -801,10 +812,11 @@ function loaded() { isBaked: entity.isBaked, drawCalls: displayIfNonZero(entity.drawCalls), hasScript: entity.hasScript, + parentState: entity.parentState, elRow: null, // if this entity has a visible row element assigned to it selected: false // if this entity is selected for edit regardless of having a visible row }; - + entities.push(entityData); entitiesByID[entityData.id] = entityData; }); @@ -1060,6 +1072,8 @@ function loaded() { let elCell = elRow.childNodes[i]; if (column.data.glyph) { elCell.innerHTML = itemData[column.data.propertyID] ? column.data.columnHeader : null; + } else if (column.data.vglyph) { + elCell.innerHTML = itemData[column.data.propertyID]; } else { let value = itemData[column.data.propertyID]; if (column.data.format) { @@ -1147,6 +1161,9 @@ function loaded() { let column = columnsByID[columnID]; let visible = column.elTh.style.visibility !== "hidden"; let className = column.data.glyph ? "glyph" : ""; + if (column.data.vglyph) { + className = "vglyph"; + } className += visible ? "" : " hidden"; return className; } From 4c1de14cbbda078172e95e9bb9c24362945b1b4f Mon Sep 17 00:00:00 2001 From: Kalila L Date: Wed, 21 Oct 2020 00:56:55 -0400 Subject: [PATCH 096/127] Add input error handling and notice. --- domain-server/resources/web/js/shared.js | 2 -- domain-server/resources/web/wizard/js/wizard.js | 17 ++++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/domain-server/resources/web/js/shared.js b/domain-server/resources/web/js/shared.js index 0395106297..bffd512890 100644 --- a/domain-server/resources/web/js/shared.js +++ b/domain-server/resources/web/js/shared.js @@ -522,8 +522,6 @@ function createDomainIDPrompt(callback) { if (callback) { callback(inputValue); } - - swal.close(); }); } diff --git a/domain-server/resources/web/wizard/js/wizard.js b/domain-server/resources/web/wizard/js/wizard.js index 6c46a3b35c..6039c68cfa 100644 --- a/domain-server/resources/web/wizard/js/wizard.js +++ b/domain-server/resources/web/wizard/js/wizard.js @@ -179,7 +179,14 @@ function promptToCreateDomainID() { "label": label }; - $.post("/api/domains", domainJSON, function (data) { + $.post("/api/domainsss", domainJSON, function (data) { + if (data.status === "failure") { + swal.showInputError("Error: " + data.error); + return; + } + + swal.close(); + // we successfully created a domain ID, set it on that field var domainID = data.domain.domainId; console.log("Setting domain ID to ", data, domainID); @@ -192,9 +199,13 @@ function promptToCreateDomainID() { // POST the form JSON to the domain-server settings.json endpoint so the settings are saved postSettings(formJSON, goToNextStep); - }, 'json').fail(function () { + }, 'json').fail(function (data) { + if (data && data.status === "failure") { + swal.showInputError("Error: " + data.error); + } else { + swal.showInputError("Error: Failed to post to metaverse."); + } console.log("Failed to create domain ID..."); - goToNextStep(); }); }); }, 500); // Apparently swal needs time before opening another prompt. From c1a47878b935abecd1332518f12582a24fecd3fc Mon Sep 17 00:00:00 2001 From: Kalila L Date: Wed, 21 Oct 2020 00:57:30 -0400 Subject: [PATCH 097/127] Fix indent. --- domain-server/resources/web/wizard/js/wizard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/resources/web/wizard/js/wizard.js b/domain-server/resources/web/wizard/js/wizard.js index 6039c68cfa..1350de7205 100644 --- a/domain-server/resources/web/wizard/js/wizard.js +++ b/domain-server/resources/web/wizard/js/wizard.js @@ -199,7 +199,7 @@ function promptToCreateDomainID() { // POST the form JSON to the domain-server settings.json endpoint so the settings are saved postSettings(formJSON, goToNextStep); - }, 'json').fail(function (data) { + }, 'json').fail(function (data) { if (data && data.status === "failure") { swal.showInputError("Error: " + data.error); } else { From 35210fdb3259a266da5175e7047156e4144b488c Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 01:12:48 -0400 Subject: [PATCH 098/127] Add Hierarchy display in List and Selection Add Hierarchy display in List and Selection --- interface/resources/fonts/vircadia_glyphs.ttf | Bin 4660 -> 5240 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/interface/resources/fonts/vircadia_glyphs.ttf b/interface/resources/fonts/vircadia_glyphs.ttf index b6a8c2e7ad4c30ed5d6d713f6590cae1f5a27f10..f7e9d7f372c88e34027d1ab63880127354150ed1 100644 GIT binary patch literal 5240 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 Ck#F?? From 70b04b12268fd71ceb3486e047cc4fa2c47c4be6 Mon Sep 17 00:00:00 2001 From: kasenvr <52365539+kasenvr@users.noreply.github.com> Date: Wed, 21 Oct 2020 16:42:10 -0400 Subject: [PATCH 099/127] Update wizard.js --- domain-server/resources/web/wizard/js/wizard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/resources/web/wizard/js/wizard.js b/domain-server/resources/web/wizard/js/wizard.js index 1350de7205..d7eda38055 100644 --- a/domain-server/resources/web/wizard/js/wizard.js +++ b/domain-server/resources/web/wizard/js/wizard.js @@ -179,7 +179,7 @@ function promptToCreateDomainID() { "label": label }; - $.post("/api/domainsss", domainJSON, function (data) { + $.post("/api/domains", domainJSON, function (data) { if (data.status === "failure") { swal.showInputError("Error: " + data.error); return; From affad6741ca4dafaffe0d45f98a5e74cdcb93818 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Wed, 21 Oct 2020 22:44:55 -0400 Subject: [PATCH 100/127] Better icons for Hierarchy Better icons for Hierarchy --- interface/resources/fonts/vircadia_glyphs.ttf | Bin 5240 -> 4000 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/interface/resources/fonts/vircadia_glyphs.ttf b/interface/resources/fonts/vircadia_glyphs.ttf index f7e9d7f372c88e34027d1ab63880127354150ed1..7d3fe9d913a85bcbfc00162d1ebf1617c40c1b48 100644 GIT binary patch literal 4000 zcmds)Yit}>703VQ&g{&3-)ry7$-caHX4j4#@67DOk0gG^X&#Q9M;)hmIGaapD{*TQ zH#7o;3RNgVk!S!_0-_2CAjGE_1VVxj{SXPLQt_b?&_ZY;BoJ1W@}Z!zg0+1Zr z-)T%A7=H_(NdU)B&Q<1LUwGlifcOBQebbfm^D8Tm0RIsH&grukpDxE58Ue=@K-xWX zx^gP^$xB-S{02a2X6AH7dK*^05P+7MxrOKD2jm0jhX4(pefDIfa_;z70eKvtp1I2N z^Y}fc0O|seex@>a`poA)bp~+$3Xl%YKYM;*cKkDc0X%s?YJ)X50;Ipb=b!R#{xjSH zR{Ql2UKv}BA%O0P>sGy}?zYDWEZ+uq&>cI|!_8s$T*DDK?QUx%*?s+dm_#4YdvE~a zv*Jepu2dtv4V`M9TBAUX08CC!PNE;_yWQ0q=)S$vnu{g*tu=EH{miNyz;^(P)~5Uq zS{HWU^6EGZJ*)iDZ4zLA;=I1QA=wm%jJ$nK)UJw4ce__s?1f0*g+(jBOP{En6|0eA zUpQ5^PRH6)VqJ-{Ls6Y|F1N?)^9O?U4WV!(8f#p)KAuRX(oLD>mJM1q*V?wRy<<~n zUN_7_u~hEr?&;mUWouvmz~IpEwvp{m?AW<$_voIn@xA-@A9!-&;N+pF4j(ysZ0dNW zD*u1C$p2_Nj&I{uZKDbL)<=7@uNdoY^nGz15>%j}DcDqQ3O0r4Ys*u4>R*0UT>snA zycn|1uoGSApx5Z8eQW@YNT3O==l~kbaC13q7VC{jNNLV!g_atWqiWXrC{{;CE0oP} z^W}HnO)hrk;)#Y(e0ixFzYv-T-JA$bbm!vnT)ZU`p_@y$78jTQn8+m(xs?6=iNJL5 zWwe4_o0=`Z{KgyU zs}t$8qgu_GTs)yANV7vOHW2&rKx}|c|NO>FFU{?}Vi&XgO*}wp2tg8&A_UbtWF`H; zK~5ngB64{;NU5`irs$WhzOCa&`b(;sQ(}Sod{>X2N+o^qh37s_BH-`|Ns@#hw-BukTv_F zX>6hBDwj)JC|mt2qivx=xztNWG@@ozrIXZX#3<7hkFS1d$v^4!G`#bU!{IpURK0I{ z>g!zYH@&K}7~ZES>2TVU^w7%>!hU}y_+aq;h}YkwNY3{U-uAj&A@6Ok+vRfYjU973 zH^f@JUH}<-W%d3npfD5sXl1r~w=+v<#HX2MMDQB30|I|wRuHBLvkE~5vlD`Pnd=~E znArtEqs(pynqc-o&=j*5f@YX~5cDzT0Q~et<{%XMuJy|#*V!v?{bpHANTQBez=LjP z2?q8s%V@_nW(Q>4V^+|HC1w>ewKF>*Q<1q2GHqpcL8k4@Zpbvw?14;&n7xqc1hWq^ zona0jNej$Dc<39*AOmDFzy-|W98RKwQ`hH*7Gk?r5_!d$@Hwrovvkjd`WBad{~lybApeXY^|QvRR1MBeqL*5@*zw8 zPfs;#+co=1SU`dd2NbAqq7E*&;ei)E_z^%5^=Lo{VMGu`42@Wa^@t;ZBvMGD2^ln_ z1sk9tiyT_fhK*=P2R5M-dFU`;qJSbwD5DGA=s_Gwgl%^)iP&2jA2GS@?IclXg+DPrxL7S+P@}!eN zCKaeiB`Q-FbyE-Zs?R+$yDgv3bJRH+98Hb|jzx|oj%AKr9J@IVa2(_~#BrG8HjX3J zsIy;Zzs`Q0{W|+~_Ur7|*{`!-XTQ#Vo&7rdb@uD**V%8d-(bJNeuMo6`wjLR>^InN zu-{<6!G44N2Kx>68|*jOZ?fNHzsY`+{U-ZO_M7ZC*>AGn?6&_gXk`V$zKeSRMC@lg af`qStAV2huV87kHwf{?hvPM1pe)@M1PF?u` literal 5240 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 Date: Fri, 23 Oct 2020 23:17:22 -0400 Subject: [PATCH 101/127] Code Adjustments Code Adjustments --- scripts/system/html/css/edit-style.css | 8 -------- 1 file changed, 8 deletions(-) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 2ba68e505b..1f1fb9c86a 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -419,7 +419,6 @@ input[type=button].normal, button.hifi-edit-button.normal { font-family: FiraSans-SemiBold; font-size: 15px; text-transform: none; - //min-width: 65px; padding: 0; } @@ -1244,7 +1243,6 @@ textarea:enabled[scrolling="true"]::-webkit-resizer { background: #2e2e2e url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACKSURBVChTjdAxDsMgDAXQT4UYuQIzCwsSKxsSJ4YDoByDY7AwUOG2aZMQqX+xhd9gzIwxA3/k8a7LCCFgraX+Fk4UY4RSCoyxNfwgzjlyzhhjXOEvSimhtUbvB3hGUkp472m2wxUKIaD3TnOCd6jWim3bvlBrfdjJOUeolEJoZj/4PMH83bl/BXgCWSs2Z09IjgoAAAAASUVORK5CYII=) no-repeat bottom right; } - div#grid-section, body#entity-list-body { padding-bottom: 0; margin: 16px; @@ -1275,12 +1273,6 @@ div#grid-section, body#entity-list-body { border-bottom-left-radius: 0; } -/*#delete { - float: right; - margin-right: 0; - background-color: #ff0000; -}*/ - #entity-list { position: relative; /* New positioning context. */ } From 5b0a00a81aa5c97c22403e66324bda7dac8fcbb3 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Fri, 23 Oct 2020 23:21:32 -0400 Subject: [PATCH 102/127] Add Parent-Children Selector group Add Parent-Children Selector group Prevent action to happen when some entities are Locked in the Selection Code Adjustments --- scripts/system/create/edit.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index 35bcd45786..69e2e94818 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -1696,7 +1696,7 @@ function recursiveDelete(entities, childrenList, deletedIDs, entityHostType) { } function unparentSelectedEntities() { - if (SelectionManager.hasSelection()) { + if (SelectionManager.hasSelection() && SelectionManager.hasUnlockedSelection()) { var selectedEntities = selectionManager.selections; var parentCheck = false; @@ -1733,11 +1733,11 @@ function unparentSelectedEntities() { } } else { audioFeedback.rejection(); - Window.notifyEditError("You have nothing selected to unparent"); + Window.notifyEditError("You have nothing selected or the selection has locked entities."); } } function parentSelectedEntities() { - if (SelectionManager.hasSelection()) { + if (SelectionManager.hasSelection() && SelectionManager.hasUnlockedSelection()) { var selectedEntities = selectionManager.selections; if (selectedEntities.length <= 1) { audioFeedback.rejection(); @@ -1768,11 +1768,11 @@ function parentSelectedEntities() { } } else { audioFeedback.rejection(); - Window.notifyEditError("You have nothing selected to parent"); + Window.notifyEditError("You have nothing selected or the selection has locked entities."); } } function deleteSelectedEntities() { - if (SelectionManager.hasSelection()) { + if (SelectionManager.hasSelection() && SelectionManager.hasUnlockedSelection()) { var deletedIDs = []; SelectionManager.saveProperties(); @@ -1803,6 +1803,9 @@ function deleteSelectedEntities() { pushCommandForSelections([], savedProperties); entityListTool.deleteEntities(deletedIDs); } + } else { + audioFeedback.rejection(); + Window.notifyEditError("You have nothing selected or the selection has locked entities."); } } From 6da472b7e31d031db95844bf0831a7f51f498d43 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Fri, 23 Oct 2020 23:22:37 -0400 Subject: [PATCH 103/127] Add Parent-Children Selector group Add Parent-Children Selector group Prevent action to happen when some entities are Locked in the Selection Code Adjustments --- .../entitySelectionTool.js | 110 +++++++++++++++++- 1 file changed, 104 insertions(+), 6 deletions(-) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index 0f8c8cc8bf..b4bf427a85 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -19,6 +19,7 @@ const SPACE_LOCAL = "local"; const SPACE_WORLD = "world"; const HIGHLIGHT_LIST_NAME = "editHandleHighlightList"; +const MIN_DISTANCE_TO_REZ_FROM_AVATAR = 3; Script.include([ "../../libraries/controllers.js", @@ -26,7 +27,6 @@ Script.include([ "../../libraries/utils.js" ]); - function deepCopy(v) { return JSON.parse(JSON.stringify(v)); } @@ -638,18 +638,19 @@ SelectionManager = (function() { that.teleportToEntity = function() { if (that.hasSelection()) { - var distanceFromTarget = 3 + Math.max(Math.max(that.worldDimensions.x, that.worldDimensions.y), that.worldDimensions.z); + var distanceFromTarget = MIN_DISTANCE_TO_REZ_FROM_AVATAR + Math.max(Math.max(that.worldDimensions.x, that.worldDimensions.y), that.worldDimensions.z); var teleportTargetPosition = Vec3.sum(that.worldPosition, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: distanceFromTarget })); MyAvatar.goToLocation(teleportTargetPosition, false); } else { audioFeedback.rejection(); + Window.notifyEditError("You have nothing selected."); } }; that.moveEntitiesSelectionToAvatar = function() { - if (that.hasSelection()) { + if (that.hasSelection() && that.hasUnlockedSelection()) { that.saveProperties(); - var distanceFromTarget = 3 + Math.max(Math.max(that.worldDimensions.x, that.worldDimensions.y), that.worldDimensions.z); + var distanceFromTarget = MIN_DISTANCE_TO_REZ_FROM_AVATAR + Math.max(Math.max(that.worldDimensions.x, that.worldDimensions.y), that.worldDimensions.z); var targetPosition = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -distanceFromTarget })); // editing a parent will cause all the children to automatically follow along, so don't // edit any entity who has an ancestor in that.selections @@ -670,9 +671,106 @@ SelectionManager = (function() { that._update(false, this); } else { audioFeedback.rejection(); + Window.notifyEditError("You have nothing selected or the selection has locked entities."); } }; + that.selectParent = function() { + if (that.hasSelection()) { + var currentSelection = that.selections; + that.selections = []; + for (var i = 0; i < currentSelection.length; i++) { + var properties = Entities.getEntityProperties(currentSelection[i], ['parentID']); + if (properties.parentID !== Uuid.NULL) { + that.selections.push(properties.parentID); + } + } + that._update(true, this); + } else { + audioFeedback.rejection(); + Window.notifyEditError("You have nothing selected."); + } + }; + + that.selectTopParent = function() { + if (that.hasSelection()) { + var currentSelection = that.selections; + that.selections = []; + for (var i = 0; i < currentSelection.length; i++) { + var topParentId = getTopParent(currentSelection[i]); + if (topParentId !== Uuid.NULL) { + that.selections.push(topParentId); + } + } + that._update(true, this); + } else { + audioFeedback.rejection(); + Window.notifyEditError("You have nothing selected."); + } + }; + + function getTopParent(id) { + var topParentId = Uuid.NULL; + var properties = Entities.getEntityProperties(id, ['parentID']); + if(properties.parentID === Uuid.NULL) { + topParentId = id; + } else { + topParentId = getTopParent(properties.parentID); + } + return topParentId; + } + + that.addChildrenToSelection = function() { + if (that.hasSelection()) { + for (var i = 0; i < that.selections.length; i++) { + var childrenIds = Entities.getChildrenIDs(that.selections[i]); + var collectNewChildren; + var j; + var k = 0; + do { + collectNewChildren = Entities.getChildrenIDs(childrenIds[k]); + if (collectNewChildren.length > 0) { + for (j = 0; j < collectNewChildren.length; j++) { + childrenIds.push(collectNewChildren[j]); + } + } + k++; + } while (k < childrenIds.length); + if (childrenIds.length > 0) { + for (j = 0; j < childrenIds.length; j++) { + that.selections.push(childrenIds[j]); + } + } + } + that._update(true, this); + } else { + audioFeedback.rejection(); + Window.notifyEditError("You have nothing selected."); + } + }; + + that.hasUnlockedSelection = function() { + var selectionNotLocked = true; + for (var i = 0; i < that.selections.length; i++) { + var properties = Entities.getEntityProperties(that.selections[i], ['locked']); + if (properties.locked) { + selectionNotLocked = false; + break; + } + } + return selectionNotLocked; + }; + + that.selectFamily = function() { + that.selectParent(); + that.addChildrenToSelection(); + }; + + that.selectTopFamily = function() { + that.selectTopParent(); + that.addChildrenToSelection(); + }; + return that; })(); @@ -698,8 +796,8 @@ SelectionDisplay = (function() { const COLOR_DUPLICATOR = { red: 162, green: 0, blue: 255 }; const COLOR_ROTATE_CURRENT_RING = { red: 255, green: 99, blue: 9 }; const COLOR_BOUNDING_EDGE = { red: 160, green: 160, blue: 160 }; - const COLOR_BOUNDING_EDGE_PARENT = { red: 194, green: 123, blue: 0 }; //{ red: 255, green: 160, blue: 0 }; - const COLOR_BOUNDING_EDGE_CHILDREN = { red: 0, green: 168, blue: 214 }; // { red: 0, green: 200, blue: 255 } + const COLOR_BOUNDING_EDGE_PARENT = { red: 194, green: 123, blue: 0 }; + const COLOR_BOUNDING_EDGE_CHILDREN = { red: 0, green: 168, blue: 214 }; const COLOR_SCALE_CUBE = { red: 192, green: 192, blue: 192 }; const COLOR_DEBUG_PICK_PLANE = { red: 255, green: 255, blue: 255 }; const COLOR_DEBUG_PICK_PLANE_HIT = { red: 255, green: 165, blue: 0 }; From ba371613ba0be00a99fc4a4997cb5e71f012a5c7 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Fri, 23 Oct 2020 23:24:06 -0400 Subject: [PATCH 104/127] Add Parent-Children Selector group Add Parent-Children Selector group Prevent action to happen when some entities are Locked in the Selection Code Adjustments --- scripts/system/create/entityList/entityList.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index cb6beeaa4a..d0294c2c27 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -207,11 +207,11 @@ EntityListTool = function(shouldUseEditTabletApp) { var parentStatus = getParentState(ids[i]); var parentState = ""; if (parentStatus === "PARENT") { - parentState = "N"; + parentState = "A"; } else if (parentStatus === "CHILDREN") { - parentState = "O"; + parentState = "C"; } else if (parentStatus === "PARENT_CHILDREN") { - parentState = "M"; + parentState = "B"; } entities.push({ @@ -339,6 +339,16 @@ EntityListTool = function(shouldUseEditTabletApp) { selectAllEntitiesInCurrentSelectionBox(false); } else if (data.type === 'selectAllTouchingBox') { selectAllEntitiesInCurrentSelectionBox(true); + } else if (data.type === 'selectParent') { + SelectionManager.selectParent(); + } else if (data.type === 'selectTopParent') { + SelectionManager.selectTopParent(); + } else if (data.type === 'addChildrenToSelection') { + SelectionManager.addChildrenToSelection(); + } else if (data.type === 'selectFamily') { + SelectionManager.selectFamily(); + } else if (data.type === 'selectTopFamily') { + SelectionManager.selectTopFamily(); } else if (data.type === 'teleportToEntity') { SelectionManager.teleportToEntity(); } else if (data.type === 'moveEntitySelectionToAvatar') { From bfc216ab00abeafe0d3807e20b31d719f82904fe Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Fri, 23 Oct 2020 23:25:51 -0400 Subject: [PATCH 105/127] Add Parent-Children Selector group Add Parent-Children Selector group "Inverse Selection" is now responding to Ctrl-I Code Adjustments --- .../create/entityList/html/entityList.html | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index 361b1a2c70..242a91eeda 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -138,7 +138,7 @@ @@ -172,7 +172,7 @@ @@ -189,6 +189,37 @@
    + + + + + + From b3ab7e05d37ff4120bf65f47c2bacabc84bd822b Mon Sep 17 00:00:00 2001 From: Kalila L Date: Sat, 24 Oct 2020 04:20:02 -0400 Subject: [PATCH 108/127] Add missing authorship comment. --- plugins/KasenAPIExample/src/ExampleScriptPlugin.h | 4 +++- plugins/KasenAPIExample/src/KasenAPIExample.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/KasenAPIExample/src/ExampleScriptPlugin.h b/plugins/KasenAPIExample/src/ExampleScriptPlugin.h index a6af105e0e..76c0a494d7 100644 --- a/plugins/KasenAPIExample/src/ExampleScriptPlugin.h +++ b/plugins/KasenAPIExample/src/ExampleScriptPlugin.h @@ -5,10 +5,12 @@ // Created by Kasen IO on 2019.07.14 | realities.dev | kasenvr@gmail.com // Copyright 2019 Kasen IO // +// Authored by: Humbletim (humbletim@gmail.com) +// // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -// Supporting file containing all QtScript specific integration. +// Supporting file containing all QtScript specific integration. #ifndef EXAMPLE_SCRIPT_PLUGIN_H #define EXAMPLE_SCRIPT_PLUGIN_H diff --git a/plugins/KasenAPIExample/src/KasenAPIExample.cpp b/plugins/KasenAPIExample/src/KasenAPIExample.cpp index d446e98e6e..720c47f6cd 100644 --- a/plugins/KasenAPIExample/src/KasenAPIExample.cpp +++ b/plugins/KasenAPIExample/src/KasenAPIExample.cpp @@ -5,10 +5,12 @@ // Created by Kasen IO on 2019.07.14 | realities.dev | kasenvr@gmail.com // Copyright 2019 Kasen IO // +// Authored by: Humbletim (humbletim@gmail.com) +// // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -// Example of prototyping new JS APIs by leveraging the existing plugin system. +// Example of prototyping new JS APIs by leveraging the existing plugin system. #include "ExampleScriptPlugin.h" From 0dadb100b1064da4eaead79e0855a51dea0e6e2a Mon Sep 17 00:00:00 2001 From: Kalila L Date: Sat, 24 Oct 2020 04:49:01 -0400 Subject: [PATCH 109/127] Revert 0b46c53df17761d3799f6d5d3886eaf85e0c2dbe --- cmake/externals/polyvox/CMakeLists.txt | 78 ++++++++++++++ interface/CMakeLists.txt | 6 -- interface/src/Application.cpp | 2 +- libraries/audio-client/src/AudioClient.cpp | 2 +- .../networking/src/UserActivityLogger.cpp | 3 - libraries/script-engine/src/ScriptEngine.cpp | 101 ++---------------- plugins/CMakeLists.txt | 4 +- 7 files changed, 88 insertions(+), 108 deletions(-) create mode 100644 cmake/externals/polyvox/CMakeLists.txt diff --git a/cmake/externals/polyvox/CMakeLists.txt b/cmake/externals/polyvox/CMakeLists.txt new file mode 100644 index 0000000000..a92c07da86 --- /dev/null +++ b/cmake/externals/polyvox/CMakeLists.txt @@ -0,0 +1,78 @@ +set(EXTERNAL_NAME polyvox) + +include(ExternalProject) +ExternalProject_Add( + ${EXTERNAL_NAME} + URL https://public.highfidelity.com/dependencies/polyvox-master-2015-7-15.zip + URL_MD5 9ec6323b87e849ae36e562ae1c7494a9 + CMAKE_ARGS -DENABLE_EXAMPLES=OFF -DENABLE_BINDINGS=OFF -DCMAKE_INSTALL_PREFIX:PATH= + BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 +) + +# Hide this external target (for ide users) +set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") + +ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) + +if (APPLE) + set(INSTALL_NAME_LIBRARY_DIR ${INSTALL_DIR}/lib) + + ExternalProject_Add_Step( + ${EXTERNAL_NAME} + change-install-name-debug + COMMENT "Calling install_name_tool on libraries to fix install name for dylib linking" + COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${INSTALL_NAME_LIBRARY_DIR}/Debug -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake + DEPENDEES install + WORKING_DIRECTORY + LOG 1 + ) + + ExternalProject_Add_Step( + ${EXTERNAL_NAME} + change-install-name-release + COMMENT "Calling install_name_tool on libraries to fix install name for dylib linking" + COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${INSTALL_NAME_LIBRARY_DIR}/Release -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake + DEPENDEES install + WORKING_DIRECTORY + LOG 1 + ) +endif () + + +string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) + +if (WIN32) + set(${EXTERNAL_NAME_UPPER}_CORE_INCLUDE_DIRS ${INSTALL_DIR}/PolyVoxCore/include CACHE FILEPATH + "Path to polyvox core include directory") + set(${EXTERNAL_NAME_UPPER}_UTIL_INCLUDE_DIRS ${INSTALL_DIR}/PolyVoxUtil/include CACHE FILEPATH + "Path to polyvox util include directory") +else () + set(${EXTERNAL_NAME_UPPER}_CORE_INCLUDE_DIRS ${INSTALL_DIR}/include/PolyVoxCore CACHE FILEPATH + "Path to polyvox core include directory") + set(${EXTERNAL_NAME_UPPER}_UTIL_INCLUDE_DIRS ${INSTALL_DIR}/include/PolyVoxUtil CACHE FILEPATH + "Path to polyvox util include directory") +endif () + + +if (WIN32) + set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_DEBUG ${INSTALL_DIR}/PolyVoxCore/lib/Debug/PolyVoxCore.lib CACHE FILEPATH "polyvox core library") + + # use generator expression to ensure the correct library is found when building different configurations in VS + set(_LIB_FOLDER "$<$:PolyVoxCore/lib/RelWithDebInfo>") + set(_LIB_FOLDER "${_LIB_FOLDER}$<$:build/library/PolyVoxCore/MinSizeRel>") + set(_LIB_FOLDER "${_LIB_FOLDER}$<$,$>:PolyVoxCore/lib/Release>") + + set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_RELEASE "${INSTALL_DIR}/${_LIB_FOLDER}/PolyVoxCore.lib" CACHE FILEPATH "polyvox core library") +# set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY ${INSTALL_DIR}/PolyVoxUtil/lib/PolyVoxUtil.lib CACHE FILEPATH "polyvox util library") +elseif (APPLE) + set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_DEBUG ${INSTALL_DIR}/lib/Debug/libPolyVoxCore.dylib CACHE FILEPATH "polyvox core library") + set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_RELEASE ${INSTALL_DIR}/lib/Release/libPolyVoxCore.dylib CACHE FILEPATH "polyvox core library") +# set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY ${INSTALL_DIR}/lib/libPolyVoxUtil.dylib CACHE FILEPATH "polyvox util library") +else () + set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_DEBUG ${INSTALL_DIR}/lib/Debug/libPolyVoxCore.so CACHE FILEPATH "polyvox core library") + set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_RELEASE ${INSTALL_DIR}/lib/Release/libPolyVoxCore.so CACHE FILEPATH "polyvox core library") +# set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY ${INSTALL_DIR}/lib/libPolyVoxUtil.so CACHE FILEPATH "polyvox util library") +endif () diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 0a0ade149d..7d54065286 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -165,8 +165,6 @@ elseif (WIN32) # add an executable that also has the icon itself and the configured rc file as resources add_executable(${TARGET_NAME} WIN32 ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT} ${CONFIGURE_VERSION_INFO_RC_OUTPUT}) - ##^^^^^ creates native Win32 app w/o cmd console vvvvvv forces cmd console for logging - # add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT} ${CONFIGURE_VERSION_INFO_RC_OUTPUT}) if (NOT DEV_BUILD) add_custom_command( @@ -190,10 +188,6 @@ if (BUILD_TOOLS AND NPM_EXECUTABLE) add_dependencies(resources jsdoc) endif() -if (WIN32 OR APPLE) - add_dependencies(${TARGET_NAME} resources screenshare) -endif() - if (WIN32) # These are external plugins, but we need to do the 'add dependency' here so that their diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b76e3f8dca..7002780e4e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -7164,7 +7164,7 @@ void Application::updateWindowTitle() const { bool isDomainLoggedIn = domainAccountManager->isLoggedIn(); QString authedDomainName = domainAccountManager->getAuthedDomainName(); - QString buildVersion = " - Vircadia - " + QString buildVersion = " - " + (BuildInfo::BUILD_TYPE == BuildInfo::BuildType::Stable ? QString("Version") : QString("Build")) + " " + applicationVersion(); diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 8d96a2e6b5..911da25c36 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -2163,7 +2163,7 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi int deviceChannelCount = _outputFormat.channelCount(); int frameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / _desiredOutputFormat.sampleRate(); int requestedSize = _sessionOutputBufferSizeFrames * frameSize * AudioConstants::SAMPLE_SIZE; - _audioOutput->setBufferSize(requestedSize * 16); + _audioOutput->setBufferSize(requestedSize); connect(_audioOutput, &QAudioOutput::notify, this, &AudioClient::outputNotify); diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index 94d6371ba4..3c1cbc315b 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -39,9 +39,6 @@ void UserActivityLogger::crashMonitorDisable(bool disable) { } void UserActivityLogger::logAction(QString action, QJsonObject details, JSONCallbackParameters params) { -// qCDebug(networking).nospace() << ">>> UserActivityLogger::logAction(" << action << "," << QJsonDocument(details).toJson(); -// This logs what the UserActivityLogger would normally send to centralized servers. - return; if (_disabled.get()) { return; } diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index c5c6c1fef1..4523c50e74 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -307,7 +307,7 @@ QString ScriptEngine::getContext() const { return "unknown"; } -bool ScriptEngine::isDebugMode() const { +bool ScriptEngine::isDebugMode() const { #if defined(DEBUG) return true; #else @@ -875,11 +875,6 @@ void ScriptEngine::init() { #if DEV_BUILD || PR_BUILD registerGlobalObject("StackTest", new StackTestScriptingInterface(this)); #endif - - globalObject().setProperty("KALILA", "isWaifu"); - globalObject().setProperty("Kute", newFunction([](QScriptContext* context, QScriptEngine* engine) -> QScriptValue { - return context->argument(0).toString().toLower() == "kalila" ? true : false; - })); } void ScriptEngine::registerEnum(const QString& enumName, QMetaEnum newEnum) { @@ -2444,7 +2439,6 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co BaseScriptEngine sandbox; sandbox.setProcessEventsInterval(SANDBOX_TIMEOUT); QScriptValue testConstructor, exception; - if (atoi(getenv("UNSAFE_ENTITY_SCRIPTS") ? getenv("UNSAFE_ENTITY_SCRIPTS") : "0")) { QTimer timeout; timeout.setSingleShot(true); @@ -2466,94 +2460,14 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co } else if (testConstructor.isError()) { exception = testConstructor; } - } else { - // ENTITY SCRIPT WHITELIST STARTS HERE - auto nodeList = DependencyManager::get(); - bool passList = false; // assume unsafe - QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]"; - QList safeURLPrefixes = { "file:///", "atp:", "cache:" }; - safeURLPrefixes += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts); - - // Entity Script Whitelist toggle check. - Setting::Handle whitelistEnabled {"private/whitelistEnabled", false }; - - if (!whitelistEnabled.get()) { - passList = true; - } - - // Pull SAFEURLS from the Interface.JSON settings. - QVariant raw = Setting::Handle("private/settingsSafeURLS").get(); - QStringList settingsSafeURLS = raw.toString().trimmed().split(QRegExp("\\s*[,\r\n]+\\s*"), QString::SkipEmptyParts); - safeURLPrefixes += settingsSafeURLS; - // END Pull SAFEURLS from the Interface.JSON settings. - - // Get current domain whitelist bypass, in case an entire domain is whitelisted. - QString currentDomain = DependencyManager::get()->getDomainURL().host(); - - QString domainSafeIP = nodeList->getDomainHandler().getHostname(); - QString domainSafeURL = URL_SCHEME_HIFI + "://" + currentDomain; - for (const auto& str : safeURLPrefixes) { - if (domainSafeURL.startsWith(str) || domainSafeIP.startsWith(str)) { - qCDebug(scriptengine) << whitelistPrefix << "Whitelist Bypassed, entire domain is whitelisted. Current Domain Host: " - << nodeList->getDomainHandler().getHostname() - << "Current Domain: " << currentDomain; - passList = true; - } - } - // END bypass whitelist based on current domain. - - // Start processing scripts through the whitelist. - if (ScriptEngine::getContext() == "entity_server") { // If running on the server, do not engage whitelist. - passList = true; - } else if (!passList) { // If waved through, do not engage whitelist. - for (const auto& str : safeURLPrefixes) { - qCDebug(scriptengine) << whitelistPrefix << "Script URL: " << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN" - << scriptOrURL.startsWith(str); - if (!str.isEmpty() && scriptOrURL.startsWith(str)) { - passList = true; - qCDebug(scriptengine) << whitelistPrefix << "Script approved."; - break; // Bail early since we found a match. - } - } - } - // END processing of scripts through the whitelist. - - if (!passList) { // If the entity failed to pass for any reason, it's blocked and an error is thrown. - qCDebug(scriptengine) << whitelistPrefix << "(disabled entity script)" << entityID.toString() << scriptOrURL; - exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0"); - } else { - QTimer timeout; - timeout.setSingleShot(true); - timeout.start(SANDBOX_TIMEOUT); - connect(&timeout, &QTimer::timeout, [=, &sandbox] { - qCDebug(scriptengine) << "ScriptEngine::entityScriptContentAvailable timeout"; - - // Guard against infinite loops and non-performant code - sandbox.raiseException( - sandbox.makeError(QString("Timed out (entity constructors are limited to %1ms)").arg(SANDBOX_TIMEOUT))); - }); - - testConstructor = sandbox.evaluate(program); - - if (sandbox.hasUncaughtException()) { - exception = sandbox.cloneUncaughtException(QString("(preflight %1)").arg(entityID.toString())); - sandbox.clearExceptions(); - } else if (testConstructor.isError()) { - exception = testConstructor; - } - } - // ENTITY SCRIPT WHITELIST ENDS HERE, uncomment below for original full disabling. - - // qDebug() << "(disabled entity script)" << entityID.toString() << scriptOrURL; - // exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0"); } if (exception.isError()) { - // create a local copy using makeError to decouple from the sandbox engine - exception = makeError(exception); - setError(formatException(exception, _enableExtendedJSExceptions.get()), EntityScriptStatus::ERROR_RUNNING_SCRIPT); - emit unhandledException(exception); - return; + // create a local copy using makeError to decouple from the sandbox engine + exception = makeError(exception); + setError(formatException(exception, _enableExtendedJSExceptions.get()), EntityScriptStatus::ERROR_RUNNING_SCRIPT); + emit unhandledException(exception); + return; } // CONSTRUCTOR VIABILITY @@ -2925,6 +2839,3 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS } } -QString ScriptEngine::getExternalPath(ExternalResource::Bucket bucket, const QString& path) { - return ExternalResource::getInstance()->getUrl(bucket, path); -} diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 1448e14c72..11ff195d56 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -9,7 +9,7 @@ # add the plugin directories file(GLOB PLUGIN_SUBDIRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*") list(REMOVE_ITEM PLUGIN_SUBDIRS "CMakeFiles") -set(CMAKE_BUILD_TYPE "Release") + # client-side plugins if (NOT SERVER_ONLY AND NOT ANDROID) set(DIR "oculus") @@ -25,7 +25,7 @@ if (NOT SERVER_ONLY AND NOT ANDROID) set(DIR "hifiSixense") add_subdirectory(${DIR}) endif() - + set(DIR "hifiSpacemouse") add_subdirectory(${DIR}) set(DIR "hifiNeuron") From 96877db43a73fedc2f0315b501a08156c5a8da20 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Sat, 24 Oct 2020 05:02:45 -0400 Subject: [PATCH 110/127] Re-apply 0dadb100b1064da4eaead79e0855a51dea0e6e2a w/ authorship. Co-Authored-By: Humbletim --- cmake/externals/polyvox/CMakeLists.txt | 78 -------------- interface/CMakeLists.txt | 6 ++ interface/src/Application.cpp | 2 +- libraries/audio-client/src/AudioClient.cpp | 2 +- .../networking/src/UserActivityLogger.cpp | 3 + libraries/script-engine/src/ScriptEngine.cpp | 101 ++++++++++++++++-- plugins/CMakeLists.txt | 4 +- 7 files changed, 108 insertions(+), 88 deletions(-) delete mode 100644 cmake/externals/polyvox/CMakeLists.txt diff --git a/cmake/externals/polyvox/CMakeLists.txt b/cmake/externals/polyvox/CMakeLists.txt deleted file mode 100644 index a92c07da86..0000000000 --- a/cmake/externals/polyvox/CMakeLists.txt +++ /dev/null @@ -1,78 +0,0 @@ -set(EXTERNAL_NAME polyvox) - -include(ExternalProject) -ExternalProject_Add( - ${EXTERNAL_NAME} - URL https://public.highfidelity.com/dependencies/polyvox-master-2015-7-15.zip - URL_MD5 9ec6323b87e849ae36e562ae1c7494a9 - CMAKE_ARGS -DENABLE_EXAMPLES=OFF -DENABLE_BINDINGS=OFF -DCMAKE_INSTALL_PREFIX:PATH= - BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build - LOG_DOWNLOAD 1 - LOG_CONFIGURE 1 - LOG_BUILD 1 -) - -# Hide this external target (for ide users) -set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") - -ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) - -if (APPLE) - set(INSTALL_NAME_LIBRARY_DIR ${INSTALL_DIR}/lib) - - ExternalProject_Add_Step( - ${EXTERNAL_NAME} - change-install-name-debug - COMMENT "Calling install_name_tool on libraries to fix install name for dylib linking" - COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${INSTALL_NAME_LIBRARY_DIR}/Debug -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake - DEPENDEES install - WORKING_DIRECTORY - LOG 1 - ) - - ExternalProject_Add_Step( - ${EXTERNAL_NAME} - change-install-name-release - COMMENT "Calling install_name_tool on libraries to fix install name for dylib linking" - COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${INSTALL_NAME_LIBRARY_DIR}/Release -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake - DEPENDEES install - WORKING_DIRECTORY - LOG 1 - ) -endif () - - -string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) - -if (WIN32) - set(${EXTERNAL_NAME_UPPER}_CORE_INCLUDE_DIRS ${INSTALL_DIR}/PolyVoxCore/include CACHE FILEPATH - "Path to polyvox core include directory") - set(${EXTERNAL_NAME_UPPER}_UTIL_INCLUDE_DIRS ${INSTALL_DIR}/PolyVoxUtil/include CACHE FILEPATH - "Path to polyvox util include directory") -else () - set(${EXTERNAL_NAME_UPPER}_CORE_INCLUDE_DIRS ${INSTALL_DIR}/include/PolyVoxCore CACHE FILEPATH - "Path to polyvox core include directory") - set(${EXTERNAL_NAME_UPPER}_UTIL_INCLUDE_DIRS ${INSTALL_DIR}/include/PolyVoxUtil CACHE FILEPATH - "Path to polyvox util include directory") -endif () - - -if (WIN32) - set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_DEBUG ${INSTALL_DIR}/PolyVoxCore/lib/Debug/PolyVoxCore.lib CACHE FILEPATH "polyvox core library") - - # use generator expression to ensure the correct library is found when building different configurations in VS - set(_LIB_FOLDER "$<$:PolyVoxCore/lib/RelWithDebInfo>") - set(_LIB_FOLDER "${_LIB_FOLDER}$<$:build/library/PolyVoxCore/MinSizeRel>") - set(_LIB_FOLDER "${_LIB_FOLDER}$<$,$>:PolyVoxCore/lib/Release>") - - set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_RELEASE "${INSTALL_DIR}/${_LIB_FOLDER}/PolyVoxCore.lib" CACHE FILEPATH "polyvox core library") -# set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY ${INSTALL_DIR}/PolyVoxUtil/lib/PolyVoxUtil.lib CACHE FILEPATH "polyvox util library") -elseif (APPLE) - set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_DEBUG ${INSTALL_DIR}/lib/Debug/libPolyVoxCore.dylib CACHE FILEPATH "polyvox core library") - set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_RELEASE ${INSTALL_DIR}/lib/Release/libPolyVoxCore.dylib CACHE FILEPATH "polyvox core library") -# set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY ${INSTALL_DIR}/lib/libPolyVoxUtil.dylib CACHE FILEPATH "polyvox util library") -else () - set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_DEBUG ${INSTALL_DIR}/lib/Debug/libPolyVoxCore.so CACHE FILEPATH "polyvox core library") - set(${EXTERNAL_NAME_UPPER}_CORE_LIBRARY_RELEASE ${INSTALL_DIR}/lib/Release/libPolyVoxCore.so CACHE FILEPATH "polyvox core library") -# set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY ${INSTALL_DIR}/lib/libPolyVoxUtil.so CACHE FILEPATH "polyvox util library") -endif () diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 7d54065286..0a0ade149d 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -165,6 +165,8 @@ elseif (WIN32) # add an executable that also has the icon itself and the configured rc file as resources add_executable(${TARGET_NAME} WIN32 ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT} ${CONFIGURE_VERSION_INFO_RC_OUTPUT}) + ##^^^^^ creates native Win32 app w/o cmd console vvvvvv forces cmd console for logging + # add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT} ${CONFIGURE_VERSION_INFO_RC_OUTPUT}) if (NOT DEV_BUILD) add_custom_command( @@ -188,6 +190,10 @@ if (BUILD_TOOLS AND NPM_EXECUTABLE) add_dependencies(resources jsdoc) endif() +if (WIN32 OR APPLE) + add_dependencies(${TARGET_NAME} resources screenshare) +endif() + if (WIN32) # These are external plugins, but we need to do the 'add dependency' here so that their diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7002780e4e..b76e3f8dca 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -7164,7 +7164,7 @@ void Application::updateWindowTitle() const { bool isDomainLoggedIn = domainAccountManager->isLoggedIn(); QString authedDomainName = domainAccountManager->getAuthedDomainName(); - QString buildVersion = " - " + QString buildVersion = " - Vircadia - " + (BuildInfo::BUILD_TYPE == BuildInfo::BuildType::Stable ? QString("Version") : QString("Build")) + " " + applicationVersion(); diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 911da25c36..8d96a2e6b5 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -2163,7 +2163,7 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi int deviceChannelCount = _outputFormat.channelCount(); int frameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / _desiredOutputFormat.sampleRate(); int requestedSize = _sessionOutputBufferSizeFrames * frameSize * AudioConstants::SAMPLE_SIZE; - _audioOutput->setBufferSize(requestedSize); + _audioOutput->setBufferSize(requestedSize * 16); connect(_audioOutput, &QAudioOutput::notify, this, &AudioClient::outputNotify); diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index 3c1cbc315b..94d6371ba4 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -39,6 +39,9 @@ void UserActivityLogger::crashMonitorDisable(bool disable) { } void UserActivityLogger::logAction(QString action, QJsonObject details, JSONCallbackParameters params) { +// qCDebug(networking).nospace() << ">>> UserActivityLogger::logAction(" << action << "," << QJsonDocument(details).toJson(); +// This logs what the UserActivityLogger would normally send to centralized servers. + return; if (_disabled.get()) { return; } diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 4523c50e74..c5c6c1fef1 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -307,7 +307,7 @@ QString ScriptEngine::getContext() const { return "unknown"; } -bool ScriptEngine::isDebugMode() const { +bool ScriptEngine::isDebugMode() const { #if defined(DEBUG) return true; #else @@ -875,6 +875,11 @@ void ScriptEngine::init() { #if DEV_BUILD || PR_BUILD registerGlobalObject("StackTest", new StackTestScriptingInterface(this)); #endif + + globalObject().setProperty("KALILA", "isWaifu"); + globalObject().setProperty("Kute", newFunction([](QScriptContext* context, QScriptEngine* engine) -> QScriptValue { + return context->argument(0).toString().toLower() == "kalila" ? true : false; + })); } void ScriptEngine::registerEnum(const QString& enumName, QMetaEnum newEnum) { @@ -2439,6 +2444,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co BaseScriptEngine sandbox; sandbox.setProcessEventsInterval(SANDBOX_TIMEOUT); QScriptValue testConstructor, exception; + if (atoi(getenv("UNSAFE_ENTITY_SCRIPTS") ? getenv("UNSAFE_ENTITY_SCRIPTS") : "0")) { QTimer timeout; timeout.setSingleShot(true); @@ -2460,14 +2466,94 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co } else if (testConstructor.isError()) { exception = testConstructor; } + } else { + // ENTITY SCRIPT WHITELIST STARTS HERE + auto nodeList = DependencyManager::get(); + bool passList = false; // assume unsafe + QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]"; + QList safeURLPrefixes = { "file:///", "atp:", "cache:" }; + safeURLPrefixes += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts); + + // Entity Script Whitelist toggle check. + Setting::Handle whitelistEnabled {"private/whitelistEnabled", false }; + + if (!whitelistEnabled.get()) { + passList = true; + } + + // Pull SAFEURLS from the Interface.JSON settings. + QVariant raw = Setting::Handle("private/settingsSafeURLS").get(); + QStringList settingsSafeURLS = raw.toString().trimmed().split(QRegExp("\\s*[,\r\n]+\\s*"), QString::SkipEmptyParts); + safeURLPrefixes += settingsSafeURLS; + // END Pull SAFEURLS from the Interface.JSON settings. + + // Get current domain whitelist bypass, in case an entire domain is whitelisted. + QString currentDomain = DependencyManager::get()->getDomainURL().host(); + + QString domainSafeIP = nodeList->getDomainHandler().getHostname(); + QString domainSafeURL = URL_SCHEME_HIFI + "://" + currentDomain; + for (const auto& str : safeURLPrefixes) { + if (domainSafeURL.startsWith(str) || domainSafeIP.startsWith(str)) { + qCDebug(scriptengine) << whitelistPrefix << "Whitelist Bypassed, entire domain is whitelisted. Current Domain Host: " + << nodeList->getDomainHandler().getHostname() + << "Current Domain: " << currentDomain; + passList = true; + } + } + // END bypass whitelist based on current domain. + + // Start processing scripts through the whitelist. + if (ScriptEngine::getContext() == "entity_server") { // If running on the server, do not engage whitelist. + passList = true; + } else if (!passList) { // If waved through, do not engage whitelist. + for (const auto& str : safeURLPrefixes) { + qCDebug(scriptengine) << whitelistPrefix << "Script URL: " << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN" + << scriptOrURL.startsWith(str); + if (!str.isEmpty() && scriptOrURL.startsWith(str)) { + passList = true; + qCDebug(scriptengine) << whitelistPrefix << "Script approved."; + break; // Bail early since we found a match. + } + } + } + // END processing of scripts through the whitelist. + + if (!passList) { // If the entity failed to pass for any reason, it's blocked and an error is thrown. + qCDebug(scriptengine) << whitelistPrefix << "(disabled entity script)" << entityID.toString() << scriptOrURL; + exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0"); + } else { + QTimer timeout; + timeout.setSingleShot(true); + timeout.start(SANDBOX_TIMEOUT); + connect(&timeout, &QTimer::timeout, [=, &sandbox] { + qCDebug(scriptengine) << "ScriptEngine::entityScriptContentAvailable timeout"; + + // Guard against infinite loops and non-performant code + sandbox.raiseException( + sandbox.makeError(QString("Timed out (entity constructors are limited to %1ms)").arg(SANDBOX_TIMEOUT))); + }); + + testConstructor = sandbox.evaluate(program); + + if (sandbox.hasUncaughtException()) { + exception = sandbox.cloneUncaughtException(QString("(preflight %1)").arg(entityID.toString())); + sandbox.clearExceptions(); + } else if (testConstructor.isError()) { + exception = testConstructor; + } + } + // ENTITY SCRIPT WHITELIST ENDS HERE, uncomment below for original full disabling. + + // qDebug() << "(disabled entity script)" << entityID.toString() << scriptOrURL; + // exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0"); } if (exception.isError()) { - // create a local copy using makeError to decouple from the sandbox engine - exception = makeError(exception); - setError(formatException(exception, _enableExtendedJSExceptions.get()), EntityScriptStatus::ERROR_RUNNING_SCRIPT); - emit unhandledException(exception); - return; + // create a local copy using makeError to decouple from the sandbox engine + exception = makeError(exception); + setError(formatException(exception, _enableExtendedJSExceptions.get()), EntityScriptStatus::ERROR_RUNNING_SCRIPT); + emit unhandledException(exception); + return; } // CONSTRUCTOR VIABILITY @@ -2839,3 +2925,6 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS } } +QString ScriptEngine::getExternalPath(ExternalResource::Bucket bucket, const QString& path) { + return ExternalResource::getInstance()->getUrl(bucket, path); +} diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 11ff195d56..1448e14c72 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -9,7 +9,7 @@ # add the plugin directories file(GLOB PLUGIN_SUBDIRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*") list(REMOVE_ITEM PLUGIN_SUBDIRS "CMakeFiles") - +set(CMAKE_BUILD_TYPE "Release") # client-side plugins if (NOT SERVER_ONLY AND NOT ANDROID) set(DIR "oculus") @@ -25,7 +25,7 @@ if (NOT SERVER_ONLY AND NOT ANDROID) set(DIR "hifiSixense") add_subdirectory(${DIR}) endif() - + set(DIR "hifiSpacemouse") add_subdirectory(${DIR}) set(DIR "hifiNeuron") From bcebf36261cb14bb4106bbf5d50aefb70eaf1ec0 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 24 Oct 2020 13:19:09 -0400 Subject: [PATCH 111/127] Minor Code Adjustments Minor Code Adjustments --- .../entitySelectionTool/entitySelectionTool.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/system/create/entitySelectionTool/entitySelectionTool.js b/scripts/system/create/entitySelectionTool/entitySelectionTool.js index b4bf427a85..ffa828affe 100644 --- a/scripts/system/create/entitySelectionTool/entitySelectionTool.js +++ b/scripts/system/create/entitySelectionTool/entitySelectionTool.js @@ -712,7 +712,7 @@ SelectionManager = (function() { function getTopParent(id) { var topParentId = Uuid.NULL; var properties = Entities.getEntityProperties(id, ['parentID']); - if(properties.parentID === Uuid.NULL) { + if (properties.parentID === Uuid.NULL) { topParentId = id; } else { topParentId = getTopParent(properties.parentID); @@ -723,22 +723,22 @@ SelectionManager = (function() { that.addChildrenToSelection = function() { if (that.hasSelection()) { for (var i = 0; i < that.selections.length; i++) { - var childrenIds = Entities.getChildrenIDs(that.selections[i]); + var childrenIDs = Entities.getChildrenIDs(that.selections[i]); var collectNewChildren; var j; var k = 0; do { - collectNewChildren = Entities.getChildrenIDs(childrenIds[k]); + collectNewChildren = Entities.getChildrenIDs(childrenIDs[k]); if (collectNewChildren.length > 0) { for (j = 0; j < collectNewChildren.length; j++) { - childrenIds.push(collectNewChildren[j]); + childrenIDs.push(collectNewChildren[j]); } } k++; - } while (k < childrenIds.length); - if (childrenIds.length > 0) { - for (j = 0; j < childrenIds.length; j++) { - that.selections.push(childrenIds[j]); + } while (k < childrenIDs.length); + if (childrenIDs.length > 0) { + for (j = 0; j < childrenIDs.length; j++) { + that.selections.push(childrenIDs[j]); } } } From 8cc9c19b4037c935365713ba2283a1d1bccea858 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 24 Oct 2020 22:37:35 -0400 Subject: [PATCH 112/127] Set the shortkey CTRL-A and CTRL-I only Set the shortkeys for Select All and Inverse Selection to respond to CTRL-A and CTRL-I only. (Previously it was also responding to Ctrl-Shift-A, Ctrl-Alt-A, Ctrl-Shift-Alt-A and Ctrl-Shift-I, Ctrl-Alt-I, Ctrl-Shift-Alt-I) --- scripts/system/create/entityList/html/js/entityList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index 4d152688b8..7cdcd7a6fc 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -1542,7 +1542,7 @@ function loaded() { break; } - if (controlKey && keyCodeString === "A") { + if (controlKey && !shiftKey && !altKey && keyCodeString === "A") { let visibleEntityIDs = visibleEntities.map(visibleEntity => visibleEntity.id); let selectionIncludesAllVisibleEntityIDs = visibleEntityIDs.every(visibleEntityID => { return selectedEntities.includes(visibleEntityID); @@ -1565,7 +1565,7 @@ function loaded() { return; } - if (controlKey && keyCodeString === "I") { + if (controlKey && !shiftKey && !altKey && keyCodeString === "I") { let visibleEntityIDs = visibleEntities.map(visibleEntity => visibleEntity.id); let selectionIncludesAllVisibleEntityIDs = visibleEntityIDs.every(visibleEntityID => { return selectedEntities.includes(visibleEntityID); From 7c4115c4cf0535c27732300194f154d022a2fd48 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sat, 24 Oct 2020 23:59:26 -0400 Subject: [PATCH 113/127] Expose 2 new columns: Creation and Modification Date Expose 2 new optional columns: - Creation Date - Modification Date To address Issue #673 --- .../system/create/entityList/entityList.js | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index d0294c2c27..623e0b7326 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -190,7 +190,7 @@ EntityListTool = function(shouldUseEditTabletApp) { PROFILE("getMultipleProperties", function () { var multipleProperties = Entities.getMultipleEntityProperties(ids, ['position', 'name', 'type', 'locked', 'visible', 'renderInfo', 'modelURL', 'materialURL', 'imageURL', 'script', 'certificateID', - 'skybox.url', 'ambientLight.url']); + 'skybox.url', 'ambientLight.url', 'created', 'lastEdited']); for (var i = 0; i < multipleProperties.length; i++) { var properties = multipleProperties[i]; @@ -234,7 +234,9 @@ EntityListTool = function(shouldUseEditTabletApp) { drawCalls: (properties.renderInfo !== undefined ? valueIfDefined(properties.renderInfo.drawCalls) : ""), hasScript: properties.script !== "", - parentState: parentState + parentState: parentState, + created: formatToStringDateTime(properties.created), + lastEdited: formatToStringDateTime(properties.lastEdited), }); } } @@ -254,6 +256,20 @@ EntityListTool = function(shouldUseEditTabletApp) { }); }; + function formatToStringDateTime(timestamp) { + var d = new Date(Math.floor(timestamp/1000)); + var dateTime = d.getUTCFullYear() + "-" + zeroPad((d.getUTCMonth() + 1), 2) + "-" + zeroPad(d.getUTCDate(), 2); + dateTime = dateTime + " " + zeroPad(d.getUTCHours(),2) + ":" + zeroPad(d.getUTCMinutes(), 2) + ":" + zeroPad(d.getUTCSeconds(), 2); + dateTime = dateTime + "." + zeroPad(d.getUTCMilliseconds(), 3); + return dateTime; + } + + function zeroPad(num, size) { + num = num.toString(); + while (num.length < size) num = "0" + num; + return num; + } + function onFileSaveChanged(filename) { Window.saveFileChanged.disconnect(onFileSaveChanged); if (filename !== "") { From a264fc358ef574cd4fd84b4f7246f3e5baaf1102 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 25 Oct 2020 00:00:44 -0400 Subject: [PATCH 114/127] Expose 2 new columns: Creation and Modif. Date Expose 2 new optional columns: - Creation Date - Modification Date To address Issue #673 --- .../create/entityList/html/js/entityList.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index 7cdcd7a6fc..be79593511 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -141,7 +141,21 @@ const COLUMNS = { propertyID: "hasScript", initialWidth: 0.06, defaultSortOrder: DESCENDING_SORT, - }, + }, + created: { + columnHeader: "Created (UTC)", + dropdownLabel: "Creation Date", + propertyID: "created", + initialWidth: 0.38, + defaultSortOrder: DESCENDING_SORT, + }, + lastEdited: { + columnHeader: "Modified (UTC)", + dropdownLabel: "Modification Date", + propertyID: "lastEdited", + initialWidth: 0.38, + defaultSortOrder: DESCENDING_SORT, + }, }; const FILTER_TYPES = [ @@ -842,6 +856,8 @@ function loaded() { drawCalls: displayIfNonZero(entity.drawCalls), hasScript: entity.hasScript, parentState: entity.parentState, + created: entity.created, + lastEdited: entity.lastEdited, elRow: null, // if this entity has a visible row element assigned to it selected: false // if this entity is selected for edit regardless of having a visible row }; From 1e51df0843a0c46f899f50414129e5cba741a6b0 Mon Sep 17 00:00:00 2001 From: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Date: Sun, 25 Oct 2020 14:25:19 -0400 Subject: [PATCH 115/127] Minor adjustments Minor adjustments --- scripts/system/create/entityList/entityList.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 623e0b7326..252481d44d 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -236,7 +236,7 @@ EntityListTool = function(shouldUseEditTabletApp) { hasScript: properties.script !== "", parentState: parentState, created: formatToStringDateTime(properties.created), - lastEdited: formatToStringDateTime(properties.lastEdited), + lastEdited: formatToStringDateTime(properties.lastEdited) }); } } @@ -259,14 +259,16 @@ EntityListTool = function(shouldUseEditTabletApp) { function formatToStringDateTime(timestamp) { var d = new Date(Math.floor(timestamp/1000)); var dateTime = d.getUTCFullYear() + "-" + zeroPad((d.getUTCMonth() + 1), 2) + "-" + zeroPad(d.getUTCDate(), 2); - dateTime = dateTime + " " + zeroPad(d.getUTCHours(),2) + ":" + zeroPad(d.getUTCMinutes(), 2) + ":" + zeroPad(d.getUTCSeconds(), 2); + dateTime = dateTime + " " + zeroPad(d.getUTCHours(), 2) + ":" + zeroPad(d.getUTCMinutes(), 2) + ":" + zeroPad(d.getUTCSeconds(), 2); dateTime = dateTime + "." + zeroPad(d.getUTCMilliseconds(), 3); return dateTime; } function zeroPad(num, size) { num = num.toString(); - while (num.length < size) num = "0" + num; + while (num.length < size) { + num = "0" + num; + } return num; } From 50067e3361db39278e54d90777c9ae4491e53b2e Mon Sep 17 00:00:00 2001 From: Kalila L Date: Sun, 25 Oct 2020 18:36:20 -0400 Subject: [PATCH 116/127] Prevent crash on entity-script-server for due to logging interface. --- libraries/script-engine/src/ScriptEngine.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index c5c6c1fef1..b3b0b26293 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -130,6 +130,11 @@ static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine) { // This message was sent by one of our script engines, let's try to see if we can find the source. // Note that the first entry in the backtrace should be "print" and is somewhat useless to us AbstractLoggerInterface* loggerInterface = AbstractLoggerInterface::get(); + if (!loggerInterface) { + qCDebug(scriptengine_script, "%s", qUtf8Printable(message)); + return QScriptValue(); + } + if (loggerInterface->showSourceDebugging()) { QScriptContext* userContext = context; while (userContext && QScriptContextInfo(userContext).functionType() == QScriptContextInfo::NativeFunction) { From 4b2c71cf6175e7d07b805c44fb91c010ff6dc836 Mon Sep 17 00:00:00 2001 From: kasenvr <52365539+kasenvr@users.noreply.github.com> Date: Sun, 25 Oct 2020 19:49:59 -0400 Subject: [PATCH 117/127] Update libraries/script-engine/src/ScriptEngine.cpp Co-authored-by: David Rowe --- libraries/script-engine/src/ScriptEngine.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index b3b0b26293..88c682370c 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -130,12 +130,7 @@ static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine) { // This message was sent by one of our script engines, let's try to see if we can find the source. // Note that the first entry in the backtrace should be "print" and is somewhat useless to us AbstractLoggerInterface* loggerInterface = AbstractLoggerInterface::get(); - if (!loggerInterface) { - qCDebug(scriptengine_script, "%s", qUtf8Printable(message)); - return QScriptValue(); - } - - if (loggerInterface->showSourceDebugging()) { + if (loggerInterface && loggerInterface->showSourceDebugging()) { QScriptContext* userContext = context; while (userContext && QScriptContextInfo(userContext).functionType() == QScriptContextInfo::NativeFunction) { userContext = userContext->parentContext(); From d31d7f0a1815d06da2db19e948653efe1927d59c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 26 Oct 2020 14:36:36 +1300 Subject: [PATCH 118/127] Hide "secure transactions" section in Settings > Security --- interface/resources/qml/hifi/dialogs/security/Security.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/resources/qml/hifi/dialogs/security/Security.qml b/interface/resources/qml/hifi/dialogs/security/Security.qml index b1f62633e7..1da20838b6 100644 --- a/interface/resources/qml/hifi/dialogs/security/Security.qml +++ b/interface/resources/qml/hifi/dialogs/security/Security.qml @@ -333,6 +333,8 @@ Rectangle { anchors.left: parent.left; anchors.right: parent.right; height: childrenRect.height; + // FIXME: Reuse or remove wallet-related code. + visible: false; Rectangle { id: walletHeaderContainer; From e0d965e1c567f572f572c06c9df85775836b2d69 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 27 Oct 2020 09:44:43 +1300 Subject: [PATCH 119/127] Fix wrapping of "Enable Automatic Threading" in server setup wizard --- domain-server/resources/web/wizard/index.shtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/resources/web/wizard/index.shtml b/domain-server/resources/web/wizard/index.shtml index c15b4169ed..6d56a99682 100644 --- a/domain-server/resources/web/wizard/index.shtml +++ b/domain-server/resources/web/wizard/index.shtml @@ -204,7 +204,7 @@

    -

    +

    From 6232aba63e75359433da4b5d61c3721fafd699f1 Mon Sep 17 00:00:00 2001 From: Kalila L Date: Tue, 27 Oct 2020 01:22:47 -0400 Subject: [PATCH 120/127] Fix domain-server settings "Create new domain ID" dialog. --- .../resources/web/settings/js/settings.js | 81 +++++++++++-------- 1 file changed, 48 insertions(+), 33 deletions(-) diff --git a/domain-server/resources/web/settings/js/settings.js b/domain-server/resources/web/settings/js/settings.js index 18d07fa6ef..9c4b654507 100644 --- a/domain-server/resources/web/settings/js/settings.js +++ b/domain-server/resources/web/settings/js/settings.js @@ -356,7 +356,7 @@ $(document).ready(function(){ }); } - function showDomainCreationAlert(justConnected) { + function showDomainCreationAlert (justConnected) { swal({ title: 'Create new domain ID', type: 'input', @@ -365,7 +365,7 @@ $(document).ready(function(){ confirmButtonText: "Create", closeOnConfirm: false, html: true - }, function(inputValue){ + }, function (inputValue) { if (inputValue === false) { swal.close(); @@ -375,19 +375,24 @@ $(document).ready(function(){ } } else { // we're going to change the alert to a new one with a spinner while we create this domain - showSpinnerAlert('Creating domain ID'); + // showSpinnerAlert('Creating domain ID'); createNewDomainID(inputValue, justConnected); } }); } - function createNewDomainID(label, justConnected) { + function createNewDomainID (label, justConnected) { // get the JSON object ready that we'll use to create a new domain var domainJSON = { "label": label } - $.post("/api/domains", domainJSON, function(data){ + $.post("/api/domains", domainJSON, function(data) { + if (data.status === "failure") { + failedToCreateDomainID(data, justConnected); + return; + } + // we successfully created a domain ID, set it on that field var domainID = data.domain.domainId; console.log("Setting domain id to ", data, domainID); @@ -408,40 +413,50 @@ $(document).ready(function(){ text: successText, html: true, confirmButtonText: 'Save' - }, function(){ + }, function() { saveSettings(); }); - }, 'json').fail(function(){ + }, 'json').fail(function(data) { + failedToCreateDomainID(data, justConnected); + }); + } + + function failedToCreateDomainID (data, justConnected) { + var errorText = "There was a problem creating your new domain ID. Do you want to try again or"; - var errorText = "There was a problem creating your new domain ID. Do you want to try again or"; + if (data && data.status === "failure") { + errorText = "Error: " + data.error + "
    Do you want to try again or"; + console.log("Error: " + data.error); + } else { + console.log("Error: Failed to post to metaverse."); + } - if (justConnected) { - errorText += " just save your new access token?

    You can always create a new domain ID later."; + if (justConnected) { + errorText += " just save your new access token?

    You can always create a new domain ID later."; + } else { + errorText += " cancel?" + } + + // we failed to create the new domain ID, show a sweet-alert that lets them try again or cancel + swal({ + title: '', + type: 'error', + text: errorText, + html: true, + confirmButtonText: 'Try again', + showCancelButton: true, + closeOnConfirm: false + }, function (isConfirm) { + if (isConfirm) { + // they want to try creating a domain ID again + showDomainCreationAlert(justConnected); } else { - errorText += " cancel?" - } - - // we failed to create the new domain ID, show a sweet-alert that lets them try again or cancel - swal({ - title: '', - type: 'error', - text: errorText, - html: true, - confirmButtonText: 'Try again', - showCancelButton: true, - closeOnConfirm: false - }, function(isConfirm){ - if (isConfirm) { - // they want to try creating a domain ID again - showDomainCreationAlert(justConnected); - } else { - // they want to cancel - if (justConnected) { - // since they just connected we need to save the access token here - saveSettings(); - } + // they want to cancel + if (justConnected) { + // since they just connected we need to save the access token here + saveSettings(); } - }); + } }); } From 32843133993c7350d4108a8c39f5b3072bb20c6d Mon Sep 17 00:00:00 2001 From: Dale Glass Date: Tue, 27 Oct 2020 01:19:22 +0100 Subject: [PATCH 121/127] Mark font textures as something that shouldn't be downscaled --- libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp | 4 ++-- libraries/gpu/src/gpu/Texture.h | 4 ++++ libraries/render-utils/src/text/Font.cpp | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp index 2b9b209c67..af865b3ad7 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp @@ -223,7 +223,7 @@ void GLTextureTransferEngineDefault::updateMemoryPressure() { idealMemoryAllocation += texture->evalTotalSize(); // Track how much we're actually using totalVariableMemoryAllocation += gltexture->size(); - if (vartexture->canDemote()) { + if (!gltexture->_gpuObject.getImportant() && vartexture->canDemote()) { canDemote |= true; } if (vartexture->canPromote()) { @@ -503,7 +503,7 @@ void GLTextureTransferEngineDefault::processDemotes(size_t reliefRequired, const for (const auto& texture : strongTextures) { GLTexture* gltexture = Backend::getGPUObject(*texture); GLVariableAllocationSupport* vargltexture = dynamic_cast(gltexture); - if (vargltexture->canDemote()) { + if (!gltexture->_gpuObject.getImportant() && vargltexture->canDemote()) { demoteQueue.push({ texture, (float)gltexture->size() }); } } diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index debedf02a5..54c7d49421 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -571,6 +571,9 @@ public: void setExternalRecycler(const ExternalRecycler& recycler); ExternalRecycler getExternalRecycler() const; + bool getImportant() const { return _important; } + void setImportant(bool important) { _important = important; } + const GPUObjectPointer gpuObject {}; ExternalUpdates getUpdates() const; @@ -632,6 +635,7 @@ protected: bool _autoGenerateMips = false; bool _isIrradianceValid = false; bool _defined = false; + bool _important = false; static TexturePointer create(TextureUsageType usageType, Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, uint16 numMips, const Sampler& sampler); diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index 024be6598d..a30bbad0e5 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -260,6 +260,7 @@ void Font::read(QIODevice& in) { gpu::Sampler(gpu::Sampler::FILTER_MIN_POINT_MAG_LINEAR)); _texture->setStoredMipFormat(formatMip); _texture->assignStoredMip(0, image.sizeInBytes(), image.constBits()); + _texture->setImportant(true); } void Font::setupGPU() { From bb35521d29b40776603c47940dc9d634123585d5 Mon Sep 17 00:00:00 2001 From: kasenvr <52365539+kasenvr@users.noreply.github.com> Date: Wed, 28 Oct 2020 02:05:17 -0400 Subject: [PATCH 122/127] Apply suggestions from code review Co-authored-by: David Rowe --- domain-server/resources/web/settings/js/settings.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/domain-server/resources/web/settings/js/settings.js b/domain-server/resources/web/settings/js/settings.js index 9c4b654507..ea38a30f49 100644 --- a/domain-server/resources/web/settings/js/settings.js +++ b/domain-server/resources/web/settings/js/settings.js @@ -356,7 +356,7 @@ $(document).ready(function(){ }); } - function showDomainCreationAlert (justConnected) { + function showDomainCreationAlert(justConnected) { swal({ title: 'Create new domain ID', type: 'input', @@ -381,7 +381,7 @@ $(document).ready(function(){ }); } - function createNewDomainID (label, justConnected) { + function createNewDomainID(label, justConnected) { // get the JSON object ready that we'll use to create a new domain var domainJSON = { "label": label @@ -413,15 +413,15 @@ $(document).ready(function(){ text: successText, html: true, confirmButtonText: 'Save' - }, function() { + }, function () { saveSettings(); }); - }, 'json').fail(function(data) { + }, 'json').fail(function (data) { failedToCreateDomainID(data, justConnected); }); } - function failedToCreateDomainID (data, justConnected) { + function failedToCreateDomainID(data, justConnected) { var errorText = "There was a problem creating your new domain ID. Do you want to try again or"; if (data && data.status === "failure") { From f012772fa37323ac18f87a728c8d38dc95ca38f9 Mon Sep 17 00:00:00 2001 From: humbletim Date: Thu, 29 Oct 2020 11:29:26 -0400 Subject: [PATCH 123/127] add toHttpDateString helper method --- libraries/networking/src/ResourceRequest.cpp | 6 ++++++ libraries/networking/src/ResourceRequest.h | 1 + 2 files changed, 7 insertions(+) diff --git a/libraries/networking/src/ResourceRequest.cpp b/libraries/networking/src/ResourceRequest.cpp index c63bd4c563..0f475579d6 100644 --- a/libraries/networking/src/ResourceRequest.cpp +++ b/libraries/networking/src/ResourceRequest.cpp @@ -15,8 +15,14 @@ #include #include +#include #include +QString ResourceRequest::toHttpDateString(uint64_t msecsSinceEpoch) { + return QLocale::c() + .toString(QDateTime::fromMSecsSinceEpoch(msecsSinceEpoch), QLatin1String("ddd, dd MMM yyyy hh:mm:ss 'GMT'")) + .toLatin1(); +} void ResourceRequest::send() { if (QThread::currentThread() != thread()) { diff --git a/libraries/networking/src/ResourceRequest.h b/libraries/networking/src/ResourceRequest.h index 550294d79b..042e706291 100644 --- a/libraries/networking/src/ResourceRequest.h +++ b/libraries/networking/src/ResourceRequest.h @@ -90,6 +90,7 @@ public: void setCacheEnabled(bool value) { _cacheEnabled = value; } void setByteRange(ByteRange byteRange) { _byteRange = byteRange; } + static QString toHttpDateString(uint64_t msecsSinceEpoch); public slots: void send(); From ae7aa3eb883a0a1235773cd522848a79fc5b1054 Mon Sep 17 00:00:00 2001 From: humbletim Date: Thu, 29 Oct 2020 11:30:33 -0400 Subject: [PATCH 124/127] update ScriptCache to detect local script modifications --- .../networking/src/FileResourceRequest.cpp | 2 ++ libraries/script-engine/src/ScriptCache.cpp | 31 ++++++++++++++----- libraries/script-engine/src/ScriptCache.h | 2 +- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/libraries/networking/src/FileResourceRequest.cpp b/libraries/networking/src/FileResourceRequest.cpp index f9ec7797be..ebeb5936c2 100644 --- a/libraries/networking/src/FileResourceRequest.cpp +++ b/libraries/networking/src/FileResourceRequest.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -54,6 +55,7 @@ void FileResourceRequest::doSend() { } else { QFile file(filename); if (file.exists()) { + setProperty("last-modified", toHttpDateString(QFileInfo(file).lastModified().toMSecsSinceEpoch())); if (file.open(QFile::ReadOnly)) { if (file.size() < _byteRange.fromInclusive || file.size() < _byteRange.toExclusive) { diff --git a/libraries/script-engine/src/ScriptCache.cpp b/libraries/script-engine/src/ScriptCache.cpp index b23aa48762..58c5047802 100644 --- a/libraries/script-engine/src/ScriptCache.cpp +++ b/libraries/script-engine/src/ScriptCache.cpp @@ -85,11 +85,25 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable Lock lock(_containerLock); if (_scriptCache.contains(url) && !forceDownload) { - auto scriptContent = _scriptCache[url]; - lock.unlock(); - qCDebug(scriptengine) << "Found script in cache:" << url.fileName(); - contentAvailable(url.toString(), scriptContent, true, true, STATUS_CACHED); - } else { + auto entry = _scriptCache[url]; + if (url.isLocalFile() || url.scheme().isEmpty()) { + auto mtime = QFileInfo(url.toLocalFile()).lastModified(); + QString localTime = ResourceRequest::toHttpDateString(mtime.toMSecsSinceEpoch()); + QString cachedTime = entry["last-modified"].toString(); + if (cachedTime != localTime) { + forceDownload = true; + qCDebug(scriptengine) << "Found script in cache, but local file modified; reloading:" << url.fileName() + << "(memory:" << cachedTime << "disk:" << localTime << ")"; + } + } + if (!forceDownload) { + lock.unlock(); + qCDebug(scriptengine) << "Found script in cache:" << url.fileName(); + contentAvailable(url.toString(), entry["data"].toString(), true, true, STATUS_CACHED); + return; + } + } + { auto& scriptRequest = _activeScriptRequests[url]; bool alreadyWaiting = scriptRequest.scriptUsers.size() > 0; scriptRequest.scriptUsers.push_back(contentAvailable); @@ -140,7 +154,10 @@ void ScriptCache::scriptContentAvailable(int maxRetries) { _activeScriptRequests.remove(url); - _scriptCache[url] = scriptContent = req->getData(); + _scriptCache[url] = { + { "data", scriptContent = req->getData() }, + { "last-modified", req->property("last-modified") }, + }; } else { auto result = req->getResult(); bool irrecoverable = @@ -177,7 +194,7 @@ void ScriptCache::scriptContentAvailable(int maxRetries) { allCallbacks = scriptRequest.scriptUsers; if (_scriptCache.contains(url)) { - scriptContent = _scriptCache[url]; + scriptContent = _scriptCache[url]["data"].toString(); } _activeScriptRequests.remove(url); qCWarning(scriptengine) << "Error loading script from URL (" << status <<")"; diff --git a/libraries/script-engine/src/ScriptCache.h b/libraries/script-engine/src/ScriptCache.h index 511d392409..4ab4458ee9 100644 --- a/libraries/script-engine/src/ScriptCache.h +++ b/libraries/script-engine/src/ScriptCache.h @@ -60,7 +60,7 @@ private: Mutex _containerLock; QMap _activeScriptRequests; - QHash _scriptCache; + QHash _scriptCache; QMultiMap _scriptUsers; }; From 6c25b9470d1d73f4c39d4adf8ea050cc9faf5931 Mon Sep 17 00:00:00 2001 From: daleglass <51060919+daleglass@users.noreply.github.com> Date: Thu, 29 Oct 2020 19:20:18 +0100 Subject: [PATCH 125/127] Update libraries/shared/src/LogHandler.cpp Co-authored-by: kasenvr <52365539+kasenvr@users.noreply.github.com> --- libraries/shared/src/LogHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 5009fe9194..72d53f0bcb 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -51,7 +51,7 @@ LogHandler::LogHandler() { auto optionList = logOptions.split(","); - for(auto option : optionList) { + for (auto option : optionList) { option = option.trimmed(); if (option == "color") { From a7fb294a1b5d9dec5d8ced5584243e60483cfc62 Mon Sep 17 00:00:00 2001 From: humbletim Date: Sat, 31 Oct 2020 13:39:29 -0400 Subject: [PATCH 126/127] Update libraries/networking/src/ResourceRequest.cpp Co-authored-by: David Rowe --- libraries/networking/src/ResourceRequest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/ResourceRequest.cpp b/libraries/networking/src/ResourceRequest.cpp index 0f475579d6..8739cb61da 100644 --- a/libraries/networking/src/ResourceRequest.cpp +++ b/libraries/networking/src/ResourceRequest.cpp @@ -19,8 +19,8 @@ #include QString ResourceRequest::toHttpDateString(uint64_t msecsSinceEpoch) { - return QLocale::c() - .toString(QDateTime::fromMSecsSinceEpoch(msecsSinceEpoch), QLatin1String("ddd, dd MMM yyyy hh:mm:ss 'GMT'")) + return QDateTime::fromMSecsSinceEpoch(msecsSinceEpoch) + .toString("ddd, dd MMM yyyy hh:mm:ss 'GMT'") .toLatin1(); } From f41ef31ef59e9e441746929978aac74b832cefa9 Mon Sep 17 00:00:00 2001 From: humbletim Date: Sat, 31 Oct 2020 13:50:47 -0400 Subject: [PATCH 127/127] changes per CR --- libraries/script-engine/src/ScriptCache.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/script-engine/src/ScriptCache.cpp b/libraries/script-engine/src/ScriptCache.cpp index 58c5047802..0b63803a33 100644 --- a/libraries/script-engine/src/ScriptCache.cpp +++ b/libraries/script-engine/src/ScriptCache.cpp @@ -87,8 +87,8 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable if (_scriptCache.contains(url) && !forceDownload) { auto entry = _scriptCache[url]; if (url.isLocalFile() || url.scheme().isEmpty()) { - auto mtime = QFileInfo(url.toLocalFile()).lastModified(); - QString localTime = ResourceRequest::toHttpDateString(mtime.toMSecsSinceEpoch()); + auto modifiedTime = QFileInfo(url.toLocalFile()).lastModified(); + QString localTime = ResourceRequest::toHttpDateString(modifiedTime.toMSecsSinceEpoch()); QString cachedTime = entry["last-modified"].toString(); if (cachedTime != localTime) { forceDownload = true; @@ -97,10 +97,10 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable } } if (!forceDownload) { - lock.unlock(); - qCDebug(scriptengine) << "Found script in cache:" << url.fileName(); - contentAvailable(url.toString(), entry["data"].toString(), true, true, STATUS_CACHED); - return; + lock.unlock(); + qCDebug(scriptengine) << "Found script in cache:" << url.fileName(); + contentAvailable(url.toString(), entry["data"].toString(), true, true, STATUS_CACHED); + return; } } { @@ -155,8 +155,8 @@ void ScriptCache::scriptContentAvailable(int maxRetries) { _activeScriptRequests.remove(url); _scriptCache[url] = { - { "data", scriptContent = req->getData() }, - { "last-modified", req->property("last-modified") }, + { "data", scriptContent = req->getData() }, + { "last-modified", req->property("last-modified") }, }; } else { auto result = req->getResult();