From b6620f128bfdafc1f10ec5a0730ecfee727efd46 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 11 Aug 2016 11:06:36 -0700 Subject: [PATCH 01/32] Add asset server bandwidth to stats --- interface/resources/qml/Stats.qml | 6 ++++++ interface/src/ui/Stats.cpp | 3 +++ interface/src/ui/Stats.h | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index fe88899658..180e5e1bcc 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -99,6 +99,12 @@ Item { font.pixelSize: root.fontSize text: "Mbps In/Out: " + root.mbpsIn.toFixed(2) + "/" + root.mbpsOut.toFixed(2) } + Text { + color: root.fontColor; + font.pixelSize: root.fontSize + visible: root.expanded + text: "Asset Mbps In/Out: " + root.assetMbpsIn.toFixed(2) + "/" + root.assetMbpsOut.toFixed(2) + } } } diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index ec4b2280b6..7fdf5cd57d 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -136,6 +136,9 @@ void Stats::updateStats(bool force) { STAT_UPDATE_FLOAT(mbpsIn, (float)bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond() / 1000.0f, 0.01f); STAT_UPDATE_FLOAT(mbpsOut, (float)bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond() / 1000.0f, 0.01f); + STAT_UPDATE_FLOAT(assetMbpsIn, (float)bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AssetServer) / 1000.0f, 0.01f); + STAT_UPDATE_FLOAT(assetMbpsOut, (float)bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AssetServer) / 1000.0f, 0.01f); + // Second column: ping SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer); SharedNodePointer avatarMixerNode = nodeList->soloNodeOfType(NodeType::AvatarMixer); diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index f6643a1a7a..4be2d88d9e 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -43,6 +43,8 @@ class Stats : public QQuickItem { STATS_PROPERTY(int, packetOutCount, 0) STATS_PROPERTY(float, mbpsIn, 0) STATS_PROPERTY(float, mbpsOut, 0) + STATS_PROPERTY(float, assetMbpsIn, 0) + STATS_PROPERTY(float, assetMbpsOut, 0) STATS_PROPERTY(int, audioPing, 0) STATS_PROPERTY(int, avatarPing, 0) STATS_PROPERTY(int, entitiesPing, 0) @@ -128,6 +130,8 @@ signals: void packetOutCountChanged(); void mbpsInChanged(); void mbpsOutChanged(); + void assetMbpsInChanged(); + void assetMbpsOutChanged(); void audioPingChanged(); void avatarPingChanged(); void entitiesPingChanged(); From 4c150efc1155960b702cf3e89806159ed6d3ae02 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 11 Aug 2016 11:55:08 -0700 Subject: [PATCH 02/32] Categorize some debug logging in FBX parsing --- libraries/fbx/src/FBXReader_Material.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Material.cpp b/libraries/fbx/src/FBXReader_Material.cpp index eb25f1d8a2..8c0f4b34ac 100644 --- a/libraries/fbx/src/FBXReader_Material.cpp +++ b/libraries/fbx/src/FBXReader_Material.cpp @@ -9,7 +9,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "FBXReader.h" + #include +#include + #include #include #include @@ -20,9 +24,8 @@ #include #include #include -#include "FBXReader.h" -#include +#include "ModelFormatLogging.h" bool FBXMaterial::needTangentSpace() const { return !normalTexture.isNull(); @@ -258,11 +261,11 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) { } } } - qDebug() << " fbx material Name:" << material.name; + qCDebug(modelformat) << " fbx material Name:" << material.name; if (materialMap.contains(material.name)) { QJsonObject materialOptions = materialMap.value(material.name).toObject(); - qDebug() << "Mapping fbx material:" << material.name << " with HifiMaterial: " << materialOptions; + qCDebug(modelformat) << "Mapping fbx material:" << material.name << " with HifiMaterial: " << materialOptions; if (materialOptions.contains("scattering")) { float scattering = (float) materialOptions.value("scattering").toDouble(); From 473a7e95934e6e13cddce46ba99d9348aef86407 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 11 Aug 2016 15:17:36 -0700 Subject: [PATCH 03/32] Fix bandwidth calculations not including the full size of reliable ordered messages For reliable ordered messages, we were: * only tracking bandwidth for the first few packets of a message IF a message handler opted in to receiving pending (unfinished) messages. * tracking the entire thing all at once, when the entire messages was received. --- libraries/networking/src/PacketReceiver.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 530efc5fb3..df38a68515 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -215,6 +215,15 @@ void PacketReceiver::handleVerifiedPacket(std::unique_ptr packet) { _inPacketCount += 1; _inByteCount += nlPacket->size(); + SharedNodePointer matchingNode; + NodeType_t nodeType = NodeType::Unassigned; + if (!nlPacket->getSourceID().isNull()) { + auto nodeList = DependencyManager::get(); + matchingNode = nodeList->nodeWithUUID(nlPacket->getSourceID()); + nodeType = matchingNode->getType(); + } + emit dataReceived(nodeType, nlPacket->getPayloadSize()); + handleVerifiedMessage(receivedMessage, true); } @@ -224,6 +233,15 @@ void PacketReceiver::handleVerifiedMessagePacket(std::unique_ptr pa _inPacketCount += 1; _inByteCount += nlPacket->size(); + SharedNodePointer matchingNode; + NodeType_t nodeType = NodeType::Unassigned; + if (!nlPacket->getSourceID().isNull()) { + auto nodeList = DependencyManager::get(); + matchingNode = nodeList->nodeWithUUID(nlPacket->getSourceID()); + nodeType = matchingNode->getType(); + } + emit dataReceived(nodeType, nlPacket->getPayloadSize()); + auto key = std::pair(nlPacket->getSenderSockAddr(), nlPacket->getMessageNumber()); auto it = _pendingMessages.find(key); QSharedPointer message; @@ -294,7 +312,6 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer recei PacketType packetType = receivedMessage->getType(); if (matchingNode) { - emit dataReceived(matchingNode->getType(), receivedMessage->getSize()); matchingNode->recordBytesReceived(receivedMessage->getSize()); QMetaMethod metaMethod = listener.method; @@ -326,7 +343,6 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer recei } } else { // qDebug() << "Got verified unsourced packet list: " << QString(nlPacketList->getMessage()); - emit dataReceived(NodeType::Unassigned, receivedMessage->getSize()); // one final check on the QPointer before we invoke if (listener.object) { From 211da3c428da40c66684adf74fcb58cfcacd08e6 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 11 Aug 2016 16:49:29 -0700 Subject: [PATCH 04/32] Add more user activity tracking data --- interface/src/Application.cpp | 21 +++++++++++++++++++ .../entities/src/EntityScriptingInterface.cpp | 14 +++++++++++++ .../entities/src/EntityScriptingInterface.h | 12 +++++++++++ 3 files changed, 47 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3d519d1790..c4750c69df 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1145,10 +1145,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : static int SEND_STATS_INTERVAL_MS = 10000; static int NEARBY_AVATAR_RADIUS_METERS = 10; + static glm::vec3 lastAvatarPosition = getMyAvatar()->getPosition(); + static glm::mat4 lastHMDHeadPose = getHMDSensorPose(); + // Periodically send fps as a user activity event QTimer* sendStatsTimer = new QTimer(this); sendStatsTimer->setInterval(SEND_STATS_INTERVAL_MS); connect(sendStatsTimer, &QTimer::timeout, this, [this]() { + QJsonObject properties = {}; MemoryInfo memInfo; if (getMemoryInfo(memInfo)) { @@ -1190,6 +1194,23 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : properties["throttled"] = _displayPlugin ? _displayPlugin->isThrottled() : false; + glm::vec3 avatarPosition = getMyAvatar()->getPosition(); + properties["avatar_has_moved"] = lastAvatarPosition != avatarPosition; + lastAvatarPosition = avatarPosition; + + auto entityScriptingInterface = DependencyManager::get(); + auto entityActivityTracking = entityScriptingInterface->getActivityTracking(); + entityScriptingInterface->resetActivityTracking(); + properties["added_entity"] = entityActivityTracking.hasAddedEntity; + properties["deleted_entity"] = entityActivityTracking.hasDeletedEntity; + properties["edited_entity"] = entityActivityTracking.hasEditedEntity; + + auto hmdHeadPose = getHMDSensorPose(); + properties["hmd_head_pose_changed"] = isHMDMode() && (hmdHeadPose != lastHMDHeadPose); + lastHMDHeadPose = hmdHeadPose; + + properties["hand_pose_changed"] = false; + UserActivityLogger::getInstance().logAction("stats", properties); }); sendStatsTimer->start(); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 653b37c3bb..031847b3f3 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -40,6 +40,12 @@ void EntityScriptingInterface::queueEntityMessage(PacketType packetType, getEntityPacketSender()->queueEditEntityMessage(packetType, _entityTree, entityID, properties); } +void EntityScriptingInterface::resetActivityTracking() { + _activityTracking.hasAddedEntity = false; + _activityTracking.hasDeletedEntity = false; + _activityTracking.hasEditedEntity = false; +} + bool EntityScriptingInterface::canAdjustLocks() { auto nodeList = DependencyManager::get(); return nodeList->isAllowedEditor(); @@ -130,6 +136,8 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties, bool clientOnly) { + _activityTracking.hasAddedEntity = true; + EntityItemProperties propertiesWithSimID = convertLocationFromScriptSemantics(properties); propertiesWithSimID.setDimensionsInitialized(properties.dimensionsChanged()); @@ -200,6 +208,8 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties QUuid EntityScriptingInterface::addModelEntity(const QString& name, const QString& modelUrl, const QString& shapeType, bool dynamic, const glm::vec3& position, const glm::vec3& gravity) { + _activityTracking.hasAddedEntity = true; + EntityItemProperties properties; properties.setType(EntityTypes::Model); properties.setName(name); @@ -263,6 +273,8 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit } QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& scriptSideProperties) { + _activityTracking.hasEditedEntity = true; + EntityItemProperties properties = scriptSideProperties; auto dimensions = properties.getDimensions(); @@ -406,6 +418,8 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& } void EntityScriptingInterface::deleteEntity(QUuid id) { + _activityTracking.hasDeletedEntity = true; + EntityItemID entityID(id); bool shouldDelete = true; diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 5aa0f5907e..bde0974d7c 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -65,6 +65,13 @@ class EntityScriptingInterface : public OctreeScriptingInterface, public Depende public: EntityScriptingInterface(bool bidOnSimulationOwnership); + class ActivityTracking { + public: + bool hasAddedEntity { false }; + bool hasDeletedEntity { false }; + bool hasEditedEntity { false }; + }; + EntityEditPacketSender* getEntityPacketSender() const { return (EntityEditPacketSender*)getPacketSender(); } virtual NodeType_t getServerNodeType() const { return NodeType::EntityServer; } virtual OctreeEditPacketSender* createPacketSender() { return new EntityEditPacketSender(); } @@ -73,6 +80,9 @@ public: EntityTreePointer getEntityTree() { return _entityTree; } void setEntitiesScriptEngine(EntitiesScriptEngineProvider* engine); float calculateCost(float mass, float oldVelocity, float newVelocity); + + void resetActivityTracking(); + ActivityTracking getActivityTracking() const { return _activityTracking; } public slots: // returns true if the DomainServer will allow this Node/Avatar to make changes @@ -226,6 +236,8 @@ private: float _currentAvatarEnergy = { FLT_MAX }; float getCurrentAvatarEnergy() { return _currentAvatarEnergy; } void setCurrentAvatarEnergy(float energy); + + ActivityTracking _activityTracking; float costMultiplier = { 0.01f }; float getCostMultiplier(); From ccca6d935faffc6f9f06f7613472d360fa68abeb Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 12 Aug 2016 14:35:22 -0700 Subject: [PATCH 05/32] don't fade after physics kick in --- interface/src/Application.cpp | 5 ++++ libraries/entities/src/EntityItem.cpp | 1 + libraries/entities/src/EntityItem.h | 5 +++- .../render-utils/src/MeshPartPayload.cpp | 24 ++++++++++++------- libraries/render-utils/src/MeshPartPayload.h | 1 - 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3d519d1790..ef12dd3475 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1244,6 +1244,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _defaultSkybox->setCubemap(_defaultSkyboxTexture); _defaultSkybox->setColor({ 1.0, 1.0, 1.0 }); + EntityItem::setEntitiesShouldFadeFunction([this]() { + SharedNodePointer entityServerNode = DependencyManager::get()->soloNodeOfType(NodeType::EntityServer); + return entityServerNode && !isPhysicsEnabled(); + }); + // After all of the constructor is completed, then set firstRun to false. Setting::Handle firstRun{ Settings::firstRun, true }; firstRun.set(false); diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index b9f384f013..29cbfd79e6 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -35,6 +35,7 @@ int EntityItem::_maxActionsDataSize = 800; quint64 EntityItem::_rememberDeletedActionTime = 20 * USECS_PER_SECOND; +std::function EntityItem::_entitiesShouldFadeFunction = [](){ return true; }; EntityItem::EntityItem(const EntityItemID& entityItemID) : SpatiallyNestable(NestableType::Entity, entityItemID), diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index f12075d191..c705f9bf46 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -436,6 +436,8 @@ public: QUuid getOwningAvatarID() const { return _owningAvatarID; } void setOwningAvatarID(const QUuid& owningAvatarID) { _owningAvatarID = owningAvatarID; } + static void setEntitiesShouldFadeFunction(std::function func) { _entitiesShouldFadeFunction = func; } + static std::function getEntitiesShouldFadeFunction() { return _entitiesShouldFadeFunction; } virtual bool isTransparent() { return _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) < 1.0f : false; } protected: @@ -568,7 +570,8 @@ protected: quint64 _lastUpdatedAccelerationTimestamp { 0 }; quint64 _fadeStartTime { usecTimestampNow() }; - bool _isFading { true }; + static std::function _entitiesShouldFadeFunction; + bool _isFading { _entitiesShouldFadeFunction() }; }; #endif // hifi_EntityItem_h diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 38d181e748..63082a8995 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -15,6 +15,7 @@ #include "DeferredLightingEffect.h" #include "Model.h" +#include "EntityItem.h" using namespace render; @@ -517,10 +518,16 @@ void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline: } void ModelMeshPartPayload::startFade() { - _fadeStartTime = usecTimestampNow(); - _hasStartedFade = true; - _prevHasStartedFade = false; - _hasFinishedFade = false; + bool shouldFade = EntityItem::getEntitiesShouldFadeFunction()(); + if (shouldFade) { + _fadeStartTime = usecTimestampNow(); + _hasStartedFade = true; + _hasFinishedFade = false; + } else { + _isFading = true; + _hasStartedFade = true; + _hasFinishedFade = true; + } } void ModelMeshPartPayload::render(RenderArgs* args) const { @@ -533,10 +540,11 @@ void ModelMeshPartPayload::render(RenderArgs* args) const { // When an individual mesh parts like this finishes its fade, we will mark the Model as // having render items that need updating bool nextIsFading = _isFading ? isStillFading() : false; - if (_isFading != nextIsFading || _prevHasStartedFade != _hasStartedFade) { - _isFading = nextIsFading || _prevHasStartedFade != _hasStartedFade; - _hasFinishedFade = _prevHasStartedFade == _hasStartedFade && !_isFading; - _prevHasStartedFade = _hasStartedFade; + bool startFading = !_isFading && !_hasFinishedFade && _hasStartedFade; + bool endFading = _isFading && !nextIsFading; + if (startFading || endFading) { + _isFading = startFading; + _hasFinishedFade = endFading; _model->setRenderItemsNeedUpdate(); } diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index 67fb660f8b..29478b3b4e 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -110,7 +110,6 @@ public: private: quint64 _fadeStartTime { 0 }; bool _hasStartedFade { false }; - mutable bool _prevHasStartedFade{ false }; mutable bool _hasFinishedFade { false }; mutable bool _isFading { false }; }; From b5e2913eb90bea2b1ee36bbb67dc7f94ad0b02b1 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 15 Aug 2016 09:22:56 -0700 Subject: [PATCH 06/32] Move node received bandwidth tracking to LimitedNodeList --- interface/src/Application.cpp | 2 +- libraries/networking/src/LimitedNodeList.cpp | 11 +++++++++-- libraries/networking/src/LimitedNodeList.h | 3 ++- libraries/networking/src/PacketReceiver.cpp | 18 ------------------ libraries/networking/src/PacketReceiver.h | 3 --- 5 files changed, 12 insertions(+), 25 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3d519d1790..71bb7fbb66 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -845,7 +845,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : QSharedPointer bandwidthRecorder = DependencyManager::get(); connect(nodeList.data(), &LimitedNodeList::dataSent, bandwidthRecorder.data(), &BandwidthRecorder::updateOutboundData); - connect(&nodeList->getPacketReceiver(), &PacketReceiver::dataReceived, + connect(nodeList.data(), &LimitedNodeList::dataReceived, bandwidthRecorder.data(), &BandwidthRecorder::updateInboundData); // FIXME -- I'm a little concerned about this. diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 431d372089..6d9de2dbc1 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -175,7 +175,11 @@ QUdpSocket& LimitedNodeList::getDTLSSocket() { } bool LimitedNodeList::isPacketVerified(const udt::Packet& packet) { - return packetVersionMatch(packet) && packetSourceAndHashMatch(packet); + // We track bandwidth when doing packet verification to avoid needing to do a node lookup + // later when we already do it in packetSourceAndHashMatchAndTrackBandwidth. A node lookup + // incurs a lock, so it is ideal to avoid needing to do it 2+ times for each packet + // received. + return packetVersionMatch(packet) && packetSourceAndHashMatchAndTrackBandwidth(packet); } bool LimitedNodeList::packetVersionMatch(const udt::Packet& packet) { @@ -224,11 +228,12 @@ bool LimitedNodeList::packetVersionMatch(const udt::Packet& packet) { } } -bool LimitedNodeList::packetSourceAndHashMatch(const udt::Packet& packet) { +bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packet& packet) { PacketType headerType = NLPacket::typeInHeader(packet); if (NON_SOURCED_PACKETS.contains(headerType)) { + emit dataReceived(NodeType::Unassigned, packet.getPayloadSize()); return true; } else { QUuid sourceID = NLPacket::sourceIDInHeader(packet); @@ -260,6 +265,8 @@ bool LimitedNodeList::packetSourceAndHashMatch(const udt::Packet& packet) { // from this sending node matchingNode->setLastHeardMicrostamp(usecTimestampNow()); + emit dataReceived(matchingNode->getType(), packet.getPayloadSize()); + return true; } else { diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 48379b5e39..49a3a155a2 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -243,6 +243,7 @@ public slots: signals: void dataSent(quint8 channelType, int bytes); + void dataReceived(quint8 channelType, int bytes); // QUuid might be zero for non-sourced packet types. void packetVersionMismatch(PacketType type, const HifiSockAddr& senderSockAddr, const QUuid& senderUUID); @@ -279,7 +280,7 @@ protected: void setLocalSocket(const HifiSockAddr& sockAddr); - bool packetSourceAndHashMatch(const udt::Packet& packet); + bool packetSourceAndHashMatchAndTrackBandwidth(const udt::Packet& packet); void processSTUNResponse(std::unique_ptr packet); void handleNodeKill(const SharedNodePointer& node); diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index df38a68515..21ba7129d4 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -215,15 +215,6 @@ void PacketReceiver::handleVerifiedPacket(std::unique_ptr packet) { _inPacketCount += 1; _inByteCount += nlPacket->size(); - SharedNodePointer matchingNode; - NodeType_t nodeType = NodeType::Unassigned; - if (!nlPacket->getSourceID().isNull()) { - auto nodeList = DependencyManager::get(); - matchingNode = nodeList->nodeWithUUID(nlPacket->getSourceID()); - nodeType = matchingNode->getType(); - } - emit dataReceived(nodeType, nlPacket->getPayloadSize()); - handleVerifiedMessage(receivedMessage, true); } @@ -233,15 +224,6 @@ void PacketReceiver::handleVerifiedMessagePacket(std::unique_ptr pa _inPacketCount += 1; _inByteCount += nlPacket->size(); - SharedNodePointer matchingNode; - NodeType_t nodeType = NodeType::Unassigned; - if (!nlPacket->getSourceID().isNull()) { - auto nodeList = DependencyManager::get(); - matchingNode = nodeList->nodeWithUUID(nlPacket->getSourceID()); - nodeType = matchingNode->getType(); - } - emit dataReceived(nodeType, nlPacket->getPayloadSize()); - auto key = std::pair(nlPacket->getSenderSockAddr(), nlPacket->getMessageNumber()); auto it = _pendingMessages.find(key); QSharedPointer message; diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index ff4ab3e15c..4b4d260409 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -67,9 +67,6 @@ public: void handleVerifiedPacket(std::unique_ptr packet); void handleVerifiedMessagePacket(std::unique_ptr message); void handleMessageFailure(HifiSockAddr from, udt::Packet::MessageNumber messageNumber); - -signals: - void dataReceived(quint8 channelType, int bytes); private: struct Listener { From 493adca04f154104fb51ccec853b6f8b584051d7 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 15 Aug 2016 10:02:53 -0700 Subject: [PATCH 07/32] map oculus grip to trigger --- interface/resources/controllers/oculus_touch.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/controllers/oculus_touch.json b/interface/resources/controllers/oculus_touch.json index ef5d8c59a8..ec78db38d8 100644 --- a/interface/resources/controllers/oculus_touch.json +++ b/interface/resources/controllers/oculus_touch.json @@ -22,7 +22,7 @@ }, { "from": "OculusTouch.LT", "to": "Standard.LT" }, { "from": "OculusTouch.LS", "to": "Standard.LS" }, - { "from": "OculusTouch.LeftGrip", "to": "Standard.LeftGrip" }, + { "from": "OculusTouch.LeftGrip", "to": "Standard.LT" }, { "from": "OculusTouch.LeftHand", "to": "Standard.LeftHand" }, { "from": "OculusTouch.RY", "to": "Standard.RY", @@ -38,7 +38,7 @@ }, { "from": "OculusTouch.RT", "to": "Standard.RT" }, { "from": "OculusTouch.RS", "to": "Standard.RS" }, - { "from": "OculusTouch.RightGrip", "to": "Standard.RightGrip" }, + { "from": "OculusTouch.RightGrip", "to": "Standard.RT" }, { "from": "OculusTouch.RightHand", "to": "Standard.RightHand" }, { "from": "OculusTouch.LeftApplicationMenu", "to": "Standard.Back" }, From a078b20f9da70e5d7940d6d7b25616beef102d73 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 15 Aug 2016 10:24:24 -0700 Subject: [PATCH 08/32] make it work with click --- .../resources/controllers/oculus_touch.json | 62 ------------------- 1 file changed, 62 deletions(-) delete mode 100644 interface/resources/controllers/oculus_touch.json diff --git a/interface/resources/controllers/oculus_touch.json b/interface/resources/controllers/oculus_touch.json deleted file mode 100644 index ec78db38d8..0000000000 --- a/interface/resources/controllers/oculus_touch.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "Oculus Touch to Standard", - "channels": [ - { "from": "OculusTouch.A", "to": "Standard.RightPrimaryThumb", "peek": true }, - { "from": "OculusTouch.X", "to": "Standard.LeftPrimaryThumb", "peek": true }, - - { "from": "OculusTouch.A", "to": "Standard.A" }, - { "from": "OculusTouch.B", "to": "Standard.B" }, - { "from": "OculusTouch.X", "to": "Standard.X" }, - { "from": "OculusTouch.Y", "to": "Standard.Y" }, - - { "from": "OculusTouch.LY", "to": "Standard.LY", - "filters": [ - { "type": "deadZone", "min": 0.05 }, - "invert" - ] - }, - { "from": "OculusTouch.LX", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Standard.LX" }, - { "from": "OculusTouch.LT", "to": "Standard.LTClick", - "peek": true, - "filters": [ { "type": "hysteresis", "min": 0.85, "max": 0.9 } ] - }, - { "from": "OculusTouch.LT", "to": "Standard.LT" }, - { "from": "OculusTouch.LS", "to": "Standard.LS" }, - { "from": "OculusTouch.LeftGrip", "to": "Standard.LT" }, - { "from": "OculusTouch.LeftHand", "to": "Standard.LeftHand" }, - - { "from": "OculusTouch.RY", "to": "Standard.RY", - "filters": [ - { "type": "deadZone", "min": 0.05 }, - "invert" - ] - }, - { "from": "OculusTouch.RX", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Standard.RX" }, - { "from": "OculusTouch.RT", "to": "Standard.RTClick", - "peek": true, - "filters": [ { "type": "hysteresis", "min": 0.85, "max": 0.9 } ] - }, - { "from": "OculusTouch.RT", "to": "Standard.RT" }, - { "from": "OculusTouch.RS", "to": "Standard.RS" }, - { "from": "OculusTouch.RightGrip", "to": "Standard.RT" }, - { "from": "OculusTouch.RightHand", "to": "Standard.RightHand" }, - - { "from": "OculusTouch.LeftApplicationMenu", "to": "Standard.Back" }, - { "from": "OculusTouch.RightApplicationMenu", "to": "Standard.Start" }, - - { "from": "OculusTouch.LeftPrimaryThumbTouch", "to": "Standard.LeftPrimaryThumbTouch" }, - { "from": "OculusTouch.LeftSecondaryThumbTouch", "to": "Standard.LeftSecondaryThumbTouch" }, - { "from": "OculusTouch.RightPrimaryThumbTouch", "to": "Standard.RightPrimaryThumbTouch" }, - { "from": "OculusTouch.RightSecondaryThumbTouch", "to": "Standard.RightSecondaryThumbTouch" }, - { "from": "OculusTouch.LeftPrimaryIndexTouch", "to": "Standard.LeftPrimaryIndexTouch" }, - { "from": "OculusTouch.RightPrimaryIndexTouch", "to": "Standard.RightPrimaryIndexTouch" }, - { "from": "OculusTouch.LSTouch", "to": "Standard.LSTouch" }, - { "from": "OculusTouch.RSTouch", "to": "Standard.RSTouch" }, - { "from": "OculusTouch.LeftThumbUp", "to": "Standard.LeftThumbUp" }, - { "from": "OculusTouch.RightThumbUp", "to": "Standard.RightThumbUp" }, - { "from": "OculusTouch.LeftIndexPoint", "to": "Standard.LeftIndexPoint" }, - { "from": "OculusTouch.RightIndexPoint", "to": "Standard.RightIndexPoint" } - ] -} - - From 2598d27cf3d5d5a600f321cb4b9877aca6ba1f2e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 15 Aug 2016 10:29:19 -0700 Subject: [PATCH 09/32] Add hand_pose_changed implementation for stats --- interface/src/Application.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c4750c69df..a6484c6c9c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1147,6 +1147,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : static glm::vec3 lastAvatarPosition = getMyAvatar()->getPosition(); static glm::mat4 lastHMDHeadPose = getHMDSensorPose(); + static controller::Pose lastLeftHandPose = getMyAvatar()->getLeftHandPose(); + static controller::Pose lastRightHandPose = getMyAvatar()->getRightHandPose(); // Periodically send fps as a user activity event QTimer* sendStatsTimer = new QTimer(this); @@ -1209,7 +1211,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : properties["hmd_head_pose_changed"] = isHMDMode() && (hmdHeadPose != lastHMDHeadPose); lastHMDHeadPose = hmdHeadPose; - properties["hand_pose_changed"] = false; + auto leftHandPose = getMyAvatar()->getLeftHandPose(); + auto rightHandPose = getMyAvatar()->getRightHandPose(); + // controller::Pose considers two poses to be different if either are invalid. In our case, we actually + // want to consider the pose to be unchanged if it was invalid and still is invalid, so we check that first. + properties["hand_pose_changed"] = + (!(leftHandPose.valid || lastLeftHandPose.valid) && (leftHandPose != lastLeftHandPose)) + || (!(rightHandPose.valid || lastRightHandPose.valid) && (rightHandPose != lastRightHandPose)); + lastLeftHandPose = leftHandPose; + lastRightHandPose = rightHandPose; UserActivityLogger::getInstance().logAction("stats", properties); }); From f143c62e9cd92396593d98ad29a68b1ad869ae4f Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 15 Aug 2016 11:53:32 -0700 Subject: [PATCH 10/32] whoops --- .../resources/controllers/oculus_touch.json | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 interface/resources/controllers/oculus_touch.json diff --git a/interface/resources/controllers/oculus_touch.json b/interface/resources/controllers/oculus_touch.json new file mode 100644 index 0000000000..fe2aa03032 --- /dev/null +++ b/interface/resources/controllers/oculus_touch.json @@ -0,0 +1,69 @@ +{ + "name": "Oculus Touch to Standard", + "channels": [ + { "from": "OculusTouch.A", "to": "Standard.RightPrimaryThumb", "peek": true }, + { "from": "OculusTouch.X", "to": "Standard.LeftPrimaryThumb", "peek": true }, + + { "from": "OculusTouch.A", "to": "Standard.A" }, + { "from": "OculusTouch.B", "to": "Standard.B" }, + { "from": "OculusTouch.X", "to": "Standard.X" }, + { "from": "OculusTouch.Y", "to": "Standard.Y" }, + + { "from": "OculusTouch.LY", "to": "Standard.LY", + "filters": [ + { "type": "deadZone", "min": 0.05 }, + "invert" + ] + }, + { "from": "OculusTouch.LX", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Standard.LX" }, + { "from": "OculusTouch.LT", "to": "Standard.LTClick", + "peek": true, + "filters": [ { "type": "hysteresis", "min": 0.85, "max": 0.9 } ] + }, + { "from": "OculusTouch.LT", "to": "Standard.LT" }, + { "from": "OculusTouch.LS", "to": "Standard.LS" }, + { "from": "OculusTouch.LeftGrip", "to": "Standard.LT" }, + { "from": "OculusTouch.LeftGrip", "to": "Standard.LTClick", + "peek": true, + "filters": [ { "type": "hysteresis", "min": 0.85, "max": 0.9 } ] + }, + { "from": "OculusTouch.LeftHand", "to": "Standard.LeftHand" }, + + { "from": "OculusTouch.RY", "to": "Standard.RY", + "filters": [ + { "type": "deadZone", "min": 0.05 }, + "invert" + ] + }, + { "from": "OculusTouch.RX", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Standard.RX" }, + { "from": "OculusTouch.RT", "to": "Standard.RTClick", + "peek": true, + "filters": [ { "type": "hysteresis", "min": 0.85, "max": 0.9 } ] + }, + { "from": "OculusTouch.RT", "to": "Standard.RT" }, + { "from": "OculusTouch.RS", "to": "Standard.RS" }, + { "from": "OculusTouch.RightGrip", "to": "Standard.RT" }, + { "from": "OculusTouch.RightGrip", "to": "Standard.LTClick", + "peek": true, + "filters": [ { "type": "hysteresis", "min": 0.85, "max": 0.9 } ] + }, + { "from": "OculusTouch.RightHand", "to": "Standard.RightHand" }, + + { "from": "OculusTouch.LeftApplicationMenu", "to": "Standard.Back" }, + { "from": "OculusTouch.RightApplicationMenu", "to": "Standard.Start" }, + + { "from": "OculusTouch.LeftPrimaryThumbTouch", "to": "Standard.LeftPrimaryThumbTouch" }, + { "from": "OculusTouch.LeftSecondaryThumbTouch", "to": "Standard.LeftSecondaryThumbTouch" }, + { "from": "OculusTouch.RightPrimaryThumbTouch", "to": "Standard.RightPrimaryThumbTouch" }, + { "from": "OculusTouch.RightSecondaryThumbTouch", "to": "Standard.RightSecondaryThumbTouch" }, + { "from": "OculusTouch.LeftPrimaryIndexTouch", "to": "Standard.LeftPrimaryIndexTouch" }, + { "from": "OculusTouch.RightPrimaryIndexTouch", "to": "Standard.RightPrimaryIndexTouch" }, + { "from": "OculusTouch.LSTouch", "to": "Standard.LSTouch" }, + { "from": "OculusTouch.RSTouch", "to": "Standard.RSTouch" }, + { "from": "OculusTouch.LeftThumbUp", "to": "Standard.LeftThumbUp" }, + { "from": "OculusTouch.RightThumbUp", "to": "Standard.RightThumbUp" }, + { "from": "OculusTouch.LeftIndexPoint", "to": "Standard.LeftIndexPoint" }, + { "from": "OculusTouch.RightIndexPoint", "to": "Standard.RightIndexPoint" } + ] +} + From 5a2c7cf58ef1b7f3d74cf16883bf6cfd013388b1 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 16 Aug 2016 09:58:18 -0700 Subject: [PATCH 11/32] cleanup --- interface/resources/controllers/oculus_touch.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/resources/controllers/oculus_touch.json b/interface/resources/controllers/oculus_touch.json index fe2aa03032..c50f7681d9 100644 --- a/interface/resources/controllers/oculus_touch.json +++ b/interface/resources/controllers/oculus_touch.json @@ -22,11 +22,11 @@ }, { "from": "OculusTouch.LT", "to": "Standard.LT" }, { "from": "OculusTouch.LS", "to": "Standard.LS" }, - { "from": "OculusTouch.LeftGrip", "to": "Standard.LT" }, { "from": "OculusTouch.LeftGrip", "to": "Standard.LTClick", "peek": true, "filters": [ { "type": "hysteresis", "min": 0.85, "max": 0.9 } ] }, + { "from": "OculusTouch.LeftGrip", "to": "Standard.LT" }, { "from": "OculusTouch.LeftHand", "to": "Standard.LeftHand" }, { "from": "OculusTouch.RY", "to": "Standard.RY", @@ -42,11 +42,11 @@ }, { "from": "OculusTouch.RT", "to": "Standard.RT" }, { "from": "OculusTouch.RS", "to": "Standard.RS" }, - { "from": "OculusTouch.RightGrip", "to": "Standard.RT" }, - { "from": "OculusTouch.RightGrip", "to": "Standard.LTClick", + { "from": "OculusTouch.RightGrip", "to": "Standard.LTClick", "peek": true, "filters": [ { "type": "hysteresis", "min": 0.85, "max": 0.9 } ] }, + { "from": "OculusTouch.RightGrip", "to": "Standard.RT" }, { "from": "OculusTouch.RightHand", "to": "Standard.RightHand" }, { "from": "OculusTouch.LeftApplicationMenu", "to": "Standard.Back" }, From 1632f4cb3d448281bd6ca5134b286bbec67bf581 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 16 Aug 2016 10:52:05 -0700 Subject: [PATCH 12/32] better create locations --- scripts/system/edit.js | 53 +++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 19460b409b..e1360e2398 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1129,36 +1129,37 @@ function handeMenuEvent(menuItem) { tooltip.show(false); } -// This function tries to find a reasonable position to place a new entity based on the camera -// position. If a reasonable position within the world bounds can't be found, `null` will -// be returned. The returned position will also take into account grid snapping settings. function getPositionToCreateEntity() { - var distance = cameraManager.enabled ? cameraManager.zoomDistance : DEFAULT_ENTITY_DRAG_DROP_DISTANCE; - var direction = Quat.getFront(Camera.orientation); - var offset = Vec3.multiply(distance, direction); - var placementPosition = Vec3.sum(Camera.position, offset); - - var cameraPosition = Camera.position; - var HALF_TREE_SCALE = 16384; - - var cameraOutOfBounds = Math.abs(cameraPosition.x) > HALF_TREE_SCALE || Math.abs(cameraPosition.y) > HALF_TREE_SCALE || - Math.abs(cameraPosition.z) > HALF_TREE_SCALE; - var placementOutOfBounds = Math.abs(placementPosition.x) > HALF_TREE_SCALE || - Math.abs(placementPosition.y) > HALF_TREE_SCALE || - Math.abs(placementPosition.z) > HALF_TREE_SCALE; - - if (cameraOutOfBounds && placementOutOfBounds) { - return null; + var direction = Quat.getFront(MyAvatar.orientation); + var distance = 1; + var position = Vec3.sum(MyAvatar.position, Vec3.multiply(direction, distance)); + position.y +=0.5; + if (position.x > HALF_TREE_SCALE || position.y > HALF_TREE_SCALE || position.z > HALF_TREE_SCALE) { + return null } - - placementPosition.x = Math.min(HALF_TREE_SCALE, Math.max(-HALF_TREE_SCALE, placementPosition.x)); - placementPosition.y = Math.min(HALF_TREE_SCALE, Math.max(-HALF_TREE_SCALE, placementPosition.y)); - placementPosition.z = Math.min(HALF_TREE_SCALE, Math.max(-HALF_TREE_SCALE, placementPosition.z)); - - return placementPosition; + return position; } +function getPositionToImportEntity() { + var dimensions = Clipboard.getContentsDimensions(); + var HALF_TREE_SCALE = 16384; + var direction = Quat.getFront(MyAvatar.orientation); + var distance = 1; + if (dimensions.x > distance) { + distance = dimensions.x + } + if (dimensions.z > distance) { + distance = dimensions.z + } + var position = Vec3.sum(MyAvatar.position, Vec3.multiply(direction, distance)); + + if (position.x > HALF_TREE_SCALE || position.y > HALF_TREE_SCALE || position.z > HALF_TREE_SCALE) { + return null + } + + return position; +} function importSVO(importURL) { print("Import URL requested: " + importURL); if (!Entities.canAdjustLocks()) { @@ -1183,7 +1184,7 @@ function importSVO(importURL) { z: 0 }; if (Clipboard.getClipboardContentsLargestDimension() < VERY_LARGE) { - position = getPositionToCreateEntity(); + position = getPositionToImportEntity(); } if (position !== null && position !== undefined) { var pastedEntityIDs = Clipboard.pasteEntities(position); From c85e8d05805948a8810092316904868292200a1a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 16 Aug 2016 11:18:12 -0700 Subject: [PATCH 13/32] don't show equip sphere until hand is in position to equip. widen unequip/drop cone --- scripts/system/controllers/handControllerGrab.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index f29fdfb00a..929cd7d12a 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -96,7 +96,9 @@ var PICK_MAX_DISTANCE = 500; // max length of pick-ray // var EQUIP_RADIUS = 0.1; // radius used for palm vs equip-hotspot for equipping. -var EQUIP_HOTSPOT_RENDER_RADIUS = 0.3; // radius used for palm vs equip-hotspot for rendering hot-spots +// if EQUIP_HOTSPOT_RENDER_RADIUS is greater than zero, the hotspot will appear before the hand +// has reached the required position, and then grow larger once the hand is close enough to equip. +var EQUIP_HOTSPOT_RENDER_RADIUS = 0.0; // radius used for palm vs equip-hotspot for rendering hot-spots var NEAR_GRABBING_ACTION_TIMEFRAME = 0.05; // how quickly objects move to their new position @@ -110,13 +112,11 @@ var NEAR_GRABBING_KINEMATIC = true; // force objects to be kinematic when near-g // if an equipped item is "adjusted" to be too far from the hand it's in, it will be unequipped. var CHECK_TOO_FAR_UNEQUIP_TIME = 0.3; // seconds, duration between checks -var AUTO_UNEQUIP_DISTANCE_FACTOR = 1.2; // multiplied by maximum dimension of held item, > this means drop // // other constants // -var HOTSPOT_DRAW_DISTANCE = 10; var RIGHT_HAND = 1; var LEFT_HAND = 0; @@ -1619,7 +1619,7 @@ function MyController(hand) { z: 0 }; - var DROP_ANGLE = Math.PI / 7; + var DROP_ANGLE = Math.PI / 6; var HYSTERESIS_FACTOR = 1.1; var ROTATION_ENTER_THRESHOLD = Math.cos(DROP_ANGLE); var ROTATION_EXIT_THRESHOLD = Math.cos(DROP_ANGLE * HYSTERESIS_FACTOR); From 4d0c8191734eafee06cf3bad40997f02339f97d6 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 16 Aug 2016 13:26:33 -0700 Subject: [PATCH 14/32] remove peaking irradiance from default background --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8b401b132d..16d5fb3ee0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4279,7 +4279,7 @@ namespace render { sceneKeyLight->setDirection(DEFAULT_SKYBOX_DIRECTION); auto defaultSkyboxAmbientTexture = qApp->getDefaultSkyboxAmbientTexture(); - sceneKeyLight->setAmbientSphere(defaultSkyboxAmbientTexture->getIrradiance()); + // do not set the ambient sphere - it peaks too high, and causes flashing when turning sceneKeyLight->setAmbientMap(defaultSkyboxAmbientTexture); qApp->getDefaultSkybox()->render(batch, args->getViewFrustum()); From 8c559bc65d7b1904d8de80153030d1a10f324695 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 16 Aug 2016 13:27:22 -0700 Subject: [PATCH 15/32] use lights from nontextured skyboxes --- interface/src/Application.cpp | 56 ++++++++------- .../src/EntityTreeRenderer.cpp | 72 ++++++++----------- .../src/EntityTreeRenderer.h | 14 +--- libraries/model/src/model/Stage.cpp | 15 ---- libraries/model/src/model/Stage.h | 6 +- tests/render-perf/src/main.cpp | 4 -- 6 files changed, 65 insertions(+), 102 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 16d5fb3ee0..1eb1bd3535 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4253,6 +4253,21 @@ namespace render { auto backgroundMode = skyStage->getBackgroundMode(); switch (backgroundMode) { + case model::SunSkyStage::SKY_DEFAULT: { + static const glm::vec3 DEFAULT_SKYBOX_COLOR{ 255.0f / 255.0f, 220.0f / 255.0f, 194.0f / 255.0f }; + static const float DEFAULT_SKYBOX_INTENSITY{ 0.2f }; + static const float DEFAULT_SKYBOX_AMBIENT_INTENSITY{ 2.0f }; + static const glm::vec3 DEFAULT_SKYBOX_DIRECTION{ 0.0f, 0.0f, -1.0f }; + + auto scene = DependencyManager::get()->getStage(); + auto sceneKeyLight = scene->getKeyLight(); + scene->setSunModelEnable(false); + sceneKeyLight->setColor(DEFAULT_SKYBOX_COLOR); + sceneKeyLight->setIntensity(DEFAULT_SKYBOX_INTENSITY); + sceneKeyLight->setAmbientIntensity(DEFAULT_SKYBOX_AMBIENT_INTENSITY); + sceneKeyLight->setDirection(DEFAULT_SKYBOX_DIRECTION); + // fall through: render a skybox, if available + } case model::SunSkyStage::SKY_BOX: { auto skybox = skyStage->getSkybox(); if (skybox) { @@ -4260,33 +4275,22 @@ namespace render { skybox->render(batch, args->getViewFrustum()); break; } + // fall through: render defaults, if available } - - // Fall through: if no skybox is available, render the SKY_DOME - case model::SunSkyStage::SKY_DOME: { - if (Menu::getInstance()->isOptionChecked(MenuOption::DefaultSkybox)) { - static const glm::vec3 DEFAULT_SKYBOX_COLOR { 255.0f / 255.0f, 220.0f / 255.0f, 194.0f / 255.0f }; - static const float DEFAULT_SKYBOX_INTENSITY { 0.2f }; - static const float DEFAULT_SKYBOX_AMBIENT_INTENSITY { 2.0f }; - static const glm::vec3 DEFAULT_SKYBOX_DIRECTION { 0.0f, 0.0f, -1.0f }; - - auto scene = DependencyManager::get()->getStage(); - auto sceneKeyLight = scene->getKeyLight(); - scene->setSunModelEnable(false); - sceneKeyLight->setColor(DEFAULT_SKYBOX_COLOR); - sceneKeyLight->setIntensity(DEFAULT_SKYBOX_INTENSITY); - sceneKeyLight->setAmbientIntensity(DEFAULT_SKYBOX_AMBIENT_INTENSITY); - sceneKeyLight->setDirection(DEFAULT_SKYBOX_DIRECTION); - - auto defaultSkyboxAmbientTexture = qApp->getDefaultSkyboxAmbientTexture(); - // do not set the ambient sphere - it peaks too high, and causes flashing when turning - sceneKeyLight->setAmbientMap(defaultSkyboxAmbientTexture); - - qApp->getDefaultSkybox()->render(batch, args->getViewFrustum()); - } + case model::SunSkyStage::SKY_DEFAULT_AMBIENT_TEXTURE: { + if (Menu::getInstance()->isOptionChecked(MenuOption::DefaultSkybox)) { + auto scene = DependencyManager::get()->getStage(); + auto sceneKeyLight = scene->getKeyLight(); + auto defaultSkyboxAmbientTexture = qApp->getDefaultSkyboxAmbientTexture(); + // do not set the ambient sphere - it peaks too high, and causes flashing when turning + sceneKeyLight->setAmbientMap(defaultSkyboxAmbientTexture); + } + // fall through: render defaults, if available } - break; - + case model::SunSkyStage::SKY_DEFAULT_TEXTURE: + if (Menu::getInstance()->isOptionChecked(MenuOption::DefaultSkybox)) { + qApp->getDefaultSkybox()->render(batch, args->getViewFrustum()); + } case model::SunSkyStage::NO_BACKGROUND: default: // this line intentionally left blank @@ -4503,7 +4507,7 @@ void Application::clearDomainOctreeDetails() { auto skyStage = DependencyManager::get()->getSkyStage(); - skyStage->setBackgroundMode(model::SunSkyStage::SKY_DOME); + skyStage->setBackgroundMode(model::SunSkyStage::SKY_DEFAULT); _recentlyClearedDomain = true; } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 476e64e642..6ecf1813cf 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -351,10 +351,10 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr(skyStage->getSkybox()); - static QString userData; + // If there is no zone, use the default background if (!zone) { - userData = QString(); + _zoneUserData = QString(); skybox->clear(); _pendingSkyboxTexture = false; @@ -363,50 +363,31 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrresetAmbientSphere(); - sceneKeyLight->setAmbientMap(nullptr); - sceneKeyLight->setColor(_previousKeyLightColor); - sceneKeyLight->setIntensity(_previousKeyLightIntensity); - sceneKeyLight->setAmbientIntensity(_previousKeyLightAmbientIntensity); - sceneKeyLight->setDirection(_previousKeyLightDirection); - sceneStage->setSunModelEnable(_previousStageSunModelEnabled); - sceneStage->setLocation(_previousStageLongitude, _previousStageLatitude, - _previousStageAltitude); - sceneTime->setHour(_previousStageHour); - sceneTime->setDay(_previousStageDay); + sceneKeyLight->resetAmbientSphere(); + sceneKeyLight->setAmbientMap(nullptr); - _hasPreviousZone = false; - } - - skyStage->setBackgroundMode(model::SunSkyStage::SKY_DOME); // let the application background through - return; // Early exit - } - - if (!_hasPreviousZone) { - _previousKeyLightColor = sceneKeyLight->getColor(); - _previousKeyLightIntensity = sceneKeyLight->getIntensity(); - _previousKeyLightAmbientIntensity = sceneKeyLight->getAmbientIntensity(); - _previousKeyLightDirection = sceneKeyLight->getDirection(); - _previousStageSunModelEnabled = sceneStage->isSunModelEnabled(); - _previousStageLongitude = sceneLocation->getLongitude(); - _previousStageLatitude = sceneLocation->getLatitude(); - _previousStageAltitude = sceneLocation->getAltitude(); - _previousStageHour = sceneTime->getHour(); - _previousStageDay = sceneTime->getDay(); - _hasPreviousZone = true; + skyStage->setBackgroundMode(model::SunSkyStage::SKY_DEFAULT); + return; } + // Set the keylight sceneKeyLight->setColor(ColorUtils::toVec3(zone->getKeyLightProperties().getColor())); sceneKeyLight->setIntensity(zone->getKeyLightProperties().getIntensity()); sceneKeyLight->setAmbientIntensity(zone->getKeyLightProperties().getAmbientIntensity()); sceneKeyLight->setDirection(zone->getKeyLightProperties().getDirection()); - sceneStage->setSunModelEnable(zone->getStageProperties().getSunModelEnabled()); - sceneStage->setLocation(zone->getStageProperties().getLongitude(), zone->getStageProperties().getLatitude(), - zone->getStageProperties().getAltitude()); - sceneTime->setHour(zone->getStageProperties().calculateHour()); - sceneTime->setDay(zone->getStageProperties().calculateDay()); + // Set the stage + bool isSunModelEnabled = zone->getStageProperties().getSunModelEnabled(); + sceneStage->setSunModelEnable(isSunModelEnabled); + if (isSunModelEnabled) { + sceneStage->setLocation(zone->getStageProperties().getLongitude(), + zone->getStageProperties().getLatitude(), + zone->getStageProperties().getAltitude()); + sceneTime->setHour(zone->getStageProperties().calculateHour()); + sceneTime->setDay(zone->getStageProperties().calculateDay()); + } + + // Set the ambient texture bool isAmbientTextureSet = false; if (zone->getKeyLightProperties().getAmbientURL().isEmpty()) { _pendingAmbientTexture = false; @@ -429,12 +410,13 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrgetBackgroundMode()) { case BACKGROUND_MODE_SKYBOX: { skybox->setColor(zone->getSkyboxProperties().getColorVec3()); - if (userData != zone->getUserData()) { - userData = zone->getUserData(); - skybox->parse(userData); + if (_zoneUserData != zone->getUserData()) { + _zoneUserData = zone->getUserData(); + skybox->parse(_zoneUserData); } if (zone->getSkyboxProperties().getURL().isEmpty()) { skybox->setCubemap(nullptr); @@ -471,14 +453,18 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrclear(); _skyboxTexture.clear(); _pendingSkyboxTexture = false; // Let the application background through - skyStage->setBackgroundMode(model::SunSkyStage::SKY_DOME); + if (isAmbientTextureSet) { + skyStage->setBackgroundMode(model::SunSkyStage::SKY_DEFAULT_TEXTURE); + } else { + skyStage->setBackgroundMode(model::SunSkyStage::SKY_DEFAULT_AMBIENT_TEXTURE); + } break; } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 99c62ab5f6..cfd8595f78 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -185,25 +185,15 @@ private: QMultiMap _waitingOnPreload; - bool _hasPreviousZone { false }; std::shared_ptr _bestZone; float _bestZoneVolume; + QString _zoneUserData; + quint64 _lastZoneCheck { 0 }; const quint64 ZONE_CHECK_INTERVAL = USECS_PER_MSEC * 100; // ~10hz const float ZONE_CHECK_DISTANCE = 0.001f; - glm::vec3 _previousKeyLightColor; - float _previousKeyLightIntensity; - float _previousKeyLightAmbientIntensity; - glm::vec3 _previousKeyLightDirection; - bool _previousStageSunModelEnabled; - float _previousStageLongitude; - float _previousStageLatitude; - float _previousStageAltitude; - float _previousStageHour; - int _previousStageDay; - QHash _entitiesInScene; // For Scene.shouldRenderEntities QList _entityIDsLastInScene; diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index 23503ef6fb..6cfb77f2b2 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -244,21 +244,6 @@ void SunSkyStage::updateGraphicsObject() const { double originAlt = _earthSunModel.getAltitude(); _sunLight->setPosition(Vec3(0.0f, originAlt, 0.0f)); } - - // Background - switch (getBackgroundMode()) { - case NO_BACKGROUND: { - break; - } - case SKY_DOME: { - break; - } - case SKY_BOX: { - break; - } - case NUM_BACKGROUND_MODES: - Q_UNREACHABLE(); - }; } void SunSkyStage::setBackgroundMode(BackgroundMode mode) { diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index 335fb1c758..5f48824568 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -160,8 +160,10 @@ public: enum BackgroundMode { NO_BACKGROUND = 0, - SKY_DOME, + SKY_DEFAULT, SKY_BOX, + SKY_DEFAULT_AMBIENT_TEXTURE, + SKY_DEFAULT_TEXTURE, NUM_BACKGROUND_MODES, }; @@ -173,7 +175,7 @@ public: const SkyboxPointer& getSkybox() const { valid(); return _skybox; } protected: - BackgroundMode _backgroundMode = SKY_DOME; + BackgroundMode _backgroundMode = SKY_DEFAULT; LightPointer _sunLight; mutable SkyboxPointer _skybox; diff --git a/tests/render-perf/src/main.cpp b/tests/render-perf/src/main.cpp index 19dd875026..eec7e994ae 100644 --- a/tests/render-perf/src/main.cpp +++ b/tests/render-perf/src/main.cpp @@ -345,10 +345,6 @@ namespace render { break; } } - - // Fall through: if no skybox is available, render the SKY_DOME - case model::SunSkyStage::SKY_DOME: - case model::SunSkyStage::NO_BACKGROUND: default: // this line intentionally left blank break; From d6d9871a9692870d99c7377752a7f080263878c6 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 16 Aug 2016 14:36:54 -0700 Subject: [PATCH 16/32] unused var nits --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 6ecf1813cf..e36563681a 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -346,8 +346,6 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrgetStage(); auto skyStage = scene->getSkyStage(); auto sceneKeyLight = sceneStage->getKeyLight(); - auto sceneLocation = sceneStage->getLocation(); - auto sceneTime = sceneStage->getTime(); // Skybox and procedural skybox data auto skybox = std::dynamic_pointer_cast(skyStage->getSkybox()); @@ -383,6 +381,8 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrsetLocation(zone->getStageProperties().getLongitude(), zone->getStageProperties().getLatitude(), zone->getStageProperties().getAltitude()); + + auto sceneTime = sceneStage->getTime(); sceneTime->setHour(zone->getStageProperties().calculateHour()); sceneTime->setDay(zone->getStageProperties().calculateDay()); } From dae84617739a52c444b12dfde2eb7f6a0cb14c25 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 16 Aug 2016 15:42:17 -0700 Subject: [PATCH 17/32] Fix transparency on procedural shapes --- .../entities-renderer/src/RenderableShapeEntityItem.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index e14def114d..c3e097382c 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -91,6 +91,11 @@ void RenderableShapeEntityItem::render(RenderArgs* args) { _procedural.reset(new Procedural(getUserData())); _procedural->_vertexSource = simple_vert; _procedural->_fragmentSource = simple_frag; + _procedural->_opaqueState->setCullMode(gpu::State::CULL_NONE); + _procedural->_opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL); + _procedural->_opaqueState->setBlendFunction(false, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); } gpu::Batch& batch = *args->_batch; From 7bc1235c546e76f1b58959660c881e9643afcfc9 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 16 Aug 2016 16:47:13 -0700 Subject: [PATCH 18/32] local velocity and angular velocity in scripts is now handled the way local position and rotation are --- .../entities/src/EntityItemProperties.cpp | 12 ++- libraries/entities/src/EntityItemProperties.h | 2 + libraries/entities/src/EntityPropertyFlags.h | 3 + .../entities/src/EntityScriptingInterface.cpp | 34 ++++++++- libraries/shared/src/SpatiallyNestable.cpp | 76 +++++++++++++++++++ libraries/shared/src/SpatiallyNestable.h | 11 ++- .../system/controllers/handControllerGrab.js | 29 +------ 7 files changed, 136 insertions(+), 31 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index dcd7e25bc1..b3d810c0eb 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -325,6 +325,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_QUERY_AA_CUBE, queryAACube); CHECK_PROPERTY_CHANGE(PROP_LOCAL_POSITION, localPosition); CHECK_PROPERTY_CHANGE(PROP_LOCAL_ROTATION, localRotation); + CHECK_PROPERTY_CHANGE(PROP_LOCAL_VELOCITY, localVelocity); + CHECK_PROPERTY_CHANGE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity); CHECK_PROPERTY_CHANGE(PROP_FLYING_ALLOWED, flyingAllowed); CHECK_PROPERTY_CHANGE(PROP_GHOSTING_ALLOWED, ghostingAllowed); @@ -570,6 +572,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_POSITION, localPosition); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ROTATION, localRotation); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_VELOCITY, localVelocity); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLIENT_ONLY, clientOnly); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_OWNING_AVATAR_ID, owningAvatarID); @@ -707,6 +711,8 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(localPosition, glmVec3, setLocalPosition); COPY_PROPERTY_FROM_QSCRIPTVALUE(localRotation, glmQuat, setLocalRotation); + COPY_PROPERTY_FROM_QSCRIPTVALUE(localVelocity, glmVec3, setLocalVelocity); + COPY_PROPERTY_FROM_QSCRIPTVALUE(localAngularVelocity, glmVec3, setLocalAngularVelocity); COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotationsSet, qVectorBool, setJointRotationsSet); COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotations, qVectorQuat, setJointRotations); @@ -864,6 +870,8 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_LOCAL_POSITION, LocalPosition, localPosition, glm::vec3); ADD_PROPERTY_TO_MAP(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glm::quat); + ADD_PROPERTY_TO_MAP(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glm::vec3); + ADD_PROPERTY_TO_MAP(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glm::vec3); ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector); ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector); @@ -1982,7 +1990,9 @@ QList EntityItemProperties::listChangedProperties() { } bool EntityItemProperties::parentDependentPropertyChanged() const { - return localPositionChanged() || positionChanged() || localRotationChanged() || rotationChanged(); + return localPositionChanged() || positionChanged() || + localRotationChanged() || rotationChanged() || + localVelocityChanged() || localAngularVelocityChanged(); } bool EntityItemProperties::parentRelatedPropertyChanged() const { diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 6018ba793f..22d740e0dd 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -201,6 +201,8 @@ public: // these are used when bouncing location data into and out of scripts DEFINE_PROPERTY_REF(PROP_LOCAL_POSITION, LocalPosition, localPosition, glmVec3, ENTITY_ITEM_ZERO_VEC3); DEFINE_PROPERTY_REF(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glmQuat, ENTITY_ITEM_DEFAULT_ROTATION); + DEFINE_PROPERTY_REF(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glmVec3, ENTITY_ITEM_ZERO_VEC3); + DEFINE_PROPERTY_REF(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glmVec3, ENTITY_ITEM_ZERO_VEC3); DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector, QVector()); DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector, QVector()); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 36bb37c8f3..0baef0fa25 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -177,6 +177,9 @@ enum EntityPropertyList { PROP_SHAPE, + PROP_LOCAL_VELOCITY, // only used to convert values to and from scripts + PROP_LOCAL_ANGULAR_VELOCITY, // only used to convert values to and from scripts + //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 653b37c3bb..232b952a93 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -78,6 +78,8 @@ EntityItemProperties convertLocationToScriptSemantics(const EntityItemProperties EntityItemProperties scriptSideProperties = entitySideProperties; scriptSideProperties.setLocalPosition(entitySideProperties.getPosition()); scriptSideProperties.setLocalRotation(entitySideProperties.getRotation()); + scriptSideProperties.setLocalVelocity(entitySideProperties.getLocalVelocity()); + scriptSideProperties.setLocalAngularVelocity(entitySideProperties.getLocalAngularVelocity()); bool success; glm::vec3 worldPosition = SpatiallyNestable::localToWorld(entitySideProperties.getPosition(), @@ -88,10 +90,19 @@ EntityItemProperties convertLocationToScriptSemantics(const EntityItemProperties entitySideProperties.getParentID(), entitySideProperties.getParentJointIndex(), success); - // TODO -- handle velocity and angularVelocity + glm::vec3 worldVelocity = SpatiallyNestable::localToWorldVelocity(entitySideProperties.getVelocity(), + entitySideProperties.getParentID(), + entitySideProperties.getParentJointIndex(), + success); + glm::vec3 worldAngularVelocity = SpatiallyNestable::localToWorldAngularVelocity(entitySideProperties.getAngularVelocity(), + entitySideProperties.getParentID(), + entitySideProperties.getParentJointIndex(), + success); scriptSideProperties.setPosition(worldPosition); scriptSideProperties.setRotation(worldRotation); + scriptSideProperties.setVelocity(worldVelocity); + scriptSideProperties.setAngularVelocity(worldAngularVelocity); return scriptSideProperties; } @@ -125,6 +136,27 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti entitySideProperties.setRotation(localRotation); } + if (scriptSideProperties.localVelocityChanged()) { + entitySideProperties.setVelocity(scriptSideProperties.getLocalVelocity()); + } else if (scriptSideProperties.velocityChanged()) { + glm::vec3 localVelocity = SpatiallyNestable::worldToLocalVelocity(entitySideProperties.getVelocity(), + entitySideProperties.getParentID(), + entitySideProperties.getParentJointIndex(), + success); + entitySideProperties.setVelocity(localVelocity); + } + + if (scriptSideProperties.localAngularVelocityChanged()) { + entitySideProperties.setAngularVelocity(scriptSideProperties.getLocalAngularVelocity()); + } else if (scriptSideProperties.angularVelocityChanged()) { + glm::vec3 localAngularVelocity = + SpatiallyNestable::worldToLocalAngularVelocity(entitySideProperties.getAngularVelocity(), + entitySideProperties.getParentID(), + entitySideProperties.getParentJointIndex(), + success); + entitySideProperties.setAngularVelocity(localAngularVelocity); + } + return entitySideProperties; } diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index c3dbafa0d9..453035de0f 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -224,6 +224,38 @@ glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation, return result.getRotation(); } +glm::vec3 SpatiallyNestable::worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID, + int parentJointIndex, bool& success) { + SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success); + if (!success || !parent) { + return velocity; + } + Transform parentTransform = parent->getTransform(success); + if (!success) { + return velocity; + } + glm::vec3 parentVelocity = parent->getVelocity(success); + if (!success) { + return velocity; + } + + return glm::inverse(parentTransform.getRotation()) * (velocity - parentVelocity); +} + +glm::vec3 SpatiallyNestable::worldToLocalAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID, + int parentJointIndex, bool& success) { + SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success); + if (!success || !parent) { + return angularVelocity; + } + Transform parentTransform = parent->getTransform(success); + if (!success) { + return angularVelocity; + } + + return glm::inverse(parentTransform.getRotation()) * angularVelocity; +} + glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, bool& success) { @@ -298,6 +330,38 @@ glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation, return result.getRotation(); } +glm::vec3 SpatiallyNestable::localToWorldVelocity(const glm::vec3& velocity, const QUuid& parentID, + int parentJointIndex, bool& success) { + SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success); + if (!success || !parent) { + return velocity; + } + Transform parentTransform = parent->getTransform(success); + if (!success) { + return velocity; + } + glm::vec3 parentVelocity = parent->getVelocity(success); + if (!success) { + return velocity; + } + + return parentVelocity + parentTransform.getRotation() * velocity; +} + +glm::vec3 SpatiallyNestable::localToWorldAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID, + int parentJointIndex, bool& success) { + SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success); + if (!success || !parent) { + return angularVelocity; + } + Transform parentTransform = parent->getTransform(success); + if (!success) { + return angularVelocity; + } + + return parentTransform.getRotation() * angularVelocity; +} + glm::vec3 SpatiallyNestable::getPosition(bool& success) const { return getTransform(success).getTranslation(); } @@ -1004,3 +1068,15 @@ void SpatiallyNestable::setLocalTransformAndVelocities( locationChanged(false); } } + +SpatiallyNestablePointer SpatiallyNestable::findByID(QUuid id, bool& success) { + QSharedPointer parentFinder = DependencyManager::get(); + if (!parentFinder) { + return nullptr; + } + SpatiallyNestableWeakPointer parentWP = parentFinder->find(id, success); + if (!success) { + return nullptr; + } + return parentWP.lock(); +} diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 391f13cc27..5605cc0031 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -48,9 +48,17 @@ public: static glm::vec3 worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, bool& success); static glm::quat worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, bool& success); + static glm::vec3 worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID, + int parentJointIndex, bool& success); + static glm::vec3 worldToLocalAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID, + int parentJointIndex, bool& success); static glm::vec3 localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, bool& success); static glm::quat localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, bool& success); + static glm::vec3 localToWorldVelocity(const glm::vec3& velocity, + const QUuid& parentID, int parentJointIndex, bool& success); + static glm::vec3 localToWorldAngularVelocity(const glm::vec3& angularVelocity, + const QUuid& parentID, int parentJointIndex, bool& success); // world frame virtual const Transform getTransform(bool& success, int depth = 0) const; @@ -151,6 +159,8 @@ public: virtual SpatialParentTree* getParentTree() const { return nullptr; } bool hasAncestorOfType(NestableType nestableType); + SpatiallyNestablePointer getParentPointer(bool& success) const; + static SpatiallyNestablePointer findByID(QUuid id, bool& success); void getLocalTransformAndVelocities(Transform& localTransform, glm::vec3& localVelocity, @@ -166,7 +176,6 @@ protected: QUuid _id; QUuid _parentID; // what is this thing's transform relative to? quint16 _parentJointIndex { 0 }; // which joint of the parent is this relative to? - SpatiallyNestablePointer getParentPointer(bool& success) const; mutable SpatiallyNestableWeakPointer _parent; diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 929cd7d12a..1264502aa7 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -2204,28 +2204,13 @@ function MyController(hand) { var props = Entities.getEntityProperties(entityID, ["parentID", "velocity", "dynamic", "shapeType"]); var parentID = props.parentID; - var doSetVelocity = false; - if (parentID != NULL_UUID && deactiveProps.parentID == NULL_UUID && propsArePhysical(props)) { - // TODO: EntityScriptingInterface::convertLocationToScriptSemantics should be setting up - // props.velocity to be a world-frame velocity and localVelocity to be vs parent. Until that - // is done, we use a measured velocity here so that things held via a bumper-grab / parenting-grab - // can be thrown. - doSetVelocity = true; - } - if (!noVelocity && - !doSetVelocity && parentID == MyAvatar.sessionUUID && Vec3.length(data["gravity"]) > 0.0 && data["dynamic"] && data["parentID"] == NULL_UUID && !data["collisionless"]) { - deactiveProps["velocity"] = { - x: 0.0, - y: 0.1, - z: 0.0 - }; - doSetVelocity = false; + deactiveProps["velocity"] = this.currentVelocity; } if (noVelocity) { deactiveProps["velocity"] = { @@ -2238,21 +2223,9 @@ function MyController(hand) { y: 0.0, z: 0.0 }; - doSetVelocity = false; } Entities.editEntity(entityID, deactiveProps); - - if (doSetVelocity) { - // this is a continuation of the TODO above -- we shouldn't need to set this here. - // do this after the parent has been reset. setting this at the same time as - // the parent causes it to go off in the wrong direction. This is a bug that should - // be fixed. - Entities.editEntity(entityID, { - velocity: this.currentVelocity - // angularVelocity: this.currentAngularVelocity - }); - } data = null; } else if (this.shouldResetParentOnRelease) { // we parent-grabbed this from another parent grab. try to put it back where we found it. From 727d59ab27f290317654902e1f1903824643ed70 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 16 Aug 2016 17:33:32 -0700 Subject: [PATCH 19/32] Add backup directory setting to domain server --- assignment-client/src/octree/OctreeServer.cpp | 56 +++++++++++++++---- assignment-client/src/octree/OctreeServer.h | 1 + .../resources/describe-settings.json | 8 +++ libraries/octree/src/OctreePersistThread.cpp | 20 ++++--- libraries/octree/src/OctreePersistThread.h | 7 ++- 5 files changed, 70 insertions(+), 22 deletions(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index d763d1abe7..48ffc2fdbc 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -1063,6 +1063,12 @@ void OctreeServer::readConfiguration() { _wantBackup = !noBackup; qDebug() << "wantBackup=" << _wantBackup; + if (!readOptionString("backupDirectoryPath", settingsSectionObject, _backupDirectoryPath)) { + _backupDirectoryPath = ""; + } + + qDebug() << "backupDirectoryPath=" << _backupDirectoryPath; + readOptionBool(QString("persistFileDownload"), settingsSectionObject, _persistFileDownload); qDebug() << "persistFileDownload=" << _persistFileDownload; @@ -1160,25 +1166,25 @@ void OctreeServer::domainSettingsRequestComplete() { // If persist filename does not exist, let's see if there is one beside the application binary // If there is, let's copy it over to our target persist directory QDir persistPath { _persistFilePath }; - QString absoluteFilePath = persistPath.absolutePath(); + QString persistAbsoluteFilePath = persistPath.absolutePath(); if (persistPath.isRelative()) { // if the domain settings passed us a relative path, make an absolute path that is relative to the // default data directory - absoluteFilePath = QDir(ServerPathUtils::getDataFilePath("entities/")).absoluteFilePath(_persistFilePath); + persistAbsoluteFilePath = QDir(ServerPathUtils::getDataFilePath("entities/")).absoluteFilePath(_persistFilePath); } static const QString ENTITY_PERSIST_EXTENSION = ".json.gz"; // force the persist file to end with .json.gz - if (!absoluteFilePath.endsWith(ENTITY_PERSIST_EXTENSION, Qt::CaseInsensitive)) { - absoluteFilePath += ENTITY_PERSIST_EXTENSION; + if (!persistAbsoluteFilePath.endsWith(ENTITY_PERSIST_EXTENSION, Qt::CaseInsensitive)) { + persistAbsoluteFilePath += ENTITY_PERSIST_EXTENSION; } else { // make sure the casing of .json.gz is correct - absoluteFilePath.replace(ENTITY_PERSIST_EXTENSION, ENTITY_PERSIST_EXTENSION, Qt::CaseInsensitive); + persistAbsoluteFilePath.replace(ENTITY_PERSIST_EXTENSION, ENTITY_PERSIST_EXTENSION, Qt::CaseInsensitive); } - if (!QFile::exists(absoluteFilePath)) { + if (!QFile::exists(persistAbsoluteFilePath)) { qDebug() << "Persist file does not exist, checking for existence of persist file next to application"; static const QString OLD_DEFAULT_PERSIST_FILENAME = "resources/models.json.gz"; @@ -1204,7 +1210,7 @@ void OctreeServer::domainSettingsRequestComplete() { pathToCopyFrom = oldDefaultPersistPath; } - QDir persistFileDirectory { QDir::cleanPath(absoluteFilePath + "/..") }; + QDir persistFileDirectory { QDir::cleanPath(persistAbsoluteFilePath + "/..") }; if (!persistFileDirectory.exists()) { qDebug() << "Creating data directory " << persistFileDirectory.absolutePath(); @@ -1212,16 +1218,46 @@ void OctreeServer::domainSettingsRequestComplete() { } if (shouldCopy) { - qDebug() << "Old persist file found, copying from " << pathToCopyFrom << " to " << absoluteFilePath; + qDebug() << "Old persist file found, copying from " << pathToCopyFrom << " to " << persistAbsoluteFilePath; - QFile::copy(pathToCopyFrom, absoluteFilePath); + QFile::copy(pathToCopyFrom, persistAbsoluteFilePath); } else { qDebug() << "No existing persist file found"; } } + + auto persistFileDirectory = QFileInfo(persistAbsoluteFilePath).absolutePath(); + if (_backupDirectoryPath.isEmpty()) { + // Use the persist file's directory to store backups + _backupDirectoryPath = persistFileDirectory; + } else { + // The backup directory has been set. + // If relative, make it relative to the entities directory in the application data directory + // If absolute, no resolution is necessary + QDir backupDirectory { _backupDirectoryPath }; + QString absoluteBackupDirectory; + if (backupDirectory.isRelative()) { + absoluteBackupDirectory = QDir(ServerPathUtils::getDataFilePath("entities/")).absoluteFilePath(_backupDirectoryPath); + absoluteBackupDirectory = QDir(absoluteBackupDirectory).absolutePath(); + } else { + absoluteBackupDirectory = backupDirectory.absolutePath(); + } + backupDirectory = QDir(absoluteBackupDirectory); + if (!backupDirectory.exists()) { + if (backupDirectory.mkpath(".")) { + qDebug() << "Created backup directory"; + } else { + qDebug() << "ERROR creating backup directory, using persist file directory"; + _backupDirectoryPath = persistFileDirectory; + } + } else { + _backupDirectoryPath = absoluteBackupDirectory; + } + } + qDebug() << "Backups will be stored in: " << _backupDirectoryPath; // now set up PersistThread - _persistThread = new OctreePersistThread(_tree, absoluteFilePath, _persistInterval, + _persistThread = new OctreePersistThread(_tree, persistAbsoluteFilePath, _backupDirectoryPath, _persistInterval, _wantBackup, _settings, _debugTimestampNow, _persistAsFileType); _persistThread->initialize(true); } diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index d153f31154..35436997a6 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -172,6 +172,7 @@ protected: QString _persistFilePath; QString _persistAsFileType; + QString _backupDirectoryPath; int _packetsPerClientPerInterval; int _packetsTotalPerInterval; OctreePointer _tree; // this IS a reaveraging tree diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index c888fa301b..c9d7ea77d5 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -1108,6 +1108,14 @@ "default": "models.json.gz", "advanced": true }, + { + "name": "backupDirectoryPath", + "label": "Entities Backup Directory Path", + "help": "The path to the directory to store backups in.
If this path is relative it will be relative to the application data directory.", + "placeholder": "", + "default": "", + "advanced": true + }, { "name": "persistInterval", "label": "Save Check Interval", diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index d48c35d542..7034790eaf 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -34,11 +34,12 @@ const int OctreePersistThread::DEFAULT_PERSIST_INTERVAL = 1000 * 30; // every 30 seconds -OctreePersistThread::OctreePersistThread(OctreePointer tree, const QString& filename, int persistInterval, +OctreePersistThread::OctreePersistThread(OctreePointer tree, const QString& filename, const QString& backupDirectory, int persistInterval, bool wantBackup, const QJsonObject& settings, bool debugTimestampNow, QString persistAsFileType) : _tree(tree), _filename(filename), + _backupDirectory(backupDirectory), _persistInterval(persistInterval), _initialLoadComplete(false), _loadTimeUSecs(0), @@ -316,7 +317,7 @@ bool OctreePersistThread::getMostRecentBackup(const QString& format, // Based on our backup file name, determine the path and file name pattern for backup files QFileInfo persistFileInfo(_filename); - QString path = persistFileInfo.path(); + QString path = _backupDirectory; QString fileNamePart = persistFileInfo.fileName(); QStringList filters; @@ -369,10 +370,12 @@ void OctreePersistThread::rollOldBackupVersions(const BackupRule& rule) { if (rule.maxBackupVersions > 0) { qCDebug(octree) << "Rolling old backup versions for rule" << rule.name << "..."; + QString backupFileName = _backupDirectory + "/" + QUrl(_filename).fileName(); + // Delete maximum rolling file because rename() fails on Windows if target exists QString backupMaxExtensionN = rule.extensionFormat; backupMaxExtensionN.replace(QString("%N"), QString::number(rule.maxBackupVersions)); - QString backupMaxFilenameN = _filename + backupMaxExtensionN; + QString backupMaxFilenameN = backupFileName + backupMaxExtensionN; QFile backupMaxFileN(backupMaxFilenameN); if (backupMaxFileN.exists()) { int result = remove(qPrintable(backupMaxFilenameN)); @@ -387,8 +390,8 @@ void OctreePersistThread::rollOldBackupVersions(const BackupRule& rule) { backupExtensionN.replace(QString("%N"), QString::number(n)); backupExtensionNplusOne.replace(QString("%N"), QString::number(n+1)); - QString backupFilenameN = findMostRecentFileExtension(_filename, PERSIST_EXTENSIONS) + backupExtensionN; - QString backupFilenameNplusOne = _filename + backupExtensionNplusOne; + QString backupFilenameN = findMostRecentFileExtension(backupFileName, PERSIST_EXTENSIONS) + backupExtensionN; + QString backupFilenameNplusOne = backupFileName + backupExtensionNplusOne; QFile backupFileN(backupFilenameN); @@ -434,21 +437,20 @@ void OctreePersistThread::backup() { struct tm* localTime = localtime(&_lastPersistTime); - QString backupFileName; + QString backupFileName = _backupDirectory + "/" + QUrl(_filename).fileName(); // check to see if they asked for version rolling format if (rule.extensionFormat.contains("%N")) { rollOldBackupVersions(rule); // rename all the old backup files accordingly QString backupExtension = rule.extensionFormat; backupExtension.replace(QString("%N"), QString("1")); - backupFileName = _filename + backupExtension; + backupFileName += backupExtension; } else { char backupExtension[256]; strftime(backupExtension, sizeof(backupExtension), qPrintable(rule.extensionFormat), localTime); - backupFileName = _filename + backupExtension; + backupFileName += backupExtension; } - if (rule.maxBackupVersions > 0) { QFile persistFile(_filename); if (persistFile.exists()) { diff --git a/libraries/octree/src/OctreePersistThread.h b/libraries/octree/src/OctreePersistThread.h index 061a7a0e15..2a939216c4 100644 --- a/libraries/octree/src/OctreePersistThread.h +++ b/libraries/octree/src/OctreePersistThread.h @@ -33,9 +33,9 @@ public: static const int DEFAULT_PERSIST_INTERVAL; - OctreePersistThread(OctreePointer tree, const QString& filename, int persistInterval = DEFAULT_PERSIST_INTERVAL, - bool wantBackup = false, const QJsonObject& settings = QJsonObject(), - bool debugTimestampNow = false, QString persistAsFileType="svo"); + OctreePersistThread(OctreePointer tree, const QString& filename, const QString& backupDirectory, + int persistInterval = DEFAULT_PERSIST_INTERVAL, bool wantBackup = false, + const QJsonObject& settings = QJsonObject(), bool debugTimestampNow = false, QString persistAsFileType="svo"); bool isInitialLoadComplete() const { return _initialLoadComplete; } quint64 getLoadElapsedTime() const { return _loadTimeUSecs; } @@ -64,6 +64,7 @@ protected: private: OctreePointer _tree; QString _filename; + QString _backupDirectory; int _persistInterval; bool _initialLoadComplete; From fbe971e730b71343dbe254a547f129b9c6d90910 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 16 Aug 2016 17:46:21 -0700 Subject: [PATCH 20/32] Fix hand_pose_changed event --- interface/src/Application.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a6484c6c9c..e352b841b7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1216,8 +1216,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : // controller::Pose considers two poses to be different if either are invalid. In our case, we actually // want to consider the pose to be unchanged if it was invalid and still is invalid, so we check that first. properties["hand_pose_changed"] = - (!(leftHandPose.valid || lastLeftHandPose.valid) && (leftHandPose != lastLeftHandPose)) - || (!(rightHandPose.valid || lastRightHandPose.valid) && (rightHandPose != lastRightHandPose)); + ((leftHandPose.valid || lastLeftHandPose.valid) && (leftHandPose != lastLeftHandPose)) + || ((rightHandPose.valid || lastRightHandPose.valid) && (rightHandPose != lastRightHandPose)); lastLeftHandPose = leftHandPose; lastRightHandPose = rightHandPose; From 06787029b75abf97e5677dd5908a34de8ea66168 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 16 Aug 2016 17:58:35 -0700 Subject: [PATCH 21/32] small --- scripts/system/edit.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index e1360e2398..5139425b85 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1128,13 +1128,16 @@ function handeMenuEvent(menuItem) { } tooltip.show(false); } - function getPositionToCreateEntity() { var HALF_TREE_SCALE = 16384; var direction = Quat.getFront(MyAvatar.orientation); var distance = 1; var position = Vec3.sum(MyAvatar.position, Vec3.multiply(direction, distance)); - position.y +=0.5; + + if (Camera.mode === "entity" || Camera.mode === "independent") { + position = Vec3.sum(Camera.position, Vec3.multiply(Quat.getFront(Camera.orientation), distance)) + } + position.y += 0.5; if (position.x > HALF_TREE_SCALE || position.y > HALF_TREE_SCALE || position.z > HALF_TREE_SCALE) { return null } @@ -1145,15 +1148,21 @@ function getPositionToImportEntity() { var dimensions = Clipboard.getContentsDimensions(); var HALF_TREE_SCALE = 16384; var direction = Quat.getFront(MyAvatar.orientation); - var distance = 1; + var distance = 1.5; if (dimensions.x > distance) { - distance = dimensions.x + distance = dimensions.x / 2 } if (dimensions.z > distance) { - distance = dimensions.z + distance = dimensions.z / 2 } var position = Vec3.sum(MyAvatar.position, Vec3.multiply(direction, distance)); + print('distance is:: ' + distance); + + if (Camera.mode === "entity" || Camera.mode === "independent") { + position = Vec3.sum(Camera.position, Vec3.multiply(Quat.getFront(Camera.orientation), distance)) + } + if (position.x > HALF_TREE_SCALE || position.y > HALF_TREE_SCALE || position.z > HALF_TREE_SCALE) { return null } From e9c2a1d509671769247949e83f3d72d23ed25614 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 16 Aug 2016 18:03:34 -0700 Subject: [PATCH 22/32] cleanup prints --- scripts/system/edit.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 5139425b85..3b623e6271 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1157,8 +1157,6 @@ function getPositionToImportEntity() { } var position = Vec3.sum(MyAvatar.position, Vec3.multiply(direction, distance)); - print('distance is:: ' + distance); - if (Camera.mode === "entity" || Camera.mode === "independent") { position = Vec3.sum(Camera.position, Vec3.multiply(Quat.getFront(Camera.orientation), distance)) } From 0810ad0e7b0f66bb7cf53d9131cfb068fd5ff169 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 16 Aug 2016 18:13:42 -0700 Subject: [PATCH 23/32] use square of sides --- scripts/system/edit.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 3b623e6271..a3e5476bf9 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1148,17 +1148,12 @@ function getPositionToImportEntity() { var dimensions = Clipboard.getContentsDimensions(); var HALF_TREE_SCALE = 16384; var direction = Quat.getFront(MyAvatar.orientation); - var distance = 1.5; - if (dimensions.x > distance) { - distance = dimensions.x / 2 - } - if (dimensions.z > distance) { - distance = dimensions.z / 2 - } - var position = Vec3.sum(MyAvatar.position, Vec3.multiply(direction, distance)); + var longest = 1; + longest = Math.sqrt(Math.pow(dimensions.x, 2) + Math.pow(dimensions.z, 2)); + var position = Vec3.sum(MyAvatar.position, Vec3.multiply(direction, longest)); if (Camera.mode === "entity" || Camera.mode === "independent") { - position = Vec3.sum(Camera.position, Vec3.multiply(Quat.getFront(Camera.orientation), distance)) + position = Vec3.sum(Camera.position, Vec3.multiply(Quat.getFront(Camera.orientation), longest)) } if (position.x > HALF_TREE_SCALE || position.y > HALF_TREE_SCALE || position.z > HALF_TREE_SCALE) { From 0e259dcd299ae06ff249f4337a97a473e6ee310d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 17 Aug 2016 09:29:45 -0700 Subject: [PATCH 24/32] Add open log dir button to server-console --- server-console/src/log.html | 1 + server-console/src/log.js | 2 ++ server-console/src/main.js | 5 +++++ 3 files changed, 8 insertions(+) diff --git a/server-console/src/log.html b/server-console/src/log.html index f704f3e35f..3ccf8112e8 100644 --- a/server-console/src/log.html +++ b/server-console/src/log.html @@ -8,6 +8,7 @@
    diff --git a/server-console/src/log.js b/server-console/src/log.js index 3634eaeaa7..c739f210b7 100644 --- a/server-console/src/log.js +++ b/server-console/src/log.js @@ -218,6 +218,8 @@ ready = function() { appendLogMessages('ac'); } + $('#view-logs').on('click', remote.openLogDirectory); + // handle filtering of table rows on input change $('#search-input').on('input', function() { filter = $(this).val().toLowerCase(); diff --git a/server-console/src/main.js b/server-console/src/main.js index 8f85872d0b..c47308aed6 100644 --- a/server-console/src/main.js +++ b/server-console/src/main.js @@ -285,6 +285,10 @@ function openFileBrowser(path) { } } +function openLogDirectory() { + openFileBrowser(logPath); +} + // NOTE: this looks like it does nothing, but it's very important. // Without it the default behaviour is to quit the app once all windows closed // which is absolutely not what we want for a taskbar application. @@ -309,6 +313,7 @@ global.homeServer = null; global.domainServer = null; global.acMonitor = null; global.userConfig = userConfig; +global.openLogDirectory = openLogDirectory; var LogWindow = function(ac, ds) { this.ac = ac; From 8ba105d1e418973f3e93f25e8c564343929b5563 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 17 Aug 2016 09:36:42 -0700 Subject: [PATCH 25/32] Fix open-log-dir button handler --- server-console/src/log.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/server-console/src/log.js b/server-console/src/log.js index c739f210b7..455b6828d8 100644 --- a/server-console/src/log.js +++ b/server-console/src/log.js @@ -43,6 +43,7 @@ ready = function() { var domainServer = remote.getGlobal('domainServer'); var acMonitor = remote.getGlobal('acMonitor'); + var openLogDirectory = remote.getGlobal('openLogDirectory'); var pendingLines = { 'ds': new Array(), @@ -218,7 +219,11 @@ ready = function() { appendLogMessages('ac'); } - $('#view-logs').on('click', remote.openLogDirectory); + // Binding a remote function directly does not work, so bind to a function + // that calls the remote function. + $('#view-logs').on('click', function() { + openLogDirectory(); + }); // handle filtering of table rows on input change $('#search-input').on('input', function() { From 9fa4a20e5501f8a44bb72179e62accfc447e28bf Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 18 Aug 2016 09:37:26 +1200 Subject: [PATCH 26/32] Fix Asset Browser dialog --- interface/resources/qml/LoginDialog/SignInBody.qml | 2 +- interface/resources/qml/LoginDialog/UsernameCollisionBody.qml | 2 +- interface/resources/qml/LoginDialog/WelcomeBody.qml | 2 +- .../resources/qml/styles-uit/{MenuItem.qml => InfoItem.qml} | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename interface/resources/qml/styles-uit/{MenuItem.qml => InfoItem.qml} (95%) diff --git a/interface/resources/qml/LoginDialog/SignInBody.qml b/interface/resources/qml/LoginDialog/SignInBody.qml index 2da0ea856d..7bbba683c3 100644 --- a/interface/resources/qml/LoginDialog/SignInBody.qml +++ b/interface/resources/qml/LoginDialog/SignInBody.qml @@ -48,7 +48,7 @@ Item { } } - MenuItem { + InfoItem { id: mainTextContainer anchors { top: parent.top diff --git a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml index 7e22b11f8b..b949c660d6 100644 --- a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml +++ b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml @@ -78,7 +78,7 @@ Item { placeholderText: "Choose your own" } - MenuItem { + InfoItem { id: termsContainer anchors { top: textField.bottom diff --git a/interface/resources/qml/LoginDialog/WelcomeBody.qml b/interface/resources/qml/LoginDialog/WelcomeBody.qml index ecc848cdc0..5fed9addf8 100644 --- a/interface/resources/qml/LoginDialog/WelcomeBody.qml +++ b/interface/resources/qml/LoginDialog/WelcomeBody.qml @@ -44,7 +44,7 @@ Item { } } - MenuItem { + InfoItem { id: mainTextContainer anchors { top: parent.top diff --git a/interface/resources/qml/styles-uit/MenuItem.qml b/interface/resources/qml/styles-uit/InfoItem.qml similarity index 95% rename from interface/resources/qml/styles-uit/MenuItem.qml rename to interface/resources/qml/styles-uit/InfoItem.qml index 4431c357bf..83781a4ef5 100644 --- a/interface/resources/qml/styles-uit/MenuItem.qml +++ b/interface/resources/qml/styles-uit/InfoItem.qml @@ -1,5 +1,5 @@ // -// MenuItem.qml +// InfoItem.qml // // Created by Clement on 7/18/16 // Copyright 2016 High Fidelity, Inc. From a32ab77b7dad3a9eaac11571584a7c3940835af2 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 17 Aug 2016 15:22:30 -0700 Subject: [PATCH 27/32] Address issues with random camera locations caused by bad HMD sensor poses --- interface/src/avatar/MyAvatar.cpp | 12 +++- plugins/openvr/src/OpenVrDisplayPlugin.cpp | 74 +++++++++++++--------- plugins/openvr/src/OpenVrHelpers.h | 7 ++ 3 files changed, 62 insertions(+), 31 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 57e379a9ac..782ecbcc64 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -516,13 +516,23 @@ glm::mat4 MyAvatar::getSensorToWorldMatrix() const { return _sensorToWorldMatrixCache.get(); } +// As far as I know no HMD system supports a play area of a kilometer in radius. +static const float MAX_HMD_ORIGIN_DISTANCE = 1000.0f; // Pass a recent sample of the HMD to the avatar. // This can also update the avatar's position to follow the HMD // as it moves through the world. void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { // update the sensorMatrices based on the new hmd pose _hmdSensorMatrix = hmdSensorMatrix; - _hmdSensorPosition = extractTranslation(hmdSensorMatrix); + auto newHmdSensorPosition = extractTranslation(hmdSensorMatrix); + + if (newHmdSensorPosition != _hmdSensorPosition && + glm::length(newHmdSensorPosition) > MAX_HMD_ORIGIN_DISTANCE) { + qWarning() << "Invalid HMD sensor position " << newHmdSensorPosition; + // Ignore unreasonable HMD sensor data + return; + } + _hmdSensorPosition = newHmdSensorPosition; _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); _hmdSensorFacing = getFacingDir2D(_hmdSensorOrientation); } diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index b5f360ad8d..e751427ce2 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -108,19 +108,20 @@ public: } void updateSource() { - Lock lock(_plugin._presentMutex); - while (!_queue.empty()) { - auto& front = _queue.front(); - auto result = glClientWaitSync(front.fence, 0, 0); - if (GL_TIMEOUT_EXPIRED == result && GL_WAIT_FAILED == result) { - break; - } + _plugin.withNonPresentThreadLock([&] { + while (!_queue.empty()) { + auto& front = _queue.front(); + auto result = glClientWaitSync(front.fence, 0, 0); + if (GL_TIMEOUT_EXPIRED == result && GL_WAIT_FAILED == result) { + break; + } - glDeleteSync(front.fence); - front.fence = 0; - _current = front; - _queue.pop(); - } + glDeleteSync(front.fence); + front.fence = 0; + _current = front; + _queue.pop(); + } + }); } void run() override { @@ -170,15 +171,28 @@ public: PoseData nextRender, nextSim; nextRender.frameIndex = _plugin.presentCount(); vr::VRCompositor()->WaitGetPoses(nextRender.vrPoses, vr::k_unMaxTrackedDeviceCount, nextSim.vrPoses, vr::k_unMaxTrackedDeviceCount); - { - Lock lock(_plugin._presentMutex); - _presentCount++; - _presented.notify_one(); - _nextRender = nextRender; - _nextRender.update(_plugin._sensorResetMat); - _nextSim = nextSim; - _nextSim.update(_plugin._sensorResetMat); + + // Copy invalid poses in nextSim from nextRender + for (uint32_t i = 0; i < vr::k_unMaxTrackedDeviceCount; ++i) { + if (!nextSim.vrPoses[i].bPoseIsValid) { + nextSim.vrPoses[i] = nextRender.vrPoses[i]; + } } + + mat4 sensorResetMat; + _plugin.withNonPresentThreadLock([&] { + sensorResetMat = _plugin._sensorResetMat; + }); + + nextRender.update(sensorResetMat); + nextSim.update(sensorResetMat); + + _plugin.withNonPresentThreadLock([&] { + _nextRender = nextRender; + _nextSim = nextSim; + ++_presentCount; + _presented.notify_one(); + }); } _canvas.doneCurrent(); } @@ -366,19 +380,20 @@ bool OpenVrDisplayPlugin::beginFrameRender(uint32_t frameIndex) { } _currentRenderFrameInfo = FrameInfo(); + PoseData nextSimPoseData; withNonPresentThreadLock([&] { - _currentRenderFrameInfo.renderPose = _nextSimPoseData.poses[vr::k_unTrackedDeviceIndex_Hmd]; + nextSimPoseData = _nextSimPoseData; }); // HACK: when interface is launched and steam vr is NOT running, openvr will return bad HMD poses for a few frames // To workaround this, filter out any hmd poses that are obviously bad, i.e. beneath the floor. - if (isBadPose(&_nextSimPoseData.vrPoses[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking)) { + if (isBadPose(&nextSimPoseData.vrPoses[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking)) { qDebug() << "WARNING: ignoring bad hmd pose from openvr"; // use the last known good HMD pose - _nextSimPoseData.vrPoses[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking = _lastGoodHMDPose; + nextSimPoseData.vrPoses[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking = _lastGoodHMDPose; } else { - _lastGoodHMDPose = _nextSimPoseData.vrPoses[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking; + _lastGoodHMDPose = nextSimPoseData.vrPoses[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking; } vr::TrackedDeviceIndex_t handIndices[2] { vr::k_unTrackedDeviceIndexInvalid, vr::k_unTrackedDeviceIndexInvalid }; @@ -387,7 +402,7 @@ bool OpenVrDisplayPlugin::beginFrameRender(uint32_t frameIndex) { auto trackedCount = _system->GetSortedTrackedDeviceIndicesOfClass(vr::TrackedDeviceClass_Controller, controllerIndices, 2); // Find the left and right hand controllers, if they exist for (uint32_t i = 0; i < std::min(trackedCount, 2); ++i) { - if (_nextSimPoseData.vrPoses[i].bPoseIsValid) { + if (nextSimPoseData.vrPoses[i].bPoseIsValid) { auto role = _system->GetControllerRoleForTrackedDeviceIndex(controllerIndices[i]); if (vr::TrackedControllerRole_LeftHand == role) { handIndices[0] = controllerIndices[i]; @@ -398,8 +413,7 @@ bool OpenVrDisplayPlugin::beginFrameRender(uint32_t frameIndex) { } } - _currentRenderFrameInfo.renderPose = _nextSimPoseData.poses[vr::k_unTrackedDeviceIndex_Hmd]; - + _currentRenderFrameInfo.renderPose = nextSimPoseData.poses[vr::k_unTrackedDeviceIndex_Hmd]; bool keyboardVisible = isOpenVrKeyboardShown(); std::array handPoses; @@ -409,9 +423,9 @@ bool OpenVrDisplayPlugin::beginFrameRender(uint32_t frameIndex) { continue; } auto deviceIndex = handIndices[i]; - const mat4& mat = _nextSimPoseData.poses[deviceIndex]; - const vec3& linearVelocity = _nextSimPoseData.linearVelocities[deviceIndex]; - const vec3& angularVelocity = _nextSimPoseData.angularVelocities[deviceIndex]; + const mat4& mat = nextSimPoseData.poses[deviceIndex]; + const vec3& linearVelocity = nextSimPoseData.linearVelocities[deviceIndex]; + const vec3& angularVelocity = nextSimPoseData.angularVelocities[deviceIndex]; auto correctedPose = openVrControllerPoseToHandPose(i == 0, mat, linearVelocity, angularVelocity); static const glm::quat HAND_TO_LASER_ROTATION = glm::rotation(Vectors::UNIT_Z, Vectors::UNIT_NEG_Y); handPoses[i] = glm::translate(glm::mat4(), correctedPose.translation) * glm::mat4_cast(correctedPose.rotation * HAND_TO_LASER_ROTATION); diff --git a/plugins/openvr/src/OpenVrHelpers.h b/plugins/openvr/src/OpenVrHelpers.h index 368b14cb1a..4279e6a6ac 100644 --- a/plugins/openvr/src/OpenVrHelpers.h +++ b/plugins/openvr/src/OpenVrHelpers.h @@ -66,8 +66,15 @@ struct PoseData { vec3 linearVelocities[vr::k_unMaxTrackedDeviceCount]; vec3 angularVelocities[vr::k_unMaxTrackedDeviceCount]; + PoseData() { + memset(vrPoses, 0, sizeof(vr::TrackedDevicePose_t) * vr::k_unMaxTrackedDeviceCount); + } + void update(const glm::mat4& resetMat) { for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) { + if (!vrPoses[i].bPoseIsValid) { + continue; + } poses[i] = resetMat * toGlm(vrPoses[i].mDeviceToAbsoluteTracking); linearVelocities[i] = transformVectorFast(resetMat, toGlm(vrPoses[i].vVelocity)); angularVelocities[i] = transformVectorFast(resetMat, toGlm(vrPoses[i].vAngularVelocity)); From 25b9d756ca8965b1a0162f8edb92e41d0ac30955 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 17 Aug 2016 16:54:04 -0700 Subject: [PATCH 28/32] Update entity edit tracking to track count rather than bool --- interface/src/Application.cpp | 6 +++--- .../entities/src/EntityScriptingInterface.cpp | 14 +++++++------- libraries/entities/src/EntityScriptingInterface.h | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e352b841b7..0876869554 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1203,9 +1203,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : auto entityScriptingInterface = DependencyManager::get(); auto entityActivityTracking = entityScriptingInterface->getActivityTracking(); entityScriptingInterface->resetActivityTracking(); - properties["added_entity"] = entityActivityTracking.hasAddedEntity; - properties["deleted_entity"] = entityActivityTracking.hasDeletedEntity; - properties["edited_entity"] = entityActivityTracking.hasEditedEntity; + properties["added_entity_cnt"] = entityActivityTracking.addedEntityCount; + properties["deleted_entity_cnt"] = entityActivityTracking.deletedEntityCount; + properties["edited_entity_cnt"] = entityActivityTracking.editedEntityCount; auto hmdHeadPose = getHMDSensorPose(); properties["hmd_head_pose_changed"] = isHMDMode() && (hmdHeadPose != lastHMDHeadPose); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 031847b3f3..c3dbd47600 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -41,9 +41,9 @@ void EntityScriptingInterface::queueEntityMessage(PacketType packetType, } void EntityScriptingInterface::resetActivityTracking() { - _activityTracking.hasAddedEntity = false; - _activityTracking.hasDeletedEntity = false; - _activityTracking.hasEditedEntity = false; + _activityTracking.addedEntityCount = 0; + _activityTracking.deletedEntityCount = 0; + _activityTracking.editedEntityCount = 0; } bool EntityScriptingInterface::canAdjustLocks() { @@ -136,7 +136,7 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties, bool clientOnly) { - _activityTracking.hasAddedEntity = true; + _activityTracking.addedEntityCount++; EntityItemProperties propertiesWithSimID = convertLocationFromScriptSemantics(properties); propertiesWithSimID.setDimensionsInitialized(properties.dimensionsChanged()); @@ -208,7 +208,7 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties QUuid EntityScriptingInterface::addModelEntity(const QString& name, const QString& modelUrl, const QString& shapeType, bool dynamic, const glm::vec3& position, const glm::vec3& gravity) { - _activityTracking.hasAddedEntity = true; + _activityTracking.addedEntityCount++; EntityItemProperties properties; properties.setType(EntityTypes::Model); @@ -273,7 +273,7 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit } QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& scriptSideProperties) { - _activityTracking.hasEditedEntity = true; + _activityTracking.editedEntityCount++; EntityItemProperties properties = scriptSideProperties; @@ -418,7 +418,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& } void EntityScriptingInterface::deleteEntity(QUuid id) { - _activityTracking.hasDeletedEntity = true; + _activityTracking.deletedEntity++; EntityItemID entityID(id); bool shouldDelete = true; diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index bde0974d7c..ce5b332b2a 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -67,9 +67,9 @@ public: class ActivityTracking { public: - bool hasAddedEntity { false }; - bool hasDeletedEntity { false }; - bool hasEditedEntity { false }; + int addedEntityCount { 0 }; + int deletedEntityCount { 0 }; + int editedEntityCount { 0 }; }; EntityEditPacketSender* getEntityPacketSender() const { return (EntityEditPacketSender*)getPacketSender(); } From d46af500c195eb27b36e76174a989f10aa58f788 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 17 Aug 2016 17:00:56 -0700 Subject: [PATCH 29/32] Fix wrong property name in entity activity tracking --- libraries/entities/src/EntityScriptingInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index c3dbd47600..2bff2a99de 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -418,7 +418,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& } void EntityScriptingInterface::deleteEntity(QUuid id) { - _activityTracking.deletedEntity++; + _activityTracking.deletedEntityCount++; EntityItemID entityID(id); bool shouldDelete = true; From 2ff35768aa9ecfb9743ed35fd63939c8023befd1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 17 Aug 2016 18:45:09 -0700 Subject: [PATCH 30/32] make 3d-line overlays work again --- interface/src/ui/overlays/Line3DOverlay.cpp | 51 +++++++++++++++++++-- interface/src/ui/overlays/Line3DOverlay.h | 11 +++-- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index 6b46b5b884..a50681cdb2 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -23,6 +23,7 @@ Line3DOverlay::Line3DOverlay() : Line3DOverlay::Line3DOverlay(const Line3DOverlay* line3DOverlay) : Base3DOverlay(line3DOverlay), + _start(line3DOverlay->_start), _end(line3DOverlay->_end), _geometryCacheID(DependencyManager::get()->allocateID()) { @@ -31,6 +32,40 @@ Line3DOverlay::Line3DOverlay(const Line3DOverlay* line3DOverlay) : Line3DOverlay::~Line3DOverlay() { } +const glm::vec3& Line3DOverlay::getStart() const { + bool success; + glm::vec3 worldStart = localToWorld(_start, _parentID, _parentJointIndex, success); + if (!success) { + qDebug() << "Line3DOverlay::getStart failed"; + } + return worldStart; +} + +const glm::vec3& Line3DOverlay::getEnd() const { + bool success; + glm::vec3 worldEnd = localToWorld(_end, _parentID, _parentJointIndex, success); + if (!success) { + qDebug() << "Line3DOverlay::getEnd failed"; + } + return worldEnd; +} + +void Line3DOverlay::setStart(const glm::vec3& start) { + bool success; + _start = worldToLocal(start, _parentID, _parentJointIndex, success); + if (!success) { + qDebug() << "Line3DOverlay::setStart failed"; + } +} + +void Line3DOverlay::setEnd(const glm::vec3& end) { + bool success; + _end = worldToLocal(end, _parentID, _parentJointIndex, success); + if (!success) { + qDebug() << "Line3DOverlay::setEnd failed"; + } +} + AABox Line3DOverlay::getBounds() const { auto extents = Extents{}; extents.addPoint(_start); @@ -76,8 +111,8 @@ const render::ShapeKey Line3DOverlay::getShapeKey() { return builder.build(); } -void Line3DOverlay::setProperties(const QVariantMap& properties) { - Base3DOverlay::setProperties(properties); +void Line3DOverlay::setProperties(const QVariantMap& originalProperties) { + QVariantMap properties = originalProperties; auto start = properties["start"]; // if "start" property was not there, check to see if they included aliases: startPoint @@ -87,6 +122,7 @@ void Line3DOverlay::setProperties(const QVariantMap& properties) { if (start.isValid()) { setStart(vec3FromVariant(start)); } + properties.remove("start"); // so that Base3DOverlay doesn't respond to it auto end = properties["end"]; // if "end" property was not there, check to see if they included aliases: endPoint @@ -109,14 +145,16 @@ void Line3DOverlay::setProperties(const QVariantMap& properties) { if (glowWidth.isValid()) { setGlow(glowWidth.toFloat()); } + + Base3DOverlay::setProperties(properties); } QVariant Line3DOverlay::getProperty(const QString& property) { if (property == "start" || property == "startPoint" || property == "p1") { - return vec3toVariant(_start); + return vec3toVariant(getStart()); } if (property == "end" || property == "endPoint" || property == "p2") { - return vec3toVariant(_end); + return vec3toVariant(getEnd()); } return Base3DOverlay::getProperty(property); @@ -125,3 +163,8 @@ QVariant Line3DOverlay::getProperty(const QString& property) { Line3DOverlay* Line3DOverlay::createClone() const { return new Line3DOverlay(this); } + + +void Line3DOverlay::locationChanged(bool tellPhysics) { + // do nothing +} diff --git a/interface/src/ui/overlays/Line3DOverlay.h b/interface/src/ui/overlays/Line3DOverlay.h index d066677c70..2138ddc5da 100644 --- a/interface/src/ui/overlays/Line3DOverlay.h +++ b/interface/src/ui/overlays/Line3DOverlay.h @@ -28,14 +28,15 @@ public: virtual AABox getBounds() const override; // getters - const glm::vec3& getStart() const { return _start; } - const glm::vec3& getEnd() const { return _end; } + const glm::vec3& getStart() const; + const glm::vec3& getEnd() const; const float& getGlow() const { return _glow; } const float& getGlowWidth() const { return _glowWidth; } // setters - void setStart(const glm::vec3& start) { _start = start; } - void setEnd(const glm::vec3& end) { _end = end; } + void setStart(const glm::vec3& start); + void setEnd(const glm::vec3& end); + void setGlow(const float& glow) { _glow = glow; } void setGlowWidth(const float& glowWidth) { _glowWidth = glowWidth; } @@ -44,6 +45,8 @@ public: virtual Line3DOverlay* createClone() const override; + virtual void locationChanged(bool tellPhysics = true) override; + protected: glm::vec3 _start; glm::vec3 _end; From 8487f825a0ff1c924befa4f6a8cf0fd99ce3edff Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 18 Aug 2016 08:01:42 -0700 Subject: [PATCH 31/32] don't return reference to local variables --- interface/src/ui/overlays/Line3DOverlay.cpp | 4 ++-- interface/src/ui/overlays/Line3DOverlay.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index a50681cdb2..c3a6c5920e 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -32,7 +32,7 @@ Line3DOverlay::Line3DOverlay(const Line3DOverlay* line3DOverlay) : Line3DOverlay::~Line3DOverlay() { } -const glm::vec3& Line3DOverlay::getStart() const { +glm::vec3 Line3DOverlay::getStart() const { bool success; glm::vec3 worldStart = localToWorld(_start, _parentID, _parentJointIndex, success); if (!success) { @@ -41,7 +41,7 @@ const glm::vec3& Line3DOverlay::getStart() const { return worldStart; } -const glm::vec3& Line3DOverlay::getEnd() const { +glm::vec3 Line3DOverlay::getEnd() const { bool success; glm::vec3 worldEnd = localToWorld(_end, _parentID, _parentJointIndex, success); if (!success) { diff --git a/interface/src/ui/overlays/Line3DOverlay.h b/interface/src/ui/overlays/Line3DOverlay.h index 2138ddc5da..b4e2ba8168 100644 --- a/interface/src/ui/overlays/Line3DOverlay.h +++ b/interface/src/ui/overlays/Line3DOverlay.h @@ -28,8 +28,8 @@ public: virtual AABox getBounds() const override; // getters - const glm::vec3& getStart() const; - const glm::vec3& getEnd() const; + glm::vec3 getStart() const; + glm::vec3 getEnd() const; const float& getGlow() const { return _glow; } const float& getGlowWidth() const { return _glowWidth; } From 813fefd59901ff07b0e010c98111357a71efaba8 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 18 Aug 2016 11:26:25 -0700 Subject: [PATCH 32/32] reimplement buffer get for (c)end --- libraries/gpu/src/gpu/Buffer.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libraries/gpu/src/gpu/Buffer.h b/libraries/gpu/src/gpu/Buffer.h index da1a987bee..8160f648fc 100644 --- a/libraries/gpu/src/gpu/Buffer.h +++ b/libraries/gpu/src/gpu/Buffer.h @@ -293,10 +293,18 @@ public: template Iterator end() { return Iterator(&edit(getNum()), _stride); } #else template Iterator begin() const { return Iterator(&get(), _stride); } - template Iterator end() const { return Iterator(&get(getNum()), _stride); } + template Iterator end() const { + // reimplement get without bounds checking + Resource::Size elementOffset = getNum() * _stride + _offset; + return Iterator((reinterpret_cast (_buffer->getData() + elementOffset)), _stride); + } #endif template Iterator cbegin() const { return Iterator(&get(), _stride); } - template Iterator cend() const { return Iterator(&get(getNum()), _stride); } + template Iterator cend() const { + // reimplement get without bounds checking + Resource::Size elementOffset = getNum() * _stride + _offset; + return Iterator((reinterpret_cast (_buffer->getData() + elementOffset)), _stride); + } // the number of elements of the specified type fitting in the view size template Index getNum() const {