From ab2fa16be3f2f600b36803d61d7752877e119546 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 21 Nov 2014 12:06:46 -0800 Subject: [PATCH 01/18] Update edit entities moveUp arrow position --- examples/libraries/entitySelectionTool.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index e760fb0463..b0fc68b60c 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -260,6 +260,7 @@ SelectionDisplay = (function () { var grabberColorFace = { red: 120, green: 120, blue: 120 }; var grabberLineWidth = 0.5; var grabberSolid = true; + var grabberMoveUpPosition = { x: 0, y: 0, z: 0 }; var grabberPropertiesCorner = { position: { x:0, y: 0, z: 0}, @@ -1093,7 +1094,8 @@ SelectionDisplay = (function () { Overlays.editOverlay(grabberEdgeFL, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeFL }); var grabberMoveUpOffset = 0.1; - Overlays.editOverlay(grabberMoveUp, { visible: activeTool == null || mode == "TRANSLATE_UP_DOWN", position: { x: position.x, y: position.y + worldTop + grabberMoveUpOffset, z: position.z } }); + grabberMoveUpPosition = { x: position.x, y: position.y + worldTop + grabberMoveUpOffset, z: position.z } + Overlays.editOverlay(grabberMoveUp, { visible: activeTool == null || mode == "TRANSLATE_UP_DOWN" }); }; that.setOverlaysVisible = function(isVisible) { @@ -2297,8 +2299,10 @@ SelectionDisplay = (function () { Overlays.editOverlay(rollHandle, { scale: handleSize, }); + var pos = Vec3.sum(grabberMoveUpPosition, { x: 0, y: Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 3, z: 0 }); Overlays.editOverlay(grabberMoveUp, { - scale: handleSize, + position: pos, + scale: handleSize / 2, }); } } From 08772bbae0fef5b79f49a03c5a7a996126d4f463 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 24 Nov 2014 13:07:22 -0800 Subject: [PATCH 02/18] remove spatial audio menu items --- interface/src/Audio.cpp | 6 ++-- interface/src/AudioReflector.cpp | 48 +++++++++++++++++------------ interface/src/Menu.cpp | 52 -------------------------------- interface/src/Menu.h | 12 -------- interface/src/ui/Stats.cpp | 43 +++++++++++++------------- 5 files changed, 55 insertions(+), 106 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 75b8c252f7..167c44111e 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -989,7 +989,8 @@ void Audio::processReceivedSamples(const QByteArray& inputBuffer, QByteArray& ou QByteArray buffer = inputBuffer; // Accumulate direct transmission of audio from sender to receiver - if (Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingIncludeOriginal)) { + bool includeOriginal = true; // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingIncludeOriginal) + if (includeOriginal) { emit preProcessOriginalInboundAudio(sampleTime, buffer, _desiredOutputFormat); addSpatialAudioToBuffer(sampleTime, buffer, numNetworkOutputSamples); } @@ -1264,7 +1265,8 @@ void Audio::selectAudioSourceSine440() { } void Audio::toggleAudioSpatialProcessing() { - _processSpatialAudio = !_processSpatialAudio; + // spatial audio disabled for now + _processSpatialAudio = false; //!_processSpatialAudio; if (_processSpatialAudio) { _spatialAudioStart = 0; _spatialAudioFinish = 0; diff --git a/interface/src/AudioReflector.cpp b/interface/src/AudioReflector.cpp index e18a0ad36e..8a23ecee79 100644 --- a/interface/src/AudioReflector.cpp +++ b/interface/src/AudioReflector.cpp @@ -66,10 +66,15 @@ AudioReflector::AudioReflector(QObject* parent) : } bool AudioReflector::haveAttributesChanged() { - bool withDiffusion = Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingWithDiffusions); - bool dontDistanceAttenuate = Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingDontDistanceAttenuate); - bool alternateDistanceAttenuate = Menu::getInstance()->isOptionChecked( - MenuOption::AudioSpatialProcessingAlternateDistanceAttenuate); + + // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingWithDiffusions); + bool withDiffusion = true; + + // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingDontDistanceAttenuate); + bool dontDistanceAttenuate = false; + + //Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingAlternateDistanceAttenuate); + bool alternateDistanceAttenuate = false; bool attributesChange = (_withDiffusion != withDiffusion || _lastPreDelay != _preDelay @@ -107,7 +112,8 @@ void AudioReflector::render() { calculateAllReflections(); // only render if we've been asked to do so - if (Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingRenderPaths)) { + bool renderPaths = false; // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingRenderPaths) + if (renderPaths) { drawRays(); } } @@ -116,7 +122,8 @@ void AudioReflector::render() { // = 3ms per meter float AudioReflector::getDelayFromDistance(float distance) { float delay = (_soundMsPerMeter * distance); - if (Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingPreDelay)) { + bool includePreDelay = true; // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingPreDelay) + if (includePreDelay) { delay += _preDelay; } return delay; @@ -126,12 +133,11 @@ float AudioReflector::getDelayFromDistance(float distance) { float AudioReflector::getDistanceAttenuationCoefficient(float distance) { - bool doDistanceAttenuation = !Menu::getInstance()->isOptionChecked( - MenuOption::AudioSpatialProcessingDontDistanceAttenuate); + //!Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingDontDistanceAttenuate); + bool doDistanceAttenuation = true; - bool originalFormula = !Menu::getInstance()->isOptionChecked( - MenuOption::AudioSpatialProcessingAlternateDistanceAttenuate); - + //!Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingAlternateDistanceAttenuate); + bool originalFormula = true; float distanceCoefficient = 1.0f; @@ -170,7 +176,8 @@ float AudioReflector::getDistanceAttenuationCoefficient(float distance) { } glm::vec3 AudioReflector::getFaceNormal(BoxFace face) { - bool wantSlightRandomness = Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingSlightlyRandomSurfaces); + // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingSlightlyRandomSurfaces); + bool wantSlightRandomness = true; glm::vec3 faceNormal; const float MIN_RANDOM_LENGTH = 0.99f; const float MAX_RANDOM_LENGTH = 1.0f; @@ -202,8 +209,8 @@ const int NUMBER_OF_CHANNELS = 2; void AudioReflector::injectAudiblePoint(AudioSource source, const AudiblePoint& audiblePoint, const QByteArray& samples, unsigned int sampleTime, int sampleRate) { - bool wantEarSeparation = Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingSeparateEars); - bool wantStereo = Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingStereoSource); + bool wantEarSeparation = true; // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingSeparateEars); + bool wantStereo = true; // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingStereoSource); glm::vec3 rightEarPosition = wantEarSeparation ? _myAvatar->getHead()->getRightEarPosition() : _myAvatar->getHead()->getPosition(); glm::vec3 leftEarPosition = wantEarSeparation ? _myAvatar->getHead()->getLeftEarPosition() : @@ -316,7 +323,8 @@ void AudioReflector::preProcessOriginalInboundAudio(unsigned int sampleTime, } void AudioReflector::processLocalAudio(unsigned int sampleTime, const QByteArray& samples, const QAudioFormat& format) { - if (Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingProcessLocalAudio)) { + bool processLocalAudio = true; // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingProcessLocalAudio) + if (processLocalAudio) { const int NUM_CHANNELS_INPUT = 1; const int NUM_CHANNELS_OUTPUT = 2; const int EXPECTED_SAMPLE_RATE = 24000; @@ -458,7 +466,7 @@ void AudioReflector::identifyAudioSources() { void AudioReflector::calculateAllReflections() { // only recalculate when we've moved, or if the attributes have changed // TODO: what about case where new voxels are added in front of us??? - bool wantHeadOrientation = Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingHeadOriented); + bool wantHeadOrientation = true; // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingHeadOriented); glm::quat orientation = wantHeadOrientation ? _myAvatar->getHead()->getFinalOrientationInWorldFrame() : _myAvatar->getOrientation(); glm::vec3 origin = _myAvatar->getHead()->getPosition(); glm::vec3 listenerPosition = _myAvatar->getHead()->getPosition(); @@ -505,7 +513,8 @@ void AudioReflector::drawRays() { } } - if (Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingProcessLocalAudio)) { + bool processLocalAudio = true; // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingProcessLocalAudio) + if (processLocalAudio) { // draw the paths for local audio foreach(AudioPath* const& path, _localAudioPaths) { // if this is an original reflection, draw it in RED @@ -575,7 +584,8 @@ void AudioReflector::analyzePaths() { float initialAttenuation = 1.0f; - float preDelay = Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingPreDelay) ? _preDelay : 0.0f; + bool wantPreDelay = true; // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingPreDelay) + float preDelay = wantPreDelay ? _preDelay : 0.0f; // NOTE: we're still calculating our initial paths based on the listeners position. But the analysis code has been // updated to support individual sound sources (which is how we support diffusion), we can use this new paradigm to @@ -701,7 +711,7 @@ void AudioReflector::handlePathPoint(AudioPath* path, float distance, OctreeElem float reflectiveAttenuation = currentReflectiveAttenuation * material.reflectiveRatio; float totalDiffusionAttenuation = currentReflectiveAttenuation * material.diffusionRatio; - bool wantDiffusions = Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingWithDiffusions); + bool wantDiffusions = true; // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingWithDiffusions); int fanout = wantDiffusions ? _diffusionFanout : 0; float partialDiffusionAttenuation = fanout < 1 ? 0.0f : totalDiffusionAttenuation / (float)fanout; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index db5cd5170d..baac3629ac 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -620,58 +620,6 @@ Menu::Menu() : audioScopeFramesGroup->addAction(fiftyFrames); } - QMenu* spatialAudioMenu = audioDebugMenu->addMenu("Spatial Audio"); - - addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessing, - Qt::CTRL | Qt::SHIFT | Qt::Key_M, - false, - appInstance->getAudio(), - SLOT(toggleAudioSpatialProcessing())); - - addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingIncludeOriginal, - Qt::CTRL | Qt::SHIFT | Qt::Key_O, - true); - - addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingSeparateEars, - Qt::CTRL | Qt::SHIFT | Qt::Key_E, - true); - - addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingPreDelay, - Qt::CTRL | Qt::SHIFT | Qt::Key_D, - true); - - addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingStereoSource, - Qt::CTRL | Qt::SHIFT | Qt::Key_S, - true); - - addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingHeadOriented, - Qt::CTRL | Qt::SHIFT | Qt::Key_H, - true); - - addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingWithDiffusions, - Qt::CTRL | Qt::SHIFT | Qt::Key_W, - true); - - addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingRenderPaths, - Qt::CTRL | Qt::SHIFT | Qt::Key_R, - true); - - addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingSlightlyRandomSurfaces, - Qt::CTRL | Qt::SHIFT | Qt::Key_X, - true); - - addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingProcessLocalAudio, - Qt::CTRL | Qt::SHIFT | Qt::Key_A, - true); - - addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingDontDistanceAttenuate, - Qt::CTRL | Qt::SHIFT | Qt::Key_Y, - false); - - addCheckableActionToQMenuAndActionHash(spatialAudioMenu, MenuOption::AudioSpatialProcessingAlternateDistanceAttenuate, - Qt::CTRL | Qt::SHIFT | Qt::Key_U, - false); - addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioStats, Qt::CTRL | Qt::Key_A, false, diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 7e153eba5e..6ba34ca2b9 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -341,18 +341,6 @@ namespace MenuOption { const QString AudioScopeTwentyFrames = "Twenty"; const QString AudioStats = "Audio Stats"; const QString AudioStatsShowInjectedStreams = "Audio Stats Show Injected Streams"; - const QString AudioSpatialProcessingAlternateDistanceAttenuate = "Alternate distance attenuation"; - const QString AudioSpatialProcessing = "Audio Spatial Processing"; - const QString AudioSpatialProcessingDontDistanceAttenuate = "Don't calculate distance attenuation"; - const QString AudioSpatialProcessingHeadOriented = "Head Oriented"; - const QString AudioSpatialProcessingIncludeOriginal = "Includes Network Original"; - const QString AudioSpatialProcessingPreDelay = "Add Pre-Delay"; - const QString AudioSpatialProcessingProcessLocalAudio = "Process Local Audio"; - const QString AudioSpatialProcessingRenderPaths = "Render Paths"; - const QString AudioSpatialProcessingSeparateEars = "Separate Ears"; - const QString AudioSpatialProcessingSlightlyRandomSurfaces = "Slightly Random Surfaces"; - const QString AudioSpatialProcessingStereoSource = "Stereo Source"; - const QString AudioSpatialProcessingWithDiffusions = "With Diffusions"; const QString AudioSourceInject = "Generated Audio"; const QString AudioSourcePinkNoise = "Pink Noise"; const QString AudioSourceSine440 = "Sine 440hz"; diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index e0e589b627..953c964afd 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -460,7 +460,8 @@ void Stats::display( VoxelSystem* voxels = Application::getInstance()->getVoxels(); lines = _expanded ? 14 : 3; - if (_expanded && Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessing)) { + bool wantSpatialProcessing = false; // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessing) + if (_expanded && wantSpatialProcessing) { lines += 10; // spatial audio processing adds 1 spacing line and 8 extra lines of info } @@ -652,7 +653,7 @@ void Stats::display( drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color); } - if (_expanded && Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessing)) { + if (_expanded && wantSpatialProcessing) { verticalOffset += STATS_PELS_PER_LINE; // space one line... const AudioReflector* audioReflector = Application::getInstance()->getAudioReflector(); @@ -660,23 +661,24 @@ void Stats::display( // add some reflection stats char reflectionsStatus[128]; + bool includeOriginal = true; //Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingIncludeOriginal) + bool separateEars = true; //Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingSeparateEars) + bool stereoSource = true; //Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingStereoSource) + bool randomSurfaces = true; //Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingSlightlyRandomSurfaces) + sprintf(reflectionsStatus, "Reflections: %d, Original: %s, Ears: %s, Source: %s, Normals: %s", audioReflector->getReflections(), - (Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingIncludeOriginal) - ? "included" : "silent"), - (Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingSeparateEars) - ? "two" : "one"), - (Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingStereoSource) - ? "stereo" : "mono"), - (Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingSlightlyRandomSurfaces) - ? "random" : "regular") + (includeOriginal ? "included" : "silent"), + (separateEars ? "two" : "one"), + (stereoSource ? "stereo" : "mono"), + (randomSurfaces ? "random" : "regular") ); verticalOffset += STATS_PELS_PER_LINE; drawText(horizontalOffset, verticalOffset, scale, rotation, font, reflectionsStatus, color); - float preDelay = Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingPreDelay) ? - audioReflector->getPreDelay() : 0.0f; + bool wantPreDelay = true; //Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingPreDelay) + float preDelay = wantPreDelay ? audioReflector->getPreDelay() : 0.0f; sprintf(reflectionsStatus, "Delay: pre: %6.3f, average %6.3f, max %6.3f, min %6.3f, speed: %6.3f", preDelay, @@ -688,12 +690,12 @@ void Stats::display( verticalOffset += STATS_PELS_PER_LINE; drawText(horizontalOffset, verticalOffset, scale, rotation, font, reflectionsStatus, color); - - bool distanceAttenuationDisabled = Menu::getInstance()->isOptionChecked( - MenuOption::AudioSpatialProcessingDontDistanceAttenuate); - bool alternateDistanceAttenuationEnabled = Menu::getInstance()->isOptionChecked( - MenuOption::AudioSpatialProcessingAlternateDistanceAttenuate); + //Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingDontDistanceAttenuate); + bool distanceAttenuationDisabled = false; + + // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingAlternateDistanceAttenuate); + bool alternateDistanceAttenuationEnabled = false; sprintf(reflectionsStatus, "Attenuation: average %5.3f, max %5.3f, min %5.3f, %s: %5.3f", audioReflector->getAverageAttenuation(), @@ -706,15 +708,14 @@ void Stats::display( verticalOffset += STATS_PELS_PER_LINE; drawText(horizontalOffset, verticalOffset, scale, rotation, font, reflectionsStatus, color); - sprintf(reflectionsStatus, "Local Audio: %s Attenuation: %5.3f", - (Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingProcessLocalAudio) - ? "yes" : "no"), + bool localAudio = true; // Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingProcessLocalAudio); + sprintf(reflectionsStatus, "Local Audio: %s Attenuation: %5.3f", (localAudio ? "yes" : "no"), audioReflector->getLocalAudioAttenuationFactor()); verticalOffset += STATS_PELS_PER_LINE; drawText(horizontalOffset, verticalOffset, scale, rotation, font, reflectionsStatus, color); - bool diffusionEnabled = Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingWithDiffusions); + bool diffusionEnabled = true; //Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessingWithDiffusions); int fanout = diffusionEnabled ? audioReflector->getDiffusionFanout() : 0; int diffusionPaths = diffusionEnabled ? audioReflector->getDiffusionPathCount() : 0; sprintf(reflectionsStatus, "Diffusion: %s, Fanout: %d, Paths: %d", From 1c636fe6b281f4e4549e1bcb82529691123b7893 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 24 Nov 2014 20:37:09 -0800 Subject: [PATCH 03/18] more correct entity list maintenance --- libraries/entities/src/EntityTree.cpp | 49 ++++++++++++++++++++------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index b25b153f44..bb201b6f86 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -653,7 +653,6 @@ void EntityTree::update() { } void EntityTree::updateChangedEntities(quint64 now, QSet& entitiesToDelete) { - // TODO: switch these to iterators so we can remove items that get deleted foreach (EntityItem* thisEntity, _changedEntities) { // check to see if the lifetime has expired, for immortal entities this is always false if (thisEntity->lifetimeHasExpired()) { @@ -675,15 +674,17 @@ void EntityTree::updateMovingEntities(quint64 now, QSet& entitiesT { PerformanceTimer perfTimer("_movingEntities"); - // TODO: switch these to iterators so we can remove items that get deleted - for (int i = 0; i < _movingEntities.size(); i++) { - EntityItem* thisEntity = _movingEntities[i]; + QList::iterator item_itr = _movingEntities.begin(); + while (item_itr != _movingEntities.end()) { + EntityItem* thisEntity = *item_itr; // always check to see if the lifetime has expired, for immortal entities this is always false if (thisEntity->lifetimeHasExpired()) { qDebug() << "Lifetime has expired for entity:" << thisEntity->getEntityItemID(); entitiesToDelete << thisEntity->getEntityItemID(); - clearEntityState(thisEntity); + // remove thisEntity from the list + item_itr = _movingEntities.erase(item_itr); + thisEntity->setSimulationState(EntityItem::Static); } else { AACube oldCube = thisEntity->getMaximumAACube(); thisEntity->update(now); @@ -694,10 +695,22 @@ void EntityTree::updateMovingEntities(quint64 now, QSet& entitiesT if (!domainBounds.touches(newCube)) { qDebug() << "Entity " << thisEntity->getEntityItemID() << " moved out of domain bounds."; entitiesToDelete << thisEntity->getEntityItemID(); - clearEntityState(thisEntity); + // remove thisEntity from the list + item_itr = _movingEntities.erase(item_itr); + thisEntity->setSimulationState(EntityItem::Static); } else { moveOperator.addEntityToMoveList(thisEntity, oldCube, newCube); - updateEntityState(thisEntity); + EntityItem::SimulationState newState = thisEntity->computeSimulationState(); + if (newState != EntityItem::Moving) { + if (newState == EntityItem::Mortal) { + _mortalEntities.push_back(thisEntity); + } + // remove thisEntity from the list + item_itr = _movingEntities.erase(item_itr); + thisEntity->setSimulationState(newState); + } else { + ++item_itr; + } } } } @@ -710,18 +723,30 @@ void EntityTree::updateMovingEntities(quint64 now, QSet& entitiesT } void EntityTree::updateMortalEntities(quint64 now, QSet& entitiesToDelete) { - // TODO: switch these to iterators so we can remove items that get deleted - for (int i = 0; i < _mortalEntities.size(); i++) { - EntityItem* thisEntity = _mortalEntities[i]; + QList::iterator item_itr = _mortalEntities.begin(); + while (item_itr != _mortalEntities.end()) { + EntityItem* thisEntity = *item_itr; thisEntity->update(now); // always check to see if the lifetime has expired, for immortal entities this is always false if (thisEntity->lifetimeHasExpired()) { qDebug() << "Lifetime has expired for entity:" << thisEntity->getEntityItemID(); entitiesToDelete << thisEntity->getEntityItemID(); - clearEntityState(thisEntity); + // remove thisEntity from the list + item_itr = _mortalEntities.erase(item_itr); + thisEntity->setSimulationState(EntityItem::Static); } else { // check to see if this entity is no longer moving - updateEntityState(thisEntity); + EntityItem::SimulationState newState = thisEntity->computeSimulationState(); + if (newState != EntityItem::Mortal) { + if (newState == EntityItem::Moving) { + _movingEntities.push_back(thisEntity); + } + // remove thisEntity from the list + item_itr = _mortalEntities.erase(item_itr); + thisEntity->setSimulationState(newState); + } else { + ++item_itr; + } } } } From 8966ab32d8cb0b40f77b19d65c15ef3d2f748ed1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 24 Nov 2014 20:37:52 -0800 Subject: [PATCH 04/18] add lifetime to gun bullets --- examples/gun.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/gun.js b/examples/gun.js index fff78496b2..2386e61539 100644 --- a/examples/gun.js +++ b/examples/gun.js @@ -96,6 +96,7 @@ function printVector(string, vector) { function shootBullet(position, velocity) { var BULLET_SIZE = 0.01; + var BULLET_LIFETIME = 20.0; var BULLET_GRAVITY = -0.02; Entities.addEntity( { type: "Sphere", @@ -103,6 +104,7 @@ function shootBullet(position, velocity) { dimensions: { x: BULLET_SIZE, y: BULLET_SIZE, z: BULLET_SIZE }, color: { red: 10, green: 10, blue: 10 }, velocity: velocity, + lifetime: BULLET_LIFETIME, gravity: { x: 0, y: BULLET_GRAVITY, z: 0 }, damping: 0 }); @@ -118,6 +120,7 @@ function shootBullet(position, velocity) { function shootTarget() { var TARGET_SIZE = 0.25; var TARGET_GRAVITY = -0.6; + var TARGET_LIFETIME = 300.0; var TARGET_UP_VELOCITY = 3.0; var TARGET_FWD_VELOCITY = 5.0; var DISTANCE_TO_LAUNCH_FROM = 3.0; @@ -140,7 +143,7 @@ function shootTarget() { color: { red: 0, green: 200, blue: 200 }, velocity: velocity, gravity: { x: 0, y: TARGET_GRAVITY, z: 0 }, - lifetime: 1000.0, + lifetime: TARGET_LIFETIME, damping: 0.99 }); // Record start time From 1b1482bab3c28e78e871a67584062b2e59ea0bb2 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 24 Nov 2014 21:00:04 -0800 Subject: [PATCH 05/18] Adjust size of stretch overlays to be smaller --- examples/libraries/entitySelectionTool.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index b0fc68b60c..08ac077a34 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -205,7 +205,7 @@ SelectionDisplay = (function () { var MINIMUM_DIMENSION = 0.001; - var GRABBER_DISTANCE_TO_SIZE_RATIO = 0.015; + var GRABBER_DISTANCE_TO_SIZE_RATIO = 0.0075; var spaceMode = SPACE_LOCAL; var mode = "UNKNOWN"; From 1d865ace9d41bd5336cee93d4a16f014df6c6772 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 24 Nov 2014 21:16:29 -0800 Subject: [PATCH 06/18] Add drawInFront property to Base3DOverlay --- interface/src/ui/overlays/Base3DOverlay.cpp | 16 +++++++++++++++- interface/src/ui/overlays/Base3DOverlay.h | 6 ++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 5a5bfcd937..5c6af97bf1 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -27,7 +27,8 @@ Base3DOverlay::Base3DOverlay() : _rotation(), _isSolid(DEFAULT_IS_SOLID), _isDashedLine(DEFAULT_IS_DASHED_LINE), - _ignoreRayIntersection(false) + _ignoreRayIntersection(false), + _drawInFront(false) { } @@ -45,9 +46,22 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) : Base3DOverlay::~Base3DOverlay() { } +void Base3DOverlay::setDrawInFront(bool value) { + _drawInFront = value; + emit drawInFrontUpdated(value); +} + void Base3DOverlay::setProperties(const QScriptValue& properties) { Overlay::setProperties(properties); + QScriptValue drawInFront = properties.property("drawInFront"); + + if (drawInFront.isValid()) { + bool value = drawInFront.toVariant().toBool(); + setDrawInFront(value); + _drawInFront = value; + } + QScriptValue position = properties.property("position"); // if "position" property was not there, check to see if they included aliases: start, point, p1 diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 8304883e3c..46d99cf3de 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -36,6 +36,7 @@ public: bool getIsSolidLine() const { return !_isDashedLine; } const glm::quat& getRotation() const { return _rotation; } bool getIgnoreRayIntersection() const { return _ignoreRayIntersection; } + bool getDrawInFront() const { return _drawInFront; } // setters void setPosition(const glm::vec3& position) { _position = position; } @@ -44,6 +45,7 @@ public: void setIsDashedLine(bool isDashedLine) { _isDashedLine = isDashedLine; } void setRotation(const glm::quat& value) { _rotation = value; } void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; } + void setDrawInFront(bool value); virtual void setProperties(const QScriptValue& properties); virtual QScriptValue getProperty(const QString& property); @@ -55,6 +57,9 @@ public: return findRayIntersection(origin, direction, distance, face); } +signals: + void drawInFrontUpdated(bool newValue); + protected: void drawDashedLine(const glm::vec3& start, const glm::vec3& end); @@ -64,6 +69,7 @@ protected: bool _isSolid; bool _isDashedLine; bool _ignoreRayIntersection; + bool _drawInFront; }; #endif // hifi_Base3DOverlay_h From 0b46e35f31df467faf1c698adc429a3156025b89 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 24 Nov 2014 23:19:13 -0800 Subject: [PATCH 07/18] Add support for separate list of 3d overlays to be drawn in front --- interface/src/ui/overlays/Base3DOverlay.cpp | 7 +- interface/src/ui/overlays/Overlays.cpp | 99 ++++++++++++++++----- interface/src/ui/overlays/Overlays.h | 12 +++ 3 files changed, 92 insertions(+), 26 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 5c6af97bf1..b3dc377282 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -47,8 +47,10 @@ Base3DOverlay::~Base3DOverlay() { } void Base3DOverlay::setDrawInFront(bool value) { - _drawInFront = value; - emit drawInFrontUpdated(value); + if (value != _drawInFront) { + _drawInFront = value; + emit drawInFrontUpdated(value); + } } void Base3DOverlay::setProperties(const QScriptValue& properties) { @@ -59,7 +61,6 @@ void Base3DOverlay::setProperties(const QScriptValue& properties) { if (drawInFront.isValid()) { bool value = drawInFront.toVariant().toBool(); setDrawInFront(value); - _drawInFront = value; } QScriptValue position = properties.property("position"); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index d6dbb0861e..5de410c1d9 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -29,7 +29,8 @@ #include "TextOverlay.h" #include "Text3DOverlay.h" -Overlays::Overlays() : _nextOverlayID(1) { +Overlays::Overlays() : _nextOverlayID(1), _overlaySignalMapper() { + connect(&_overlaySignalMapper, SIGNAL(mapped(int)), this, SLOT(handleOverlayDrawInFrontUpdated(unsigned int))); } Overlays::~Overlays() { @@ -70,6 +71,9 @@ void Overlays::update(float deltatime) { foreach(Overlay* thisOverlay, _overlays3D) { thisOverlay->update(deltatime); } + foreach(Overlay* thisOverlay, _overlays3DFront) { + thisOverlay->update(deltatime); + } } if (!_overlaysToDelete.isEmpty()) { @@ -94,8 +98,16 @@ void Overlays::render2D() { } void Overlays::render3D(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { + render3DOverlays(_overlays3D, renderMode, renderSide); +} + +void Overlays::render3DFront(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { + render3DOverlays(_overlays3DFront, renderMode, renderSide); +} + +void Overlays::render3DOverlays(QMap& overlays, RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { QReadLocker lock(&_lock); - if (_overlays3D.size() == 0) { + if (overlays.size() == 0) { return; } bool myAvatarComputed = false; @@ -111,7 +123,7 @@ void Overlays::render3D(RenderArgs::RenderMode renderMode, RenderArgs::RenderSid renderMode, renderSide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - foreach(Overlay* thisOverlay, _overlays3D) { + foreach(Overlay* thisOverlay, overlays) { glPushMatrix(); switch (thisOverlay->getAnchor()) { case Overlay::MY_AVATAR: @@ -188,7 +200,15 @@ unsigned int Overlays::addOverlay(Overlay* overlay) { unsigned int thisID = _nextOverlayID; _nextOverlayID++; if (overlay->is3D()) { - _overlays3D[thisID] = overlay; + Base3DOverlay* overlay3D = static_cast(overlay); + if (overlay3D->getDrawInFront()) { + _overlays3DFront[thisID] = overlay; + } else { + _overlays3D[thisID] = overlay; + } + + _overlaySignalMapper.setMapping(overlay3D, thisID); + connect(overlay3D, SIGNAL(drawInFrontUpdated(bool)), &_overlaySignalMapper, SLOT(map())); } else { _overlays2D[thisID] = overlay; } @@ -213,6 +233,8 @@ bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) { thisOverlay = _overlays2D[id]; } else if (_overlays3D.contains(id)) { thisOverlay = _overlays3D[id]; + } else if (_overlays3DFront.contains(id)) { + thisOverlay = _overlays3DFront[id]; } if (thisOverlay) { thisOverlay->setProperties(properties); @@ -230,6 +252,8 @@ void Overlays::deleteOverlay(unsigned int id) { overlayToDelete = _overlays2D.take(id); } else if (_overlays3D.contains(id)) { overlayToDelete = _overlays3D.take(id); + } else if (_overlays3DFront.contains(id)) { + overlayToDelete = _overlays3DFront.take(id); } else { return; } @@ -239,6 +263,22 @@ void Overlays::deleteOverlay(unsigned int id) { _overlaysToDelete.push_back(overlayToDelete); } +void Overlays::handleOverlayDrawInFrontUpdated(int overlayID) { + if (_overlays3D.contains(overlayID)) { + Base3DOverlay* overlay = static_cast(_overlays3D[overlayID]); + if (overlay->getDrawInFront()) { + _overlays3D.remove(overlayID); + _overlays3DFront[overlayID] = overlay; + } + } else if (_overlays3DFront.contains(overlayID)) { + Base3DOverlay* overlay = static_cast(_overlays3DFront[overlayID]); + if (!overlay->getDrawInFront()) { + _overlays3DFront.remove(overlayID); + _overlays3D[overlayID] = overlay; + } + } +} + unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { QReadLocker lock(&_lock); QMapIterator i(_overlays2D); @@ -262,6 +302,8 @@ OverlayPropertyResult Overlays::getProperty(unsigned int id, const QString& prop thisOverlay = _overlays2D[id]; } else if (_overlays3D.contains(id)) { thisOverlay = _overlays3D[id]; + } else if (_overlays3DFront.contains(id)) { + thisOverlay = _overlays3DFront[id]; } if (thisOverlay) { result.value = thisOverlay->getProperty(property); @@ -300,30 +342,39 @@ void OverlayPropertyResultFromScriptValue(const QScriptValue& value, OverlayProp } RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray) { + QMap overlayMaps[] = { _overlays3DFront, _overlays3D }; + float bestDistance = std::numeric_limits::max(); RayToOverlayIntersectionResult result; - QMapIterator i(_overlays3D); - i.toBack(); - while (i.hasPrevious()) { - i.previous(); - unsigned int thisID = i.key(); - Base3DOverlay* thisOverlay = static_cast(i.value()); - if (thisOverlay->getVisible() && !thisOverlay->getIgnoreRayIntersection() && thisOverlay->isLoaded()) { - float thisDistance; - BoxFace thisFace; - QString thisExtraInfo; - if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance, thisFace, thisExtraInfo)) { - if (thisDistance < bestDistance) { - bestDistance = thisDistance; - result.intersects = true; - result.distance = thisDistance; - result.face = thisFace; - result.overlayID = thisID; - result.intersection = ray.origin + (ray.direction * thisDistance); - result.extraInfo = thisExtraInfo; + for (int idx = 0; idx < 2; idx++) { + QMapIterator i(overlayMaps[idx]); + i.toBack(); + while (i.hasPrevious()) { + i.previous(); + unsigned int thisID = i.key(); + Base3DOverlay* thisOverlay = static_cast(i.value()); + if (thisOverlay->getVisible() && !thisOverlay->getIgnoreRayIntersection() && thisOverlay->isLoaded()) { + float thisDistance; + BoxFace thisFace; + QString thisExtraInfo; + if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance, thisFace, thisExtraInfo)) { + if (thisDistance < bestDistance) { + bestDistance = thisDistance; + result.intersects = true; + result.distance = thisDistance; + result.face = thisFace; + result.overlayID = thisID; + result.intersection = ray.origin + (ray.direction * thisDistance); + result.extraInfo = thisExtraInfo; + } } } } + if (result.intersects) { + // We first check the front overlays - if one has been intersected, prefer + // it over any other overlays and return it immediately. + break; + } } return result; } @@ -412,6 +463,8 @@ bool Overlays::isLoaded(unsigned int id) { thisOverlay = _overlays2D[id]; } else if (_overlays3D.contains(id)) { thisOverlay = _overlays3D[id]; + } else if (_overlays3DFront.contains(id)) { + thisOverlay = _overlays3DFront[id]; } else { return false; // not found } diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 2cd80041cd..c46d9474da 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -13,6 +13,7 @@ #include #include +#include #include "Overlay.h" @@ -53,6 +54,8 @@ public: void update(float deltatime); void render3D(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); + void render3DFront(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::RenderSide renderSide = RenderArgs::MONO); void render2D(); public slots: @@ -88,10 +91,19 @@ public slots: /// overlay; in meters if it is a 3D text overlay float textWidth(unsigned int id, const QString& text) const; +protected: + void render3DOverlays(QMap& overlays, RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide); + +private slots: + /// QSignalMapper unfortunately does not work with unsigned integers. + void handleOverlayDrawInFrontUpdated(int overlayID); + private: QMap _overlays2D; QMap _overlays3D; + QMap _overlays3DFront; QList _overlaysToDelete; + QSignalMapper _overlaySignalMapper; unsigned int _nextOverlayID; QGLWidget* _parent; QReadWriteLock _lock; From 8b982872c2d59370e7de9cd22abbea7d53da8467 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 24 Nov 2014 23:19:53 -0800 Subject: [PATCH 08/18] Add calls to Overlays::render3DFront() --- interface/src/Application.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4e8b95862a..8d1e77ed25 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2839,6 +2839,11 @@ void Application::updateShadowMap() { _overlays.render3D(RenderArgs::SHADOW_RENDER_MODE); } + { + PerformanceTimer perfTimer("3dOverlaysFront"); + _overlays.render3DFront(RenderArgs::SHADOW_RENDER_MODE); + } + glDisable(GL_POLYGON_OFFSET_FILL); glPopMatrix(); @@ -3135,6 +3140,13 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderAr if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } + + // Render 3D overlays that should be drawn in front + { + PerformanceTimer perfTimer("3dOverlaysFront"); + glClear(GL_DEPTH_BUFFER_BIT); + _overlays.render3DFront(); + } } void Application::updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTranslation) { From 925c2a8f6c10bcd568e4131b3b76f5d67716874e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 25 Nov 2014 08:34:44 -0800 Subject: [PATCH 09/18] Update array to use pointers --- interface/src/ui/overlays/Overlays.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 5de410c1d9..2d4edca781 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -342,12 +342,12 @@ void OverlayPropertyResultFromScriptValue(const QScriptValue& value, OverlayProp } RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray) { - QMap overlayMaps[] = { _overlays3DFront, _overlays3D }; + QMap* overlayMaps[] = { &_overlays3DFront, &_overlays3D }; float bestDistance = std::numeric_limits::max(); RayToOverlayIntersectionResult result; for (int idx = 0; idx < 2; idx++) { - QMapIterator i(overlayMaps[idx]); + QMapIterator i(*overlayMaps[idx]); i.toBack(); while (i.hasPrevious()) { i.previous(); From 4febc45b6a04d2e9cd2fe3fc7091802de8f30666 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 25 Nov 2014 08:44:38 -0800 Subject: [PATCH 10/18] Add drawInFront to Base3DOverlay::getProperty --- interface/src/ui/overlays/Base3DOverlay.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index b3dc377282..1c80b62782 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -166,6 +166,9 @@ QScriptValue Base3DOverlay::getProperty(const QString& property) { if (property == "ignoreRayIntersection") { return _ignoreRayIntersection; } + if (property == "drawInFront") { + return _drawInFront; + } return Overlay::getProperty(property); } From 649ae4a4485398843842d35c33ecdb4118a6aebf Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 25 Nov 2014 09:49:10 -0800 Subject: [PATCH 11/18] Update 3D overlays to only use one list --- interface/src/Application.cpp | 8 +- interface/src/ui/overlays/Base3DOverlay.cpp | 7 -- interface/src/ui/overlays/Base3DOverlay.h | 5 +- interface/src/ui/overlays/Overlays.cpp | 108 ++++++-------------- interface/src/ui/overlays/Overlays.h | 13 +-- 5 files changed, 37 insertions(+), 104 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8d1e77ed25..de889c7f61 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2836,12 +2836,12 @@ void Application::updateShadowMap() { // render JS/scriptable overlays { PerformanceTimer perfTimer("3dOverlays"); - _overlays.render3D(RenderArgs::SHADOW_RENDER_MODE); + _overlays.render3D(false, RenderArgs::SHADOW_RENDER_MODE); } { PerformanceTimer perfTimer("3dOverlaysFront"); - _overlays.render3DFront(RenderArgs::SHADOW_RENDER_MODE); + _overlays.render3D(true, RenderArgs::SHADOW_RENDER_MODE); } glDisable(GL_POLYGON_OFFSET_FILL); @@ -3056,7 +3056,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderAr // render JS/scriptable overlays { PerformanceTimer perfTimer("3dOverlays"); - _overlays.render3D(); + _overlays.render3D(false); } // render the ambient occlusion effect if enabled @@ -3145,7 +3145,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderAr { PerformanceTimer perfTimer("3dOverlaysFront"); glClear(GL_DEPTH_BUFFER_BIT); - _overlays.render3DFront(); + _overlays.render3D(true); } } diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 1c80b62782..55b4c88812 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -46,13 +46,6 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) : Base3DOverlay::~Base3DOverlay() { } -void Base3DOverlay::setDrawInFront(bool value) { - if (value != _drawInFront) { - _drawInFront = value; - emit drawInFrontUpdated(value); - } -} - void Base3DOverlay::setProperties(const QScriptValue& properties) { Overlay::setProperties(properties); diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 46d99cf3de..d57f9731c4 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -45,7 +45,7 @@ public: void setIsDashedLine(bool isDashedLine) { _isDashedLine = isDashedLine; } void setRotation(const glm::quat& value) { _rotation = value; } void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; } - void setDrawInFront(bool value); + void setDrawInFront(bool value) { _drawInFront = value; } virtual void setProperties(const QScriptValue& properties); virtual QScriptValue getProperty(const QString& property); @@ -57,9 +57,6 @@ public: return findRayIntersection(origin, direction, distance, face); } -signals: - void drawInFrontUpdated(bool newValue); - protected: void drawDashedLine(const glm::vec3& start, const glm::vec3& end); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 2d4edca781..151e3c3ba7 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -29,8 +29,7 @@ #include "TextOverlay.h" #include "Text3DOverlay.h" -Overlays::Overlays() : _nextOverlayID(1), _overlaySignalMapper() { - connect(&_overlaySignalMapper, SIGNAL(mapped(int)), this, SLOT(handleOverlayDrawInFrontUpdated(unsigned int))); +Overlays::Overlays() : _nextOverlayID(1) { } Overlays::~Overlays() { @@ -71,9 +70,6 @@ void Overlays::update(float deltatime) { foreach(Overlay* thisOverlay, _overlays3D) { thisOverlay->update(deltatime); } - foreach(Overlay* thisOverlay, _overlays3DFront) { - thisOverlay->update(deltatime); - } } if (!_overlaysToDelete.isEmpty()) { @@ -97,17 +93,9 @@ void Overlays::render2D() { } } -void Overlays::render3D(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { - render3DOverlays(_overlays3D, renderMode, renderSide); -} - -void Overlays::render3DFront(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { - render3DOverlays(_overlays3DFront, renderMode, renderSide); -} - -void Overlays::render3DOverlays(QMap& overlays, RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { +void Overlays::render3D(bool drawFront, RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { QReadLocker lock(&_lock); - if (overlays.size() == 0) { + if (_overlays3D.size() == 0) { return; } bool myAvatarComputed = false; @@ -123,7 +111,11 @@ void Overlays::render3DOverlays(QMap& overlays, RenderAr renderMode, renderSide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - foreach(Overlay* thisOverlay, overlays) { + foreach(Overlay* thisOverlay, _overlays3D) { + Base3DOverlay* overlay3D = static_cast(thisOverlay); + if (overlay3D->getDrawInFront() != drawFront) { + continue; + } glPushMatrix(); switch (thisOverlay->getAnchor()) { case Overlay::MY_AVATAR: @@ -200,15 +192,7 @@ unsigned int Overlays::addOverlay(Overlay* overlay) { unsigned int thisID = _nextOverlayID; _nextOverlayID++; if (overlay->is3D()) { - Base3DOverlay* overlay3D = static_cast(overlay); - if (overlay3D->getDrawInFront()) { - _overlays3DFront[thisID] = overlay; - } else { - _overlays3D[thisID] = overlay; - } - - _overlaySignalMapper.setMapping(overlay3D, thisID); - connect(overlay3D, SIGNAL(drawInFrontUpdated(bool)), &_overlaySignalMapper, SLOT(map())); + _overlays3D[thisID] = overlay; } else { _overlays2D[thisID] = overlay; } @@ -233,8 +217,6 @@ bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) { thisOverlay = _overlays2D[id]; } else if (_overlays3D.contains(id)) { thisOverlay = _overlays3D[id]; - } else if (_overlays3DFront.contains(id)) { - thisOverlay = _overlays3DFront[id]; } if (thisOverlay) { thisOverlay->setProperties(properties); @@ -252,8 +234,6 @@ void Overlays::deleteOverlay(unsigned int id) { overlayToDelete = _overlays2D.take(id); } else if (_overlays3D.contains(id)) { overlayToDelete = _overlays3D.take(id); - } else if (_overlays3DFront.contains(id)) { - overlayToDelete = _overlays3DFront.take(id); } else { return; } @@ -263,22 +243,6 @@ void Overlays::deleteOverlay(unsigned int id) { _overlaysToDelete.push_back(overlayToDelete); } -void Overlays::handleOverlayDrawInFrontUpdated(int overlayID) { - if (_overlays3D.contains(overlayID)) { - Base3DOverlay* overlay = static_cast(_overlays3D[overlayID]); - if (overlay->getDrawInFront()) { - _overlays3D.remove(overlayID); - _overlays3DFront[overlayID] = overlay; - } - } else if (_overlays3DFront.contains(overlayID)) { - Base3DOverlay* overlay = static_cast(_overlays3DFront[overlayID]); - if (!overlay->getDrawInFront()) { - _overlays3DFront.remove(overlayID); - _overlays3D[overlayID] = overlay; - } - } -} - unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { QReadLocker lock(&_lock); QMapIterator i(_overlays2D); @@ -302,8 +266,6 @@ OverlayPropertyResult Overlays::getProperty(unsigned int id, const QString& prop thisOverlay = _overlays2D[id]; } else if (_overlays3D.contains(id)) { thisOverlay = _overlays3D[id]; - } else if (_overlays3DFront.contains(id)) { - thisOverlay = _overlays3DFront[id]; } if (thisOverlay) { result.value = thisOverlay->getProperty(property); @@ -342,39 +304,33 @@ void OverlayPropertyResultFromScriptValue(const QScriptValue& value, OverlayProp } RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray) { - QMap* overlayMaps[] = { &_overlays3DFront, &_overlays3D }; - float bestDistance = std::numeric_limits::max(); + float bestIsFront = false; RayToOverlayIntersectionResult result; - for (int idx = 0; idx < 2; idx++) { - QMapIterator i(*overlayMaps[idx]); - i.toBack(); - while (i.hasPrevious()) { - i.previous(); - unsigned int thisID = i.key(); - Base3DOverlay* thisOverlay = static_cast(i.value()); - if (thisOverlay->getVisible() && !thisOverlay->getIgnoreRayIntersection() && thisOverlay->isLoaded()) { - float thisDistance; - BoxFace thisFace; - QString thisExtraInfo; - if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance, thisFace, thisExtraInfo)) { - if (thisDistance < bestDistance) { - bestDistance = thisDistance; - result.intersects = true; - result.distance = thisDistance; - result.face = thisFace; - result.overlayID = thisID; - result.intersection = ray.origin + (ray.direction * thisDistance); - result.extraInfo = thisExtraInfo; - } + QMapIterator i(_overlays3D); + i.toBack(); + while (i.hasPrevious()) { + i.previous(); + unsigned int thisID = i.key(); + Base3DOverlay* thisOverlay = static_cast(i.value()); + if (thisOverlay->getVisible() && !thisOverlay->getIgnoreRayIntersection() && thisOverlay->isLoaded()) { + float thisDistance; + BoxFace thisFace; + QString thisExtraInfo; + if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance, thisFace, thisExtraInfo)) { + bool isDrawInFront = thisOverlay->getDrawInFront(); + if (thisDistance < bestDistance && (!bestIsFront || isDrawInFront)) { + bestIsFront = isDrawInFront; + bestDistance = thisDistance; + result.intersects = true; + result.distance = thisDistance; + result.face = thisFace; + result.overlayID = thisID; + result.intersection = ray.origin + (ray.direction * thisDistance); + result.extraInfo = thisExtraInfo; } } } - if (result.intersects) { - // We first check the front overlays - if one has been intersected, prefer - // it over any other overlays and return it immediately. - break; - } } return result; } @@ -463,8 +419,6 @@ bool Overlays::isLoaded(unsigned int id) { thisOverlay = _overlays2D[id]; } else if (_overlays3D.contains(id)) { thisOverlay = _overlays3D[id]; - } else if (_overlays3DFront.contains(id)) { - thisOverlay = _overlays3DFront[id]; } else { return false; // not found } diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index c46d9474da..7acc2c7878 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -52,9 +52,7 @@ public: ~Overlays(); void init(QGLWidget* parent); void update(float deltatime); - void render3D(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, - RenderArgs::RenderSide renderSide = RenderArgs::MONO); - void render3DFront(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, + void render3D(bool drawFront, RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); void render2D(); @@ -91,19 +89,10 @@ public slots: /// overlay; in meters if it is a 3D text overlay float textWidth(unsigned int id, const QString& text) const; -protected: - void render3DOverlays(QMap& overlays, RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide); - -private slots: - /// QSignalMapper unfortunately does not work with unsigned integers. - void handleOverlayDrawInFrontUpdated(int overlayID); - private: QMap _overlays2D; QMap _overlays3D; - QMap _overlays3DFront; QList _overlaysToDelete; - QSignalMapper _overlaySignalMapper; unsigned int _nextOverlayID; QGLWidget* _parent; QReadWriteLock _lock; From b97870f32ed55314188547b8d3d99e2350458f19 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 25 Nov 2014 12:01:29 -0800 Subject: [PATCH 12/18] Update extra entity tool stretch handles to be optionally visible --- examples/libraries/entitySelectionTool.js | 44 ++++++++++++----------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 08ac077a34..d820cf733f 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -206,6 +206,8 @@ SelectionDisplay = (function () { var MINIMUM_DIMENSION = 0.001; var GRABBER_DISTANCE_TO_SIZE_RATIO = 0.0075; + + var showExtendedStretchHandles = false; var spaceMode = SPACE_LOCAL; var mode = "UNKNOWN"; @@ -1057,21 +1059,23 @@ SelectionDisplay = (function () { EdgeFL = Vec3.sum(position, EdgeFL); var stretchHandlesVisible = spaceMode == SPACE_LOCAL; + var extendedStretchHandlesVisible = stretchHandlesVisible && showExtendedStretchHandles; Overlays.editOverlay(grabberLBN, { visible: stretchHandlesVisible, rotation: rotation, position: LBN }); Overlays.editOverlay(grabberRBN, { visible: stretchHandlesVisible, rotation: rotation, position: RBN }); Overlays.editOverlay(grabberLBF, { visible: stretchHandlesVisible, rotation: rotation, position: LBF }); Overlays.editOverlay(grabberRBF, { visible: stretchHandlesVisible, rotation: rotation, position: RBF }); - Overlays.editOverlay(grabberLTN, { visible: stretchHandlesVisible, rotation: rotation, position: LTN }); - Overlays.editOverlay(grabberRTN, { visible: stretchHandlesVisible, rotation: rotation, position: RTN }); - Overlays.editOverlay(grabberLTF, { visible: stretchHandlesVisible, rotation: rotation, position: LTF }); - Overlays.editOverlay(grabberRTF, { visible: stretchHandlesVisible, rotation: rotation, position: RTF }); + + Overlays.editOverlay(grabberLTN, { visible: extendedStretchHandlesVisible, rotation: rotation, position: LTN }); + Overlays.editOverlay(grabberRTN, { visible: extendedStretchHandlesVisible, rotation: rotation, position: RTN }); + Overlays.editOverlay(grabberLTF, { visible: extendedStretchHandlesVisible, rotation: rotation, position: LTF }); + Overlays.editOverlay(grabberRTF, { visible: extendedStretchHandlesVisible, rotation: rotation, position: RTF }); Overlays.editOverlay(grabberTOP, { visible: stretchHandlesVisible, rotation: rotation, position: TOP }); Overlays.editOverlay(grabberBOTTOM, { visible: stretchHandlesVisible, rotation: rotation, position: BOTTOM }); - Overlays.editOverlay(grabberLEFT, { visible: stretchHandlesVisible, rotation: rotation, position: LEFT }); - Overlays.editOverlay(grabberRIGHT, { visible: stretchHandlesVisible, rotation: rotation, position: RIGHT }); - Overlays.editOverlay(grabberNEAR, { visible: stretchHandlesVisible, rotation: rotation, position: NEAR }); - Overlays.editOverlay(grabberFAR, { visible: stretchHandlesVisible, rotation: rotation, position: FAR }); + Overlays.editOverlay(grabberLEFT, { visible: extendedStretchHandlesVisible, rotation: rotation, position: LEFT }); + Overlays.editOverlay(grabberRIGHT, { visible: extendedStretchHandlesVisible, rotation: rotation, position: RIGHT }); + Overlays.editOverlay(grabberNEAR, { visible: extendedStretchHandlesVisible, rotation: rotation, position: NEAR }); + Overlays.editOverlay(grabberFAR, { visible: extendedStretchHandlesVisible, rotation: rotation, position: FAR }); Overlays.editOverlay(selectionBox, { position: position, @@ -1080,18 +1084,18 @@ SelectionDisplay = (function () { visible: !(mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL"), }); - Overlays.editOverlay(grabberEdgeTR, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeTR }); - Overlays.editOverlay(grabberEdgeTL, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeTL }); - Overlays.editOverlay(grabberEdgeTF, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeTF }); - Overlays.editOverlay(grabberEdgeTN, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeTN }); + Overlays.editOverlay(grabberEdgeTR, { visible: extendedStretchHandlesVisible, rotation: rotation, position: EdgeTR }); + Overlays.editOverlay(grabberEdgeTL, { visible: extendedStretchHandlesVisible, rotation: rotation, position: EdgeTL }); + Overlays.editOverlay(grabberEdgeTF, { visible: extendedStretchHandlesVisible, rotation: rotation, position: EdgeTF }); + Overlays.editOverlay(grabberEdgeTN, { visible: extendedStretchHandlesVisible, rotation: rotation, position: EdgeTN }); Overlays.editOverlay(grabberEdgeBR, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeBR }); Overlays.editOverlay(grabberEdgeBL, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeBL }); Overlays.editOverlay(grabberEdgeBF, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeBF }); Overlays.editOverlay(grabberEdgeBN, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeBN }); - Overlays.editOverlay(grabberEdgeNR, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeNR }); - Overlays.editOverlay(grabberEdgeNL, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeNL }); - Overlays.editOverlay(grabberEdgeFR, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeFR }); - Overlays.editOverlay(grabberEdgeFL, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeFL }); + Overlays.editOverlay(grabberEdgeNR, { visible: extendedStretchHandlesVisible, rotation: rotation, position: EdgeNR }); + Overlays.editOverlay(grabberEdgeNL, { visible: extendedStretchHandlesVisible, rotation: rotation, position: EdgeNL }); + Overlays.editOverlay(grabberEdgeFR, { visible: extendedStretchHandlesVisible, rotation: rotation, position: EdgeFR }); + Overlays.editOverlay(grabberEdgeFL, { visible: extendedStretchHandlesVisible, rotation: rotation, position: EdgeFL }); var grabberMoveUpOffset = 0.1; grabberMoveUpPosition = { x: position.x, y: position.y + worldTop + grabberMoveUpOffset, z: position.z } @@ -1507,10 +1511,10 @@ SelectionDisplay = (function () { addStretchTool(grabberEdgeTL, "STRETCH_EdgeTL", null, {x: -1, y: 1, z: 0}); addStretchTool(grabberEdgeTF, "STRETCH_EdgeTF", null, {x: 0, y: 1, z: -1}); addStretchTool(grabberEdgeTN, "STRETCH_EdgeTN", null, {x: 0, y: 1, z: 1}); - addStretchTool(grabberEdgeBR, "STRETCH_EdgeBR", null, {x: 1, y: -1, z: 0}); - addStretchTool(grabberEdgeBL, "STRETCH_EdgeBL", null, {x: -1, y: -1, z: 0}); - addStretchTool(grabberEdgeBF, "STRETCH_EdgeBF", null, {x: 0, y: -1, z: 1}); - addStretchTool(grabberEdgeBN, "STRETCH_EdgeBN", null, {x: 0, y: -1, z: -1}); + addStretchTool(grabberEdgeBR, "STRETCH_EdgeBR", null, {x: -1, y: 0, z: 0}); + addStretchTool(grabberEdgeBL, "STRETCH_EdgeBL", null, {x: 1, y: 0, z: 0}); + addStretchTool(grabberEdgeBF, "STRETCH_EdgeBF", null, {x: 0, y: 0, z: -1}); + addStretchTool(grabberEdgeBN, "STRETCH_EdgeBN", null, {x: 0, y: 0, z: 1}); addStretchTool(grabberEdgeNR, "STRETCH_EdgeNR", null, {x: -1, y: 0, z: 1}); addStretchTool(grabberEdgeNL, "STRETCH_EdgeNL", null, {x: 1, y: 0, z: 1}); addStretchTool(grabberEdgeFR, "STRETCH_EdgeFR", null, {x: -1, y: 0, z: -1}); From b3ca6fda72c18a4a37207581942c992eb91ed2a4 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 25 Nov 2014 12:04:11 -0800 Subject: [PATCH 13/18] Update entity tool grabbers look and size --- examples/libraries/entitySelectionTool.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index d820cf733f..38ec0ba1ea 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -273,6 +273,8 @@ SelectionDisplay = (function () { visible: false, dashed: false, lineWidth: grabberLineWidth, + drawInFront: true, + borderSize: 1.4, }; var grabberPropertiesEdge = { @@ -284,6 +286,8 @@ SelectionDisplay = (function () { visible: false, dashed: false, lineWidth: grabberLineWidth, + drawInFront: true, + borderSize: 1.4, }; var grabberPropertiesFace = { @@ -295,6 +299,8 @@ SelectionDisplay = (function () { visible: false, dashed: false, lineWidth: grabberLineWidth, + drawInFront: true, + borderSize: 1.4, }; var highlightBox = Overlays.addOverlay("cube", { @@ -328,7 +334,8 @@ SelectionDisplay = (function () { visible: false, size: 0.1, scale: 0.1, - isFacingAvatar: true + isFacingAvatar: true, + drawInFront: true, }); // var normalLine = Overlays.addOverlay("line3d", { @@ -2293,7 +2300,7 @@ SelectionDisplay = (function () { size: grabberSize, }); } - var handleSize = Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 5; + var handleSize = Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 10; Overlays.editOverlay(yawHandle, { scale: handleSize, }); From c5f2b3b5885fd675f0f223c882b555154078aa7a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 25 Nov 2014 12:05:13 -0800 Subject: [PATCH 14/18] Add borderSize to Cube3DOverlay --- interface/src/ui/overlays/Cube3DOverlay.cpp | 42 +++++++++++++++++++-- interface/src/ui/overlays/Cube3DOverlay.h | 10 +++++ 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 9c478c4465..223a695328 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -19,7 +19,7 @@ #include "Cube3DOverlay.h" #include "renderer/GlowEffect.h" -Cube3DOverlay::Cube3DOverlay() { +Cube3DOverlay::Cube3DOverlay() : _borderSize(0) { } Cube3DOverlay::Cube3DOverlay(const Cube3DOverlay* cube3DOverlay) : @@ -63,8 +63,25 @@ void Cube3DOverlay::render(RenderArgs* args) { glm::vec3 positionToCenter = center - position; glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); if (_isSolid) { - glScalef(dimensions.x, dimensions.y, dimensions.z); - Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f); + if (_borderSize > 0) { + // Disable writing to the depth mask so that the following draw + // will not be occluded by this one. This means the border + // could be covered by overlays that are further back and drawn + // later, but this is good enough for the use-case. + glDepthMask(GL_FALSE); + glPushMatrix(); + glColor4f(MAX_COLOR, MAX_COLOR, MAX_COLOR, 1.0f); + glScalef(dimensions.x * _borderSize, dimensions.y * _borderSize, dimensions.z * _borderSize); + Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f); + glPopMatrix(); + glDepthMask(GL_TRUE); + } + + glPushMatrix(); + glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); + glScalef(dimensions.x, dimensions.y, dimensions.z); + Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f); + glPopMatrix(); } else { glLineWidth(_lineWidth); @@ -111,3 +128,22 @@ void Cube3DOverlay::render(RenderArgs* args) { Cube3DOverlay* Cube3DOverlay::createClone() const { return new Cube3DOverlay(this); } + +void Cube3DOverlay::setProperties(const QScriptValue& properties) { + Volume3DOverlay::setProperties(properties); + + QScriptValue borderSize = properties.property("borderSize"); + + if (borderSize.isValid()) { + float value = borderSize.toVariant().toFloat(); + setBorderSize(value); + } +} + +QScriptValue Cube3DOverlay::getProperty(const QString& property) { + if (property == "borderSize") { + return _borderSize; + } + + return Volume3DOverlay::getProperty(property); +} diff --git a/interface/src/ui/overlays/Cube3DOverlay.h b/interface/src/ui/overlays/Cube3DOverlay.h index 9c199f2b7b..16705a9c71 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.h +++ b/interface/src/ui/overlays/Cube3DOverlay.h @@ -23,6 +23,16 @@ public: virtual void render(RenderArgs* args); virtual Cube3DOverlay* createClone() const; + + float getBorderSize() const { return _borderSize; } + + void setBorderSize(float value) { _borderSize = value; } + + virtual void setProperties(const QScriptValue& properties); + virtual QScriptValue getProperty(const QString& property); + +private: + float _borderSize; }; From f8c8ed868e2a652459c6a2646493bc8b842ef25b Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 25 Nov 2014 12:08:48 -0800 Subject: [PATCH 15/18] Update float that should be bool --- interface/src/ui/overlays/Overlays.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 151e3c3ba7..455b73fb80 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -305,7 +305,7 @@ void OverlayPropertyResultFromScriptValue(const QScriptValue& value, OverlayProp RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray) { float bestDistance = std::numeric_limits::max(); - float bestIsFront = false; + bool bestIsFront = false; RayToOverlayIntersectionResult result; QMapIterator i(_overlays3D); i.toBack(); From 2cb30c215787447221403f3ecd39bf76bb2bc478 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 25 Nov 2014 12:17:46 -0800 Subject: [PATCH 16/18] Update color used for Cube3DOverlay border --- interface/src/ui/overlays/Cube3DOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 223a695328..1f3413908e 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -70,7 +70,7 @@ void Cube3DOverlay::render(RenderArgs* args) { // later, but this is good enough for the use-case. glDepthMask(GL_FALSE); glPushMatrix(); - glColor4f(MAX_COLOR, MAX_COLOR, MAX_COLOR, 1.0f); + glColor4f(1.0f, 1.0f, 1.0f, alpha); glScalef(dimensions.x * _borderSize, dimensions.y * _borderSize, dimensions.z * _borderSize); Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f); glPopMatrix(); From 75d560744bac087757ff76c44ae1917fe3e3f8db Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 25 Nov 2014 12:34:03 -0800 Subject: [PATCH 17/18] Update rotation handles to drawInFront = true --- examples/libraries/entitySelectionTool.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 38ec0ba1ea..813bf015d1 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -542,7 +542,8 @@ SelectionDisplay = (function () { visible: false, size: 0.1, scale: 0.1, - isFacingAvatar: false + isFacingAvatar: false, + drawInFront: true, }); @@ -554,7 +555,8 @@ SelectionDisplay = (function () { visible: false, size: 0.1, scale: 0.1, - isFacingAvatar: false + isFacingAvatar: false, + drawInFront: true, }); @@ -566,7 +568,8 @@ SelectionDisplay = (function () { visible: false, size: 0.1, scale: 0.1, - isFacingAvatar: false + isFacingAvatar: false, + drawInFront: true, }); var allOverlays = [ From 0b23b57e1e45d02e7f1a1e65c171fc23e221480d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 25 Nov 2014 12:43:01 -0800 Subject: [PATCH 18/18] Update border comment in Cube3DOverlay --- interface/src/ui/overlays/Cube3DOverlay.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 1f3413908e..8e37dedd77 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -64,10 +64,12 @@ void Cube3DOverlay::render(RenderArgs* args) { glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); if (_isSolid) { if (_borderSize > 0) { - // Disable writing to the depth mask so that the following draw - // will not be occluded by this one. This means the border - // could be covered by overlays that are further back and drawn - // later, but this is good enough for the use-case. + // Draw a cube at a larger size behind the main cube, creating + // a border effect. + // Disable writing to the depth mask so that the "border" cube will not + // occlude the main cube. This means the border could be covered by + // overlays that are further back and drawn later, but this is good + // enough for the use-case. glDepthMask(GL_FALSE); glPushMatrix(); glColor4f(1.0f, 1.0f, 1.0f, alpha);