From 46f6c9f8882a8943b5f85b845291060e1dc01d02 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 17 Mar 2015 09:06:31 -0700 Subject: [PATCH 01/53] Add WebWindow::setURL --- interface/src/scripting/WebWindowClass.cpp | 8 ++++++++ interface/src/scripting/WebWindowClass.h | 1 + 2 files changed, 9 insertions(+) diff --git a/interface/src/scripting/WebWindowClass.cpp b/interface/src/scripting/WebWindowClass.cpp index ae0e327cb1..01e5f07ca9 100644 --- a/interface/src/scripting/WebWindowClass.cpp +++ b/interface/src/scripting/WebWindowClass.cpp @@ -96,6 +96,14 @@ void WebWindowClass::setVisible(bool visible) { QMetaObject::invokeMethod(_windowWidget, "setVisible", Qt::BlockingQueuedConnection, Q_ARG(bool, visible)); } +void WebWindowClass::setURL(const QString& url) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "setURL", Qt::BlockingQueuedConnection, Q_ARG(QString, url)); + return; + } + _webView->setUrl(url); +} + QScriptValue WebWindowClass::constructor(QScriptContext* context, QScriptEngine* engine) { WebWindowClass* retVal; QString file = context->argument(0).toString(); diff --git a/interface/src/scripting/WebWindowClass.h b/interface/src/scripting/WebWindowClass.h index c923fdd748..08d9a42478 100644 --- a/interface/src/scripting/WebWindowClass.h +++ b/interface/src/scripting/WebWindowClass.h @@ -42,6 +42,7 @@ public: public slots: void setVisible(bool visible); + void setURL(const QString& url); ScriptEventBridge* getEventBridge() const { return _eventBridge; } void addEventBridgeToWindowObject(); From 8088b0135622487454df0f9a0b387718dad6ad28 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 17 Mar 2015 09:06:48 -0700 Subject: [PATCH 02/53] Add WebWindow::raise --- interface/src/scripting/WebWindowClass.cpp | 4 ++++ interface/src/scripting/WebWindowClass.h | 1 + 2 files changed, 5 insertions(+) diff --git a/interface/src/scripting/WebWindowClass.cpp b/interface/src/scripting/WebWindowClass.cpp index 01e5f07ca9..c3a3dada73 100644 --- a/interface/src/scripting/WebWindowClass.cpp +++ b/interface/src/scripting/WebWindowClass.cpp @@ -104,6 +104,10 @@ void WebWindowClass::setURL(const QString& url) { _webView->setUrl(url); } +void WebWindowClass::raise() { + QMetaObject::invokeMethod(_windowWidget, "raise", Qt::BlockingQueuedConnection); +} + QScriptValue WebWindowClass::constructor(QScriptContext* context, QScriptEngine* engine) { WebWindowClass* retVal; QString file = context->argument(0).toString(); diff --git a/interface/src/scripting/WebWindowClass.h b/interface/src/scripting/WebWindowClass.h index 08d9a42478..60732acf67 100644 --- a/interface/src/scripting/WebWindowClass.h +++ b/interface/src/scripting/WebWindowClass.h @@ -43,6 +43,7 @@ public: public slots: void setVisible(bool visible); void setURL(const QString& url); + void raise(); ScriptEventBridge* getEventBridge() const { return _eventBridge; } void addEventBridgeToWindowObject(); From 1e1c60847bf5d2f415eadde65f6f8c6753c1331f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 17 Mar 2015 09:07:01 -0700 Subject: [PATCH 03/53] Add WebWindow::getURL --- interface/src/scripting/WebWindowClass.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/scripting/WebWindowClass.h b/interface/src/scripting/WebWindowClass.h index 60732acf67..429b054966 100644 --- a/interface/src/scripting/WebWindowClass.h +++ b/interface/src/scripting/WebWindowClass.h @@ -34,6 +34,7 @@ signals: class WebWindowClass : public QObject { Q_OBJECT Q_PROPERTY(QObject* eventBridge READ getEventBridge) + Q_PROPERTY(QString url READ getURL) public: WebWindowClass(const QString& title, const QString& url, int width, int height, bool isToolWindow = false); ~WebWindowClass(); @@ -42,6 +43,7 @@ public: public slots: void setVisible(bool visible); + QString getURL() const { return _webView->url().url(); } void setURL(const QString& url); void raise(); ScriptEventBridge* getEventBridge() const { return _eventBridge; } From 66517fa1c0bb4f51a62e3f4991ff75092a846194 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 17 Mar 2015 09:07:33 -0700 Subject: [PATCH 04/53] Add ability to show marketplace url from edit properties --- examples/edit.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/edit.js b/examples/edit.js index 72938e5ed4..03137310b6 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -338,7 +338,11 @@ var toolBar = (function () { return true; } if (browseModelsButton === toolBar.clicked(clickedOverlay)) { + if (marketplaceWindow.url != MARKETPLACE_URL) { + marketplaceWindow.setURL(MARKETPLACE_URL); + } marketplaceWindow.setVisible(true); + marketplaceWindow.raise(); return true; } @@ -1143,6 +1147,10 @@ PropertiesTool = function(opts) { } pushCommandForSelections(); selectionManager._update(); + } else if (data.type = "showMarketplace") { + if (marketplaceWindow.url != data.url) { + marketplaceWindow.setURL(data.url); + } } else if (data.type == "action") { if (data.action == "moveSelectionToGrid") { if (selectionManager.hasSelection()) { From d097b4409e79dcba8b500fe655f293069606c7ce Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 17 Mar 2015 10:40:51 -0700 Subject: [PATCH 05/53] Add title to non-toolbar WebWindows --- interface/src/scripting/WebWindowClass.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/scripting/WebWindowClass.cpp b/interface/src/scripting/WebWindowClass.cpp index c3a3dada73..61b3ce225f 100644 --- a/interface/src/scripting/WebWindowClass.cpp +++ b/interface/src/scripting/WebWindowClass.cpp @@ -55,6 +55,7 @@ WebWindowClass::WebWindowClass(const QString& title, const QString& url, int wid _windowWidget = dockWidget; } else { _windowWidget = new QWidget(Application::getInstance()->getWindow(), Qt::Window); + _windowWidget->setWindowTitle(title); _windowWidget->setMinimumSize(width, height); auto layout = new QVBoxLayout(_windowWidget); From af789f842dabe3837777ebd85ebadc823d9712c8 Mon Sep 17 00:00:00 2001 From: Stojce Slavkovski Date: Tue, 17 Mar 2015 22:47:18 +0100 Subject: [PATCH 06/53] #20397 initial version of script --- examples/example/entities/makeHouses.js | 146 ++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 examples/example/entities/makeHouses.js diff --git a/examples/example/entities/makeHouses.js b/examples/example/entities/makeHouses.js new file mode 100644 index 0000000000..26224fd58a --- /dev/null +++ b/examples/example/entities/makeHouses.js @@ -0,0 +1,146 @@ +// +// makeHouses.js +// +// +// Created by Stojce Slavkovski on March 14, 2015 +// Copyright 2015 High Fidelity, Inc. +// +// This sample script that creates house entities based on parameters. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function () { + + /** options **/ + var numHouses = 100; + var xRange = 300; + var yRange = 300; + + var sizeOfTheHouse = { + x: 10, + y: 10, + z: 10 + }; + /**/ + + var modelUrl = "http://localhost/~stojce/models/3-Buildings-2-SanFranciscoHouse-"; + var modelurlExt = ".fbx"; + var modelVariations = 90; + var houses = []; + + function addHouseAt(position, rotation) { + // get random house model + var modelNumber = 1 + Math.floor(Math.random() * (modelVariations - 1)); + var modUrl = modelUrl + modelNumber + modelurlExt; + print("Model ID:" + modelNumber); + + var properties = { + type: "Model", + position: position, + rotation: rotation, + dimensions: sizeOfTheHouse, + modelURL: modUrl + }; + + return Entities.addEntity(properties); + } + + // calculate initial position + var posX = MyAvatar.position.x - (xRange / 2); + var measures = calculateParcels(numHouses, xRange, yRange); + var dd = 0; + + // avatar facing rotation + var rotEven = Quat.fromPitchYawRollDegrees(0, 270.0 + MyAvatar.bodyYaw, 0.0); + + // avatar opposite rotation + var rotOdd = Quat.fromPitchYawRollDegrees(0, 90.0 + MyAvatar.bodyYaw, 0.0); + var housePos = Vec3.sum(MyAvatar.position, Quat.getFront(Camera.getOrientation())); + + for (var j = 0; j < measures.rows; j++) { + + var posX1 = 0 - (xRange / 2); + dd += measures.parcelLength; + + for (var i = 0; i < measures.cols; i++) { + + // skip reminder of houses + if (houses.length > numHouses) { + break; + } + + var posShift = { + x: posX1, + y: 0, + z: dd + }; + + print("House nr.:" + houses.length + 1); + houses.push( + addHouseAt(Vec3.sum(housePos, posShift), (j % 2 == 0) ? rotEven : rotOdd) + ); + posX1 += measures.parcelWidth; + } + } + + // calculate rows and columns in area, and dimension of single parcel + function calculateParcels(items, areaWidth, areaLength) { + + var idealSize = Math.min(Math.sqrt(areaWidth * areaLength / items), areaWidth, areaLength); + + var baseWidth = Math.min(Math.floor(areaWidth / idealSize), items); + var baseLength = Math.min(Math.floor(areaLength / idealSize), items); + + var sirRows = baseWidth; + var sirCols = Math.ceil(items / sirRows); + var sirW = areaWidth / sirRows; + var sirL = areaLength / sirCols; + + var visCols = baseLength; + var visRows = Math.ceil(items / visCols); + var visW = areaWidth / visRows; + var visL = areaLength / visCols; + + var rows = 0; + var cols = 0; + var parcelWidth = 0; + var parcelLength = 0; + + if (Math.min(sirW, sirL) > Math.min(visW, visL)) { + rows = sirRows; + cols = sirCols; + parcelWidth = sirW; + parcelLength = sirL; + } else { + rows = visRows; + cols = visCols; + parcelWidth = visW; + parcelLength = visL; + } + + print("rows:" + rows); + print("cols:" + cols); + print("parcelWidth:" + parcelWidth); + print("parcelLength:" + parcelLength); + + return { + rows: rows, + cols: cols, + parcelWidth: parcelWidth, + parcelLength: parcelLength + }; + } + + function cleanup() { + while (houses.length > 0) { + if (!houses[0].isKnownID) { + houses[0] = Entities.identifyEntity(houses[0]); + } + Entities.deleteEntity(houses.shift()); + } + } + + Script.scriptEnding.connect(cleanup); +})(); \ No newline at end of file From 00f1d96af5060180a375a8cbf7b9deb35cbeeb79 Mon Sep 17 00:00:00 2001 From: Stojce Slavkovski Date: Wed, 18 Mar 2015 19:30:08 +0100 Subject: [PATCH 07/53] Use existing house models --- examples/example/entities/makeHouses.js | 33 ++++++++++++++++++------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/examples/example/entities/makeHouses.js b/examples/example/entities/makeHouses.js index 26224fd58a..12205db4ce 100644 --- a/examples/example/entities/makeHouses.js +++ b/examples/example/entities/makeHouses.js @@ -25,23 +25,38 @@ }; /**/ - var modelUrl = "http://localhost/~stojce/models/3-Buildings-2-SanFranciscoHouse-"; - var modelurlExt = ".fbx"; - var modelVariations = 90; + // + // var modelUrl = "http://localhost/~stojce/models/3-Buildings-2-SanFranciscoHouse-"; + // var modelurlExt = ".fbx"; + // var modelVariations = 100; + + var houseModels = [ + "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseBlue.fbx", + "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseBlue3.fbx", + "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseGreen.fbx", + "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseGreen2.fbx", + "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseRed.fbx", + "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseRose.fbx", + "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseViolet.fbx", + "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseYellow.fbx", + "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseYellow2.fbx" + ]; + var houses = []; function addHouseAt(position, rotation) { // get random house model - var modelNumber = 1 + Math.floor(Math.random() * (modelVariations - 1)); - var modUrl = modelUrl + modelNumber + modelurlExt; - print("Model ID:" + modelNumber); - + //var modelNumber = 1 + Math.floor(Math.random() * (modelVariations - 1)); + //var modelUrl = modelUrl + modelNumber + modelurlExt; + //print("Model ID:" + modelNumber); + var modelUrl = houseModels[Math.floor(Math.random() * houseModels.length)]; + var properties = { type: "Model", position: position, rotation: rotation, dimensions: sizeOfTheHouse, - modelURL: modUrl + modelURL: modelUrl }; return Entities.addEntity(properties); @@ -77,7 +92,7 @@ z: dd }; - print("House nr.:" + houses.length + 1); + print("House nr.:" + (houses.length + 1)); houses.push( addHouseAt(Vec3.sum(housePos, posShift), (j % 2 == 0) ? rotEven : rotOdd) ); From 57011c2d4bd1fc0f423b5069460ac2e003653f42 Mon Sep 17 00:00:00 2001 From: Stojce Slavkovski Date: Thu, 19 Mar 2015 20:55:18 +0100 Subject: [PATCH 08/53] get models from S3 --- examples/example/entities/makeHouses.js | 46 +++++++++++-------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/examples/example/entities/makeHouses.js b/examples/example/entities/makeHouses.js index 12205db4ce..37bc1d5a8e 100644 --- a/examples/example/entities/makeHouses.js +++ b/examples/example/entities/makeHouses.js @@ -20,36 +20,32 @@ var sizeOfTheHouse = { x: 10, - y: 10, + y: 15, z: 10 }; - /**/ - - // - // var modelUrl = "http://localhost/~stojce/models/3-Buildings-2-SanFranciscoHouse-"; - // var modelurlExt = ".fbx"; - // var modelVariations = 100; - var houseModels = [ - "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseBlue.fbx", - "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseBlue3.fbx", - "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseGreen.fbx", - "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseGreen2.fbx", - "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseRed.fbx", - "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseRose.fbx", - "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseViolet.fbx", - "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseYellow.fbx", - "http://public.highfidelity.io/models/entities/3-Buildings-2-SanFranciscoHouseYellow2.fbx" - ]; - + var randomizeModels = false; + /**/ + + var modelUrlPrefix = "http://public.highfidelity.io/load_testing/3-Buildings-2-SanFranciscoHouse-"; + var modelurlExt = ".fbx"; + var modelVariations = 100; + var houses = []; function addHouseAt(position, rotation) { - // get random house model - //var modelNumber = 1 + Math.floor(Math.random() * (modelVariations - 1)); - //var modelUrl = modelUrl + modelNumber + modelurlExt; - //print("Model ID:" + modelNumber); - var modelUrl = houseModels[Math.floor(Math.random() * houseModels.length)]; + // get house model + var modelNumber = randomizeModels ? + 1 + Math.floor(Math.random() * (modelVariations - 1)) : + (houses.length + 1) % modelVariations; + + if (modelNumber == 0) { + modelNumber = modelVariations; + } + + var modelUrl = modelUrlPrefix + (modelNumber + "") + modelurlExt; + print("Model ID:" + modelNumber); + print("Model URL:" + modelUrl); var properties = { type: "Model", @@ -158,4 +154,4 @@ } Script.scriptEnding.connect(cleanup); -})(); \ No newline at end of file +})(); From 6454149536921dee807cfce03388ba3a1bd85262 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 20 Mar 2015 12:45:29 -0700 Subject: [PATCH 09/53] formatting and comments --- libraries/physics/src/CharacterController.cpp | 25 +++++++++++++------ libraries/physics/src/CharacterController.h | 2 -- libraries/physics/src/PhysicsEngine.cpp | 4 ++- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index fb200b2c57..256c83357a 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -231,7 +231,6 @@ CharacterController::CharacterController(AvatarData* avatarData) { m_addedMargin = 0.02f; m_walkDirection.setValue(0.0f,0.0f,0.0f); - m_turnAngle = btScalar(0.0f); m_useWalkDirection = true; // use walk direction by default, legacy behavior m_velocityTimeInterval = 0.0f; m_verticalVelocity = 0.0f; @@ -797,19 +796,31 @@ void CharacterController::updateShape() { } void CharacterController::preSimulation(btScalar timeStep) { + bool wasEnabled = m_enabled; + + // lock avatarData, get everything we need from it ASAP, then unlock m_avatarData->lockForRead(); - - // cache the "PhysicsEnabled" state of m_avatarData here - // and use the cached value for the rest of the simulation step m_enabled = m_avatarData->isPhysicsEnabled(); - glm::quat rotation = m_avatarData->getOrientation(); glm::vec3 position = m_avatarData->getPosition() + rotation * m_shapeLocalOffset; - m_ghostObject->setWorldTransform(btTransform(glmToBullet(rotation), glmToBullet(position))); + // TODO: Andrew to implement: harvest jump event here btVector3 walkVelocity = glmToBullet(m_avatarData->getVelocity()); - setVelocityForTimeInterval(walkVelocity, timeStep); m_avatarData->unlock(); + + if (wasEnabled != m_enabled) { + if (m_enabled) { + // TODO: Andrew to implement: add collision shape back into world + } else { + // TODO: Andrew to implement: remove collision shape from world, + // otherwise things will continue to collide with it + } + } + + if (m_enabled) { + m_ghostObject->setWorldTransform(btTransform(glmToBullet(rotation), glmToBullet(position))); + setVelocityForTimeInterval(walkVelocity, timeStep); + } } void CharacterController::postSimulation() { diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index 7969fffd9d..b84662a389 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -58,8 +58,6 @@ protected: btScalar m_maxSlopeCosine; // Cosine equivalent of m_maxSlopeRadians (calculated once when set, for optimization) btScalar m_gravity; - btScalar m_turnAngle; - btScalar m_stepHeight; // height of stepUp prior to stepForward btScalar m_addedMargin;//@todo: remove this and fix the code diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index a46ba9f819..447a3ab6f1 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -294,16 +294,18 @@ void PhysicsEngine::stepSimulation() { _clock.reset(); float timeStep = btMin(dt, MAX_TIMESTEP); - // This is step (2). + // TODO: move character->preSimulation() into relayIncomingChanges if (_characterController) { _characterController->preSimulation(timeStep); } + // This is step (2). int numSubsteps = _dynamicsWorld->stepSimulation(timeStep, MAX_NUM_SUBSTEPS, PHYSICS_ENGINE_FIXED_SUBSTEP); _numSubsteps += (uint32_t)numSubsteps; stepNonPhysicalKinematics(usecTimestampNow()); unlock(); + // TODO: make all of this harvest stuff into one function: relayOutgoingChanges() if (numSubsteps > 0) { // This is step (3) which is done outside of stepSimulation() so we can lock _entityTree. // From 0164de80fe5d235d5a44d05489841b2df194dabc Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 20 Mar 2015 13:19:24 -0700 Subject: [PATCH 10/53] apply coding standard to CharacterController --- libraries/physics/src/CharacterController.cpp | 514 +++++++++--------- libraries/physics/src/CharacterController.h | 65 ++- 2 files changed, 285 insertions(+), 294 deletions(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 256c83357a..f7f8ab4d53 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -48,18 +48,18 @@ class btKinematicClosestNotMeRayResultCallback : public btCollisionWorld::Closes public: btKinematicClosestNotMeRayResultCallback(btCollisionObject* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) { -m_me = me; +_me = me; } virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) { -if (rayResult.m_collisionObject == m_me) +if (rayResult.m_collisionObject == _me) return 1.0; return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace); } protected: -btCollisionObject* m_me; +btCollisionObject* _me; }; */ @@ -67,14 +67,14 @@ class btKinematicClosestNotMeConvexResultCallback : public btCollisionWorld::Clo public: btKinematicClosestNotMeConvexResultCallback(btCollisionObject* me, const btVector3& up, btScalar minSlopeDot) : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) - , m_me(me) - , m_up(up) - , m_minSlopeDot(minSlopeDot) + , _me(me) + , _up(up) + , _minSlopeDot(minSlopeDot) { } virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult, bool normalInWorldSpace) { - if (convexResult.m_hitCollisionObject == m_me) { + if (convexResult.m_hitCollisionObject == _me) { return btScalar(1.0); } @@ -91,10 +91,10 @@ class btKinematicClosestNotMeConvexResultCallback : public btCollisionWorld::Clo } // Note: hitNormalWorld points into character, away from object - // and m_up points opposite to movement + // and _up points opposite to movement - btScalar dotUp = m_up.dot(hitNormalWorld); - if (dotUp < m_minSlopeDot) { + btScalar dotUp = _up.dot(hitNormalWorld); + if (dotUp < _minSlopeDot) { return btScalar(1.0); } @@ -102,9 +102,9 @@ class btKinematicClosestNotMeConvexResultCallback : public btCollisionWorld::Clo } protected: - btCollisionObject* m_me; - const btVector3 m_up; - btScalar m_minSlopeDot; + btCollisionObject* _me; + const btVector3 _up; + btScalar _minSlopeDot; }; class StepDownConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback { @@ -119,19 +119,19 @@ class StepDownConvexResultCallback : public btCollisionWorld::ClosestConvexResul btScalar radius, btScalar halfHeight) : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) - , m_me(me) - , m_up(up) - , m_start(start) - , m_step(step) - , m_pushDirection(pushDirection) - , m_minSlopeDot(minSlopeDot) - , m_radius(radius) - , m_halfHeight(halfHeight) + , _me(me) + , _up(up) + , _start(start) + , _step(step) + , _pushDirection(pushDirection) + , _minSlopeDot(minSlopeDot) + , _radius(radius) + , _halfHeight(halfHeight) { } virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult, bool normalInWorldSpace) { - if (convexResult.m_hitCollisionObject == m_me) { + if (convexResult.m_hitCollisionObject == _me) { return btScalar(1.0); } @@ -148,24 +148,24 @@ class StepDownConvexResultCallback : public btCollisionWorld::ClosestConvexResul } // Note: hitNormalWorld points into character, away from object - // and m_up points opposite to movement + // and _up points opposite to movement - btScalar dotUp = m_up.dot(hitNormalWorld); - if (dotUp < m_minSlopeDot) { - if (hitNormalWorld.dot(m_pushDirection) > 0.0f) { + btScalar dotUp = _up.dot(hitNormalWorld); + if (dotUp < _minSlopeDot) { + if (hitNormalWorld.dot(_pushDirection) > 0.0f) { // ignore hits that push in same direction as character is moving // which helps character NOT snag when stepping off ledges return btScalar(1.0f); } // compute the angle between "down" and the line from character center to "hit" point - btVector3 fractionalStep = convexResult.m_hitFraction * m_step; - btVector3 localHit = convexResult.m_hitPointLocal - m_start + fractionalStep; - btScalar angle = localHit.angle(-m_up); + btVector3 fractionalStep = convexResult.m_hitFraction * _step; + btVector3 localHit = convexResult.m_hitPointLocal - _start + fractionalStep; + btScalar angle = localHit.angle(-_up); - // compute a maxAngle based on size of m_step - btVector3 side(m_radius, - (m_halfHeight - m_step.length() + fractionalStep.dot(m_up)), 0.0f); - btScalar maxAngle = side.angle(-m_up); + // compute a maxAngle based on size of _step + btVector3 side(_radius, - (_halfHeight - _step.length() + fractionalStep.dot(_up)), 0.0f); + btScalar maxAngle = side.angle(-_up); // Ignore hits that are larger than maxAngle. Effectively what is happening here is: // we're ignoring hits at contacts that have non-vertical normals... if they hit higher @@ -182,14 +182,14 @@ class StepDownConvexResultCallback : public btCollisionWorld::ClosestConvexResul } protected: - btCollisionObject* m_me; - const btVector3 m_up; - btVector3 m_start; - btVector3 m_step; - btVector3 m_pushDirection; - btScalar m_minSlopeDot; - btScalar m_radius; - btScalar m_halfHeight; + btCollisionObject* _me; + const btVector3 _up; + btVector3 _start; + btVector3 _step; + btVector3 _pushDirection; + btScalar _minSlopeDot; + btScalar _radius; + btScalar _halfHeight; }; /* @@ -218,42 +218,37 @@ btVector3 CharacterController::perpindicularComponent(const btVector3& direction CharacterController::CharacterController(AvatarData* avatarData) { assert(avatarData); - m_avatarData = avatarData; + _avatarData = avatarData; - // cache the "PhysicsEnabled" state of m_avatarData - m_avatarData->lockForRead(); - m_enabled = m_avatarData->isPhysicsEnabled(); - m_avatarData->unlock(); + // cache the "PhysicsEnabled" state of _avatarData + _avatarData->lockForRead(); + _enabled = _avatarData->isPhysicsEnabled(); + _avatarData->unlock(); createShapeAndGhost(); - m_upAxis = 1; // HACK: hard coded to be 1 for now (yAxis) + _upAxis = 1; // HACK: hard coded to be 1 for now (yAxis) - m_addedMargin = 0.02f; - m_walkDirection.setValue(0.0f,0.0f,0.0f); - m_useWalkDirection = true; // use walk direction by default, legacy behavior - m_velocityTimeInterval = 0.0f; - m_verticalVelocity = 0.0f; - m_verticalOffset = 0.0f; - m_gravity = 9.8f; - m_maxFallSpeed = 55.0f; // Terminal velocity of a sky diver in m/s. - m_jumpSpeed = 10.0f; // ? - m_wasOnGround = false; - m_wasJumping = false; - m_interpolateUp = true; + _addedMargin = 0.02f; + _walkDirection.setValue(0.0f,0.0f,0.0f); + _useWalkDirection = true; // use walk direction by default, legacy behavior + _velocityTimeInterval = 0.0f; + _verticalVelocity = 0.0f; + _verticalOffset = 0.0f; + _gravity = 9.8f; + _maxFallSpeed = 55.0f; // Terminal velocity of a sky diver in m/s. + _jumpSpeed = 10.0f; // ? + _wasOnGround = false; + _wasJumping = false; setMaxSlope(btRadians(45.0f)); - m_lastStepUp = 0.0f; - - // internal state data members - full_drop = false; - bounce_fix = false; + _lastStepUp = 0.0f; } CharacterController::~CharacterController() { } btPairCachingGhostObject* CharacterController::getGhostObject() { - return m_ghostObject; + return _ghostObject; } bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorld) { @@ -266,26 +261,26 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl // paircache and the ghostobject's internal paircache at the same time. /BW btVector3 minAabb, maxAabb; - m_convexShape->getAabb(m_ghostObject->getWorldTransform(), minAabb, maxAabb); - collisionWorld->getBroadphase()->setAabb(m_ghostObject->getBroadphaseHandle(), + _convexShape->getAabb(_ghostObject->getWorldTransform(), minAabb, maxAabb); + collisionWorld->getBroadphase()->setAabb(_ghostObject->getBroadphaseHandle(), minAabb, maxAabb, collisionWorld->getDispatcher()); bool penetration = false; - collisionWorld->getDispatcher()->dispatchAllCollisionPairs(m_ghostObject->getOverlappingPairCache(), collisionWorld->getDispatchInfo(), collisionWorld->getDispatcher()); + collisionWorld->getDispatcher()->dispatchAllCollisionPairs(_ghostObject->getOverlappingPairCache(), collisionWorld->getDispatchInfo(), collisionWorld->getDispatcher()); - m_currentPosition = m_ghostObject->getWorldTransform().getOrigin(); - btVector3 up = getUpAxisDirections()[m_upAxis]; + _currentPosition = _ghostObject->getWorldTransform().getOrigin(); + btVector3 up = getUpAxisDirections()[_upAxis]; - btVector3 currentPosition = m_currentPosition; + btVector3 currentPosition = _currentPosition; btScalar maxPen = btScalar(0.0); - for (int i = 0; i < m_ghostObject->getOverlappingPairCache()->getNumOverlappingPairs(); i++) { - m_manifoldArray.resize(0); + for (int i = 0; i < _ghostObject->getOverlappingPairCache()->getNumOverlappingPairs(); i++) { + _manifoldArray.resize(0); - btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i]; + btBroadphasePair* collisionPair = &_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i]; btCollisionObject* obj0 = static_cast(collisionPair->m_pProxy0->m_clientObject); btCollisionObject* obj1 = static_cast(collisionPair->m_pProxy1->m_clientObject); @@ -295,12 +290,12 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl } if (collisionPair->m_algorithm) { - collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray); + collisionPair->m_algorithm->getAllContactManifolds(_manifoldArray); } - for (int j = 0;j < m_manifoldArray.size(); j++) { - btPersistentManifold* manifold = m_manifoldArray[j]; - btScalar directionSign = (manifold->getBody0() == m_ghostObject) ? btScalar(1.0) : btScalar(-1.0); + for (int j = 0;j < _manifoldArray.size(); j++) { + btPersistentManifold* manifold = _manifoldArray[j]; + btScalar directionSign = (manifold->getBody0() == _ghostObject) ? btScalar(1.0) : btScalar(-1.0); for (int p = 0;p < manifold->getNumContacts(); p++) { const btManifoldPoint&pt = manifold->getContactPoint(p); @@ -312,7 +307,7 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl normal *= directionSign; // always points from object to character btScalar normalDotUp = normal.dot(up); - if (normalDotUp < m_maxSlopeCosine) { + if (normalDotUp < _maxSlopeCosine) { // this contact has a non-vertical normal... might need to ignored btVector3 collisionPoint; if (directionSign > 0.0) { @@ -322,11 +317,11 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl } // we do math in frame where character base is origin - btVector3 characterBase = currentPosition - (m_radius + m_halfHeight) * up; + btVector3 characterBase = currentPosition - (_radius + _halfHeight) * up; collisionPoint -= characterBase; btScalar collisionHeight = collisionPoint.dot(up); - if (collisionHeight < m_lastStepUp) { + if (collisionHeight < _lastStepUp) { // This contact is below the lastStepUp, so we ignore it for penetration resolution, // otherwise it may prevent the character from getting close enough to find any available // horizontal foothold that would allow it to climbe the ledge. In other words, we're @@ -338,19 +333,19 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl if (dist < maxPen) { maxPen = dist; - m_floorNormal = normal; + _floorNormal = normal; } const btScalar INCREMENTAL_RESOLUTION_FACTOR = 0.2f; - m_currentPosition += normal * (fabsf(dist) * INCREMENTAL_RESOLUTION_FACTOR); + _currentPosition += normal * (fabsf(dist) * INCREMENTAL_RESOLUTION_FACTOR); penetration = true; } } } } } - btTransform newTrans = m_ghostObject->getWorldTransform(); - newTrans.setOrigin(m_currentPosition); - m_ghostObject->setWorldTransform(newTrans); + btTransform newTrans = _ghostObject->getWorldTransform(); + newTrans.setOrigin(_currentPosition); + _ghostObject->setWorldTransform(newTrans); return penetration; } @@ -360,45 +355,40 @@ void CharacterController::stepUp( btCollisionWorld* world) { // compute start and end btTransform start, end; start.setIdentity(); - start.setOrigin(m_currentPosition + getUpAxisDirections()[m_upAxis] * (m_convexShape->getMargin() + m_addedMargin)); + start.setOrigin(_currentPosition + getUpAxisDirections()[_upAxis] * (_convexShape->getMargin() + _addedMargin)); - //m_targetPosition = m_currentPosition + getUpAxisDirections()[m_upAxis] * (m_stepHeight + (m_verticalOffset > 0.0f ? m_verticalOffset : 0.0f)); - m_targetPosition = m_currentPosition + getUpAxisDirections()[m_upAxis] * m_stepHeight; + _targetPosition = _currentPosition + getUpAxisDirections()[_upAxis] * _stepHeight; end.setIdentity(); - end.setOrigin(m_targetPosition); + end.setOrigin(_targetPosition); // sweep up - btVector3 sweepDirNegative = -getUpAxisDirections()[m_upAxis]; - btKinematicClosestNotMeConvexResultCallback callback(m_ghostObject, sweepDirNegative, btScalar(0.7071)); + btVector3 sweepDirNegative = -getUpAxisDirections()[_upAxis]; + btKinematicClosestNotMeConvexResultCallback callback(_ghostObject, sweepDirNegative, btScalar(0.7071)); callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; - m_ghostObject->convexSweepTest(m_convexShape, start, end, callback, world->getDispatchInfo().m_allowedCcdPenetration); + _ghostObject->convexSweepTest(_convexShape, start, end, callback, world->getDispatchInfo().m_allowedCcdPenetration); if (callback.hasHit()) { // we hit something, so zero our vertical velocity - m_verticalVelocity = 0.0; - m_verticalOffset = 0.0; + _verticalVelocity = 0.0; + _verticalOffset = 0.0; // Only modify the position if the hit was a slope and not a wall or ceiling. - if (callback.m_hitNormalWorld.dot(getUpAxisDirections()[m_upAxis]) > 0.0) { - m_lastStepUp = m_stepHeight * callback.m_closestHitFraction; - if (m_interpolateUp == true) { - m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction); - } else { - m_currentPosition = m_targetPosition; - } + if (callback.m_hitNormalWorld.dot(getUpAxisDirections()[_upAxis]) > 0.0) { + _lastStepUp = _stepHeight * callback.m_closestHitFraction; + _currentPosition.setInterpolate3(_currentPosition, _targetPosition, callback.m_closestHitFraction); } else { - m_lastStepUp = m_stepHeight; - m_currentPosition = m_targetPosition; + _lastStepUp = _stepHeight; + _currentPosition = _targetPosition; } } else { - m_currentPosition = m_targetPosition; - m_lastStepUp = m_stepHeight; + _currentPosition = _targetPosition; + _lastStepUp = _stepHeight; } } void CharacterController::updateTargetPositionBasedOnCollision(const btVector3& hitNormal, btScalar tangentMag, btScalar normalMag) { - btVector3 movementDirection = m_targetPosition - m_currentPosition; + btVector3 movementDirection = _targetPosition - _currentPosition; btScalar movementLength = movementDirection.length(); if (movementLength > SIMD_EPSILON) { movementDirection.normalize(); @@ -411,74 +401,74 @@ void CharacterController::updateTargetPositionBasedOnCollision(const btVector3& parallelDir = parallelComponent(reflectDir, hitNormal); perpindicularDir = perpindicularComponent(reflectDir, hitNormal); - m_targetPosition = m_currentPosition; + _targetPosition = _currentPosition; //if (tangentMag != 0.0) { if (0) { btVector3 parComponent = parallelDir * btScalar(tangentMag * movementLength); - m_targetPosition += parComponent; + _targetPosition += parComponent; } if (normalMag != 0.0) { btVector3 perpComponent = perpindicularDir * btScalar(normalMag * movementLength); - m_targetPosition += perpComponent; + _targetPosition += perpComponent; } } } void CharacterController::stepForward( btCollisionWorld* collisionWorld, const btVector3& movement) { // phase 2: forward - m_targetPosition = m_currentPosition + movement; + _targetPosition = _currentPosition + movement; btTransform start, end; start.setIdentity(); end.setIdentity(); /* TODO: experiment with this to see if we can use this to help direct motion when a floor is available - if (m_touchingContact) { - if (m_normalizedDirection.dot(m_floorNormal) < btScalar(0.0)) { - updateTargetPositionBasedOnCollision(m_floorNormal, 1.0f, 1.0f); + if (_touchingContact) { + if (_normalizedDirection.dot(_floorNormal) < btScalar(0.0)) { + updateTargetPositionBasedOnCollision(_floorNormal, 1.0f, 1.0f); } }*/ // modify shape's margin for the sweeps - btScalar margin = m_convexShape->getMargin(); - m_convexShape->setMargin(margin + m_addedMargin); + btScalar margin = _convexShape->getMargin(); + _convexShape->setMargin(margin + _addedMargin); const btScalar MIN_STEP_DISTANCE = 0.0001f; - btVector3 step = m_targetPosition - m_currentPosition; + btVector3 step = _targetPosition - _currentPosition; btScalar stepLength2 = step.length2(); int maxIter = 10; while (stepLength2 > MIN_STEP_DISTANCE && maxIter-- > 0) { - start.setOrigin(m_currentPosition); - end.setOrigin(m_targetPosition); + start.setOrigin(_currentPosition); + end.setOrigin(_targetPosition); // sweep forward - btVector3 sweepDirNegative(m_currentPosition - m_targetPosition); - btKinematicClosestNotMeConvexResultCallback callback(m_ghostObject, sweepDirNegative, btScalar(0.0)); + btVector3 sweepDirNegative(_currentPosition - _targetPosition); + btKinematicClosestNotMeConvexResultCallback callback(_ghostObject, sweepDirNegative, btScalar(0.0)); callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; - m_ghostObject->convexSweepTest(m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); + _ghostObject->convexSweepTest(_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); if (callback.hasHit()) { // we hit soemthing! // Compute new target position by removing portion cut-off by collision, which will produce a new target // that is the closest approach of the the obstacle plane to the original target. - step = m_targetPosition - m_currentPosition; + step = _targetPosition - _currentPosition; btScalar stepDotNormal = step.dot(callback.m_hitNormalWorld); // we expect this dot to be negative step += (stepDotNormal * (1.0f - callback.m_closestHitFraction)) * callback.m_hitNormalWorld; - m_targetPosition = m_currentPosition + step; + _targetPosition = _currentPosition + step; stepLength2 = step.length2(); } else { // we swept to the end without hitting anything - m_currentPosition = m_targetPosition; + _currentPosition = _targetPosition; break; } } // restore shape's margin - m_convexShape->setMargin(margin); + _convexShape->setMargin(margin); } void CharacterController::stepDown( btCollisionWorld* collisionWorld, btScalar dt) { @@ -488,20 +478,20 @@ void CharacterController::stepDown( btCollisionWorld* collisionWorld, btScalar d // If it hits a ledge then it stops otherwise it makes another sweep down in search of a floor within // reach of the character's feet. - btScalar downSpeed = (m_verticalVelocity < 0.0f) ? -m_verticalVelocity : 0.0f; - if (downSpeed > 0.0f && downSpeed > m_maxFallSpeed && (m_wasOnGround || !m_wasJumping)) { - downSpeed = m_maxFallSpeed; + btScalar downSpeed = (_verticalVelocity < 0.0f) ? -_verticalVelocity : 0.0f; + if (downSpeed > 0.0f && downSpeed > _maxFallSpeed && (_wasOnGround || !_wasJumping)) { + downSpeed = _maxFallSpeed; } // first sweep for ledge - btVector3 step = getUpAxisDirections()[m_upAxis] * (-(m_lastStepUp + downSpeed * dt)); + btVector3 step = getUpAxisDirections()[_upAxis] * (-(_lastStepUp + downSpeed * dt)); - StepDownConvexResultCallback callback(m_ghostObject, - getUpAxisDirections()[m_upAxis], - m_currentPosition, step, - m_walkDirection, - m_maxSlopeCosine, - m_radius, m_halfHeight); + StepDownConvexResultCallback callback(_ghostObject, + getUpAxisDirections()[_upAxis], + _currentPosition, step, + _walkDirection, + _maxSlopeCosine, + _radius, _halfHeight); callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; @@ -509,75 +499,77 @@ void CharacterController::stepDown( btCollisionWorld* collisionWorld, btScalar d start.setIdentity(); end.setIdentity(); - start.setOrigin(m_currentPosition); - m_targetPosition = m_currentPosition + step; - end.setOrigin(m_targetPosition); - m_ghostObject->convexSweepTest(m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); + start.setOrigin(_currentPosition); + _targetPosition = _currentPosition + step; + end.setOrigin(_targetPosition); + _ghostObject->convexSweepTest(_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); if (callback.hasHit()) { - m_currentPosition += callback.m_closestHitFraction * step; - m_verticalVelocity = 0.0f; - m_verticalOffset = 0.0f; - m_wasJumping = false; + _currentPosition += callback.m_closestHitFraction * step; + _verticalVelocity = 0.0f; + _verticalOffset = 0.0f; + _wasJumping = false; } else { // sweep again for floor within downStep threshold - StepDownConvexResultCallback callback2 (m_ghostObject, - getUpAxisDirections()[m_upAxis], - m_currentPosition, step, - m_walkDirection, - m_maxSlopeCosine, - m_radius, m_halfHeight); + StepDownConvexResultCallback callback2 (_ghostObject, + getUpAxisDirections()[_upAxis], + _currentPosition, step, + _walkDirection, + _maxSlopeCosine, + _radius, _halfHeight); callback2.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback2.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; - m_currentPosition = m_targetPosition; - btVector3 oldPosition = m_currentPosition; - step = (- m_stepHeight) * getUpAxisDirections()[m_upAxis]; - m_targetPosition = m_currentPosition + step; + _currentPosition = _targetPosition; + btVector3 oldPosition = _currentPosition; + step = (- _stepHeight) * getUpAxisDirections()[_upAxis]; + _targetPosition = _currentPosition + step; - start.setOrigin(m_currentPosition); - end.setOrigin(m_targetPosition); - m_ghostObject->convexSweepTest(m_convexShape, start, end, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); + start.setOrigin(_currentPosition); + end.setOrigin(_targetPosition); + _ghostObject->convexSweepTest(_convexShape, start, end, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); if (callback2.hasHit()) { - m_currentPosition += callback2.m_closestHitFraction * step; - m_verticalVelocity = 0.0f; - m_verticalOffset = 0.0f; - m_wasJumping = false; + _currentPosition += callback2.m_closestHitFraction * step; + _verticalVelocity = 0.0f; + _verticalOffset = 0.0f; + _wasJumping = false; } else { // nothing to step down on, so remove the stepUp effect - m_currentPosition = oldPosition - m_lastStepUp * getUpAxisDirections()[m_upAxis]; - m_lastStepUp = 0.0f; + _currentPosition = oldPosition - _lastStepUp * getUpAxisDirections()[_upAxis]; + _lastStepUp = 0.0f; } } } void CharacterController::setWalkDirection(const btVector3& walkDirection) { - m_useWalkDirection = true; - m_walkDirection = walkDirection; - m_normalizedDirection = getNormalizedVector(m_walkDirection); + _useWalkDirection = true; + _walkDirection = walkDirection; + _normalizedDirection = getNormalizedVector(_walkDirection); } void CharacterController::setVelocityForTimeInterval(const btVector3& velocity, btScalar timeInterval) { - m_useWalkDirection = false; - m_walkDirection = velocity; - m_normalizedDirection = getNormalizedVector(m_walkDirection); - m_velocityTimeInterval += timeInterval; + _useWalkDirection = false; + _walkDirection = velocity; + _normalizedDirection = getNormalizedVector(_walkDirection); + _velocityTimeInterval += timeInterval; } void CharacterController::reset( btCollisionWorld* collisionWorld ) { - m_verticalVelocity = 0.0; - m_verticalOffset = 0.0; - m_wasOnGround = false; - m_wasJumping = false; - m_walkDirection.setValue(0,0,0); - m_velocityTimeInterval = 0.0; + _verticalVelocity = 0.0; + _verticalOffset = 0.0; + _wasOnGround = false; + _wasJumping = false; + _walkDirection.setValue(0,0,0); + _velocityTimeInterval = 0.0; //clear pair cache - btHashedOverlappingPairCache *cache = m_ghostObject->getOverlappingPairCache(); + btHashedOverlappingPairCache *cache = _ghostObject->getOverlappingPairCache(); while (cache->getOverlappingPairArray().size() > 0) { - cache->removeOverlappingPair(cache->getOverlappingPairArray()[0].m_pProxy0, cache->getOverlappingPairArray()[0].m_pProxy1, collisionWorld->getDispatcher()); + cache->removeOverlappingPair(cache->getOverlappingPairArray()[0].m_pProxy0, + cache->getOverlappingPairArray()[0].m_pProxy1, + collisionWorld->getDispatcher()); } } @@ -585,46 +577,46 @@ void CharacterController::warp(const btVector3& origin) { btTransform xform; xform.setIdentity(); xform.setOrigin(origin); - m_ghostObject->setWorldTransform(xform); + _ghostObject->setWorldTransform(xform); } void CharacterController::preStep( btCollisionWorld* collisionWorld) { - if (!m_enabled) { + if (!_enabled) { return; } int numPenetrationLoops = 0; - m_touchingContact = false; + _touchingContact = false; while (recoverFromPenetration(collisionWorld)) { numPenetrationLoops++; - m_touchingContact = true; + _touchingContact = true; if (numPenetrationLoops > 4) { break; } } - m_currentPosition = m_ghostObject->getWorldTransform().getOrigin(); - m_targetPosition = m_currentPosition; + _currentPosition = _ghostObject->getWorldTransform().getOrigin(); + _targetPosition = _currentPosition; } void CharacterController::playerStep( btCollisionWorld* collisionWorld, btScalar dt) { - if (!m_enabled || (!m_useWalkDirection && m_velocityTimeInterval <= 0.0)) { + if (!_enabled || (!_useWalkDirection && _velocityTimeInterval <= 0.0)) { return; // no motion } - m_wasOnGround = onGround(); + _wasOnGround = onGround(); // Update fall velocity. - m_verticalVelocity -= m_gravity * dt; - if (m_verticalVelocity > m_jumpSpeed) { - m_verticalVelocity = m_jumpSpeed; - } else if (m_verticalVelocity < -m_maxFallSpeed) { - m_verticalVelocity = -m_maxFallSpeed; + _verticalVelocity -= _gravity * dt; + if (_verticalVelocity > _jumpSpeed) { + _verticalVelocity = _jumpSpeed; + } else if (_verticalVelocity < -_maxFallSpeed) { + _verticalVelocity = -_maxFallSpeed; } - m_verticalOffset = m_verticalVelocity * dt; + _verticalOffset = _verticalVelocity * dt; btTransform xform; - xform = m_ghostObject->getWorldTransform(); + xform = _ghostObject->getWorldTransform(); // the algorithm is as follows: // (1) step the character up a little bit so that its forward step doesn't hit the floor @@ -632,33 +624,33 @@ void CharacterController::playerStep( btCollisionWorld* collisionWorld, btScala // (3) step the character down looking for new ledges, the original floor, or a floor one step below where we started stepUp(collisionWorld); - if (m_useWalkDirection) { - stepForward(collisionWorld, m_walkDirection); + if (_useWalkDirection) { + stepForward(collisionWorld, _walkDirection); } else { // compute substep and decrement total interval - btScalar dtMoving = (dt < m_velocityTimeInterval) ? dt : m_velocityTimeInterval; - m_velocityTimeInterval -= dt; + btScalar dtMoving = (dt < _velocityTimeInterval) ? dt : _velocityTimeInterval; + _velocityTimeInterval -= dt; // stepForward substep - btVector3 move = m_walkDirection * dtMoving; + btVector3 move = _walkDirection * dtMoving; stepForward(collisionWorld, move); } stepDown(collisionWorld, dt); - xform.setOrigin(m_currentPosition); - m_ghostObject->setWorldTransform(xform); + xform.setOrigin(_currentPosition); + _ghostObject->setWorldTransform(xform); } void CharacterController::setMaxFallSpeed(btScalar speed) { - m_maxFallSpeed = speed; + _maxFallSpeed = speed; } void CharacterController::setJumpSpeed(btScalar jumpSpeed) { - m_jumpSpeed = jumpSpeed; + _jumpSpeed = jumpSpeed; } void CharacterController::setMaxJumpHeight(btScalar maxJumpHeight) { - m_maxJumpHeight = maxJumpHeight; + _maxJumpHeight = maxJumpHeight; } bool CharacterController::canJump() const { @@ -670,39 +662,39 @@ void CharacterController::jump() { return; } - m_verticalVelocity = m_jumpSpeed; - m_wasJumping = true; + _verticalVelocity = _jumpSpeed; + _wasJumping = true; #if 0 currently no jumping. btTransform xform; - m_rigidBody->getMotionState()->getWorldTransform(xform); + _rigidBody->getMotionState()->getWorldTransform(xform); btVector3 up = xform.getBasis()[1]; up.normalize(); - btScalar magnitude = (btScalar(1.0)/m_rigidBody->getInvMass()) * btScalar(8.0); - m_rigidBody->applyCentralImpulse (up * magnitude); + btScalar magnitude = (btScalar(1.0)/_rigidBody->getInvMass()) * btScalar(8.0); + _rigidBody->applyCentralImpulse (up * magnitude); #endif } void CharacterController::setGravity(btScalar gravity) { - m_gravity = gravity; + _gravity = gravity; } btScalar CharacterController::getGravity() const { - return m_gravity; + return _gravity; } void CharacterController::setMaxSlope(btScalar slopeRadians) { - m_maxSlopeRadians = slopeRadians; - m_maxSlopeCosine = btCos(slopeRadians); + _maxSlopeRadians = slopeRadians; + _maxSlopeCosine = btCos(slopeRadians); } btScalar CharacterController::getMaxSlope() const { - return m_maxSlopeRadians; + return _maxSlopeRadians; } bool CharacterController::onGround() const { - return m_enabled && m_verticalVelocity == 0.0 && m_verticalOffset == 0.0; + return _enabled && _verticalVelocity == 0.0 && _verticalOffset == 0.0; } btVector3* CharacterController::getUpAxisDirections() { @@ -715,48 +707,50 @@ void CharacterController::debugDraw(btIDebugDraw* debugDrawer) { } void CharacterController::setUpInterpolate(bool value) { - m_interpolateUp = value; + // This method is required by btCharacterControllerInterface, but it does nothing. + // What it used to do was determine whether stepUp() would: stop where it hit the ceiling + // (interpolate = true, and now default behavior) or happily penetrate objects above the avatar. } // protected void CharacterController::createShapeAndGhost() { // get new dimensions from avatar - m_avatarData->lockForRead(); - AABox box = m_avatarData->getLocalAABox(); + _avatarData->lockForRead(); + AABox box = _avatarData->getLocalAABox(); // create new ghost - m_ghostObject = new btPairCachingGhostObject(); - m_ghostObject->setWorldTransform(btTransform(glmToBullet(m_avatarData->getOrientation()), - glmToBullet(m_avatarData->getPosition()))); - m_avatarData->unlock(); + _ghostObject = new btPairCachingGhostObject(); + _ghostObject->setWorldTransform(btTransform(glmToBullet(_avatarData->getOrientation()), + glmToBullet(_avatarData->getPosition()))); + _avatarData->unlock(); const glm::vec3& diagonal = box.getScale(); - m_radius = 0.5f * sqrtf(0.5f * (diagonal.x * diagonal.x + diagonal.z * diagonal.z)); - m_halfHeight = 0.5f * diagonal.y - m_radius; + _radius = 0.5f * sqrtf(0.5f * (diagonal.x * diagonal.x + diagonal.z * diagonal.z)); + _halfHeight = 0.5f * diagonal.y - _radius; float MIN_HALF_HEIGHT = 0.1f; - if (m_halfHeight < MIN_HALF_HEIGHT) { - m_halfHeight = MIN_HALF_HEIGHT; + if (_halfHeight < MIN_HALF_HEIGHT) { + _halfHeight = MIN_HALF_HEIGHT; } glm::vec3 offset = box.getCorner() + 0.5f * diagonal; - m_shapeLocalOffset = offset; + _shapeLocalOffset = offset; // stepHeight affects the heights of ledges that the character can ascend - // however the actual ledge height is some function of m_stepHeight + // however the actual ledge height is some function of _stepHeight // due to character shape and this CharacterController algorithm - // (the function is approximately 2*m_stepHeight) - m_stepHeight = 0.1f * (m_radius + m_halfHeight) + 0.1f; + // (the function is approximately 2*_stepHeight) + _stepHeight = 0.1f * (_radius + _halfHeight) + 0.1f; // create new shape - m_convexShape = new btCapsuleShape(m_radius, 2.0f * m_halfHeight); - m_ghostObject->setCollisionShape(m_convexShape); - m_ghostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT); + _convexShape = new btCapsuleShape(_radius, 2.0f * _halfHeight); + _ghostObject->setCollisionShape(_convexShape); + _ghostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT); } bool CharacterController::needsShapeUpdate() { // get new dimensions from avatar - m_avatarData->lockForRead(); - AABox box = m_avatarData->getLocalAABox(); - m_avatarData->unlock(); + _avatarData->lockForRead(); + AABox box = _avatarData->getLocalAABox(); + _avatarData->unlock(); const glm::vec3& diagonal = box.getScale(); float radius = 0.5f * sqrtf(0.5f * (diagonal.x * diagonal.x + diagonal.z * diagonal.z)); @@ -768,14 +762,14 @@ bool CharacterController::needsShapeUpdate() { glm::vec3 offset = box.getCorner() + 0.5f * diagonal; // compare dimensions (and offset) - float radiusDelta = glm::abs(radius - m_radius); - float heightDelta = glm::abs(halfHeight - m_halfHeight); + float radiusDelta = glm::abs(radius - _radius); + float heightDelta = glm::abs(halfHeight - _halfHeight); if (radiusDelta < FLT_EPSILON && heightDelta < FLT_EPSILON) { // shape hasn't changed --> nothing to do - float offsetDelta = glm::distance(offset, m_shapeLocalOffset); + float offsetDelta = glm::distance(offset, _shapeLocalOffset); if (offsetDelta > FLT_EPSILON) { // if only the offset changes then we can update it --> no need to rebuild shape - m_shapeLocalOffset = offset; + _shapeLocalOffset = offset; } return false; } @@ -787,29 +781,29 @@ void CharacterController::updateShape() { // the PhysicsEngine before calling this. // delete shape and GhostObject - delete m_ghostObject; - m_ghostObject = NULL; - delete m_convexShape; - m_convexShape = NULL; + delete _ghostObject; + _ghostObject = NULL; + delete _convexShape; + _convexShape = NULL; createShapeAndGhost(); } void CharacterController::preSimulation(btScalar timeStep) { - bool wasEnabled = m_enabled; + bool wasEnabled = _enabled; // lock avatarData, get everything we need from it ASAP, then unlock - m_avatarData->lockForRead(); - m_enabled = m_avatarData->isPhysicsEnabled(); - glm::quat rotation = m_avatarData->getOrientation(); - glm::vec3 position = m_avatarData->getPosition() + rotation * m_shapeLocalOffset; + _avatarData->lockForRead(); + _enabled = _avatarData->isPhysicsEnabled(); + glm::quat rotation = _avatarData->getOrientation(); + glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset; // TODO: Andrew to implement: harvest jump event here - btVector3 walkVelocity = glmToBullet(m_avatarData->getVelocity()); + btVector3 walkVelocity = glmToBullet(_avatarData->getVelocity()); - m_avatarData->unlock(); + _avatarData->unlock(); - if (wasEnabled != m_enabled) { - if (m_enabled) { + if (wasEnabled != _enabled) { + if (_enabled) { // TODO: Andrew to implement: add collision shape back into world } else { // TODO: Andrew to implement: remove collision shape from world, @@ -817,21 +811,21 @@ void CharacterController::preSimulation(btScalar timeStep) { } } - if (m_enabled) { - m_ghostObject->setWorldTransform(btTransform(glmToBullet(rotation), glmToBullet(position))); + if (_enabled) { + _ghostObject->setWorldTransform(btTransform(glmToBullet(rotation), glmToBullet(position))); setVelocityForTimeInterval(walkVelocity, timeStep); } } void CharacterController::postSimulation() { - if (m_enabled) { - m_avatarData->lockForWrite(); - const btTransform& avatarTransform = m_ghostObject->getWorldTransform(); + if (_enabled) { + _avatarData->lockForWrite(); + const btTransform& avatarTransform = _ghostObject->getWorldTransform(); glm::quat rotation = bulletToGLM(avatarTransform.getRotation()); - glm::vec3 offset = rotation * m_shapeLocalOffset; - m_avatarData->setOrientation(rotation); - m_avatarData->setPosition(bulletToGLM(avatarTransform.getOrigin()) - offset); - m_avatarData->unlock(); + glm::vec3 offset = rotation * _shapeLocalOffset; + _avatarData->setOrientation(rotation); + _avatarData->setPosition(bulletToGLM(avatarTransform.getOrigin()) - offset); + _avatarData->unlock(); } } diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index b84662a389..23c338412c 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -41,53 +41,50 @@ ATTRIBUTE_ALIGNED16(class) CharacterController : public btCharacterControllerInt { protected: - AvatarData* m_avatarData = NULL; - btPairCachingGhostObject* m_ghostObject; - glm::vec3 m_shapeLocalOffset; + AvatarData* _avatarData = NULL; + btPairCachingGhostObject* _ghostObject; + glm::vec3 _shapeLocalOffset; - btConvexShape* m_convexShape;//is also in m_ghostObject, but it needs to be convex, so we store it here to avoid upcast - btScalar m_radius; - btScalar m_halfHeight; + btConvexShape* _convexShape;//is also in _ghostObject, but it needs to be convex, so we store it here to avoid upcast + btScalar _radius; + btScalar _halfHeight; - btScalar m_verticalVelocity; - btScalar m_verticalOffset; // fall distance from velocity this frame - btScalar m_maxFallSpeed; - btScalar m_jumpSpeed; - btScalar m_maxJumpHeight; - btScalar m_maxSlopeRadians; // Slope angle that is set (used for returning the exact value) - btScalar m_maxSlopeCosine; // Cosine equivalent of m_maxSlopeRadians (calculated once when set, for optimization) - btScalar m_gravity; + btScalar _verticalVelocity; + btScalar _verticalOffset; // fall distance from velocity this frame + btScalar _maxFallSpeed; + btScalar _jumpSpeed; + btScalar _maxJumpHeight; + btScalar _maxSlopeRadians; // Slope angle that is set (used for returning the exact value) + btScalar _maxSlopeCosine; // Cosine equivalent of _maxSlopeRadians (calculated once when set, for optimization) + btScalar _gravity; - btScalar m_stepHeight; // height of stepUp prior to stepForward + btScalar _stepHeight; // height of stepUp prior to stepForward - btScalar m_addedMargin;//@todo: remove this and fix the code + btScalar _addedMargin;//@todo: remove this and fix the code ///this is the desired walk direction, set by the user - btVector3 m_walkDirection; - btVector3 m_normalizedDirection; + btVector3 _walkDirection; + btVector3 _normalizedDirection; //some internal variables - btVector3 m_currentPosition; - btVector3 m_targetPosition; - btScalar m_lastStepUp; + btVector3 _currentPosition; + btVector3 _targetPosition; + btScalar _lastStepUp; ///keep track of the contact manifolds - btManifoldArray m_manifoldArray; + btManifoldArray _manifoldArray; - bool m_touchingContact; - btVector3 m_floorNormal; // points from object to character + bool _touchingContact; + btVector3 _floorNormal; // points from object to character - bool m_enabled; - bool m_wasOnGround; - bool m_wasJumping; - bool m_useWalkDirection; - btScalar m_velocityTimeInterval; - int m_upAxis; + bool _enabled; + bool _wasOnGround; + bool _wasJumping; + bool _useWalkDirection; + btScalar _velocityTimeInterval; + int _upAxis; static btVector3* getUpAxisDirections(); - bool m_interpolateUp; - bool full_drop; - bool bounce_fix; btVector3 computeReflectionDirection(const btVector3& direction, const btVector3& normal); btVector3 parallelComponent(const btVector3& direction, const btVector3& normal); @@ -121,7 +118,7 @@ public: axis = 0; if (axis > 2) axis = 2; - m_upAxis = axis; + _upAxis = axis; } /// This should probably be called setPositionIncrementPerSimulatorStep. From 49f5de2b944a59556beb53abede24fb8caa49b5c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 20 Mar 2015 16:39:38 -0700 Subject: [PATCH 11/53] make character's "up" axis depend on orientation --- libraries/physics/src/CharacterController.cpp | 40 +++++++++---------- libraries/physics/src/CharacterController.h | 12 +----- 2 files changed, 20 insertions(+), 32 deletions(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index f7f8ab4d53..d0b083fc01 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -216,6 +216,8 @@ btVector3 CharacterController::perpindicularComponent(const btVector3& direction return direction - parallelComponent(direction, normal); } +const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f); + CharacterController::CharacterController(AvatarData* avatarData) { assert(avatarData); _avatarData = avatarData; @@ -227,8 +229,6 @@ CharacterController::CharacterController(AvatarData* avatarData) { createShapeAndGhost(); - _upAxis = 1; // HACK: hard coded to be 1 for now (yAxis) - _addedMargin = 0.02f; _walkDirection.setValue(0.0f,0.0f,0.0f); _useWalkDirection = true; // use walk direction by default, legacy behavior @@ -272,7 +272,7 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl collisionWorld->getDispatcher()->dispatchAllCollisionPairs(_ghostObject->getOverlappingPairCache(), collisionWorld->getDispatchInfo(), collisionWorld->getDispatcher()); _currentPosition = _ghostObject->getWorldTransform().getOrigin(); - btVector3 up = getUpAxisDirections()[_upAxis]; + btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); btVector3 currentPosition = _currentPosition; @@ -355,14 +355,15 @@ void CharacterController::stepUp( btCollisionWorld* world) { // compute start and end btTransform start, end; start.setIdentity(); - start.setOrigin(_currentPosition + getUpAxisDirections()[_upAxis] * (_convexShape->getMargin() + _addedMargin)); + btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); + start.setOrigin(_currentPosition + up * (_convexShape->getMargin() + _addedMargin)); - _targetPosition = _currentPosition + getUpAxisDirections()[_upAxis] * _stepHeight; + _targetPosition = _currentPosition + up * _stepHeight; end.setIdentity(); end.setOrigin(_targetPosition); // sweep up - btVector3 sweepDirNegative = -getUpAxisDirections()[_upAxis]; + btVector3 sweepDirNegative = - up; btKinematicClosestNotMeConvexResultCallback callback(_ghostObject, sweepDirNegative, btScalar(0.7071)); callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; @@ -370,11 +371,11 @@ void CharacterController::stepUp( btCollisionWorld* world) { if (callback.hasHit()) { // we hit something, so zero our vertical velocity - _verticalVelocity = 0.0; - _verticalOffset = 0.0; + _verticalVelocity = 0.0f; + _verticalOffset = 0.0f; // Only modify the position if the hit was a slope and not a wall or ceiling. - if (callback.m_hitNormalWorld.dot(getUpAxisDirections()[_upAxis]) > 0.0) { + if (callback.m_hitNormalWorld.dot(up) > 0.0f) { _lastStepUp = _stepHeight * callback.m_closestHitFraction; _currentPosition.setInterpolate3(_currentPosition, _targetPosition, callback.m_closestHitFraction); } else { @@ -484,10 +485,11 @@ void CharacterController::stepDown( btCollisionWorld* collisionWorld, btScalar d } // first sweep for ledge - btVector3 step = getUpAxisDirections()[_upAxis] * (-(_lastStepUp + downSpeed * dt)); + btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); + btVector3 step = up * (-(_lastStepUp + downSpeed * dt)); StepDownConvexResultCallback callback(_ghostObject, - getUpAxisDirections()[_upAxis], + up, _currentPosition, step, _walkDirection, _maxSlopeCosine, @@ -512,7 +514,7 @@ void CharacterController::stepDown( btCollisionWorld* collisionWorld, btScalar d } else { // sweep again for floor within downStep threshold StepDownConvexResultCallback callback2 (_ghostObject, - getUpAxisDirections()[_upAxis], + up, _currentPosition, step, _walkDirection, _maxSlopeCosine, @@ -523,7 +525,7 @@ void CharacterController::stepDown( btCollisionWorld* collisionWorld, btScalar d _currentPosition = _targetPosition; btVector3 oldPosition = _currentPosition; - step = (- _stepHeight) * getUpAxisDirections()[_upAxis]; + step = (- _stepHeight) * up; _targetPosition = _currentPosition + step; start.setOrigin(_currentPosition); @@ -537,7 +539,7 @@ void CharacterController::stepDown( btCollisionWorld* collisionWorld, btScalar d _wasJumping = false; } else { // nothing to step down on, so remove the stepUp effect - _currentPosition = oldPosition - _lastStepUp * getUpAxisDirections()[_upAxis]; + _currentPosition = oldPosition - _lastStepUp * up; _lastStepUp = 0.0f; } } @@ -595,7 +597,9 @@ void CharacterController::preStep( btCollisionWorld* collisionWorld) { } } - _currentPosition = _ghostObject->getWorldTransform().getOrigin(); + const btTransform& transform = _ghostObject->getWorldTransform(); + _currentRotation = transform.getRotation(); + _currentPosition = transform.getOrigin(); _targetPosition = _currentPosition; } @@ -697,12 +701,6 @@ bool CharacterController::onGround() const { return _enabled && _verticalVelocity == 0.0 && _verticalOffset == 0.0; } -btVector3* CharacterController::getUpAxisDirections() { - static btVector3 sUpAxisDirection[3] = { btVector3(1.0f, 0.0f, 0.0f), btVector3(0.0f, 1.0f, 0.0f), btVector3(0.0f, 0.0f, 1.0f) }; - - return sUpAxisDirection; -} - void CharacterController::debugDraw(btIDebugDraw* debugDrawer) { } diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index 23c338412c..b6109eb0ff 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -68,6 +68,7 @@ protected: //some internal variables btVector3 _currentPosition; + btQuaternion _currentRotation; btVector3 _targetPosition; btScalar _lastStepUp; @@ -82,9 +83,6 @@ protected: bool _wasJumping; bool _useWalkDirection; btScalar _velocityTimeInterval; - int _upAxis; - - static btVector3* getUpAxisDirections(); btVector3 computeReflectionDirection(const btVector3& direction, const btVector3& normal); btVector3 parallelComponent(const btVector3& direction, const btVector3& normal); @@ -113,14 +111,6 @@ public: ///btActionInterface interface void debugDraw(btIDebugDraw* debugDrawer); - void setUpAxis(int axis) { - if (axis < 0) - axis = 0; - if (axis > 2) - axis = 2; - _upAxis = axis; - } - /// This should probably be called setPositionIncrementPerSimulatorStep. /// This is neither a direction nor a velocity, but the amount to /// increment the position each simulation iteration, regardless From 3de7222007e3431232ee25962156aa6070427c04 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 23 Mar 2015 09:06:15 -0700 Subject: [PATCH 12/53] Make Sixense emulate mouse only if controllers aren't at the base --- interface/src/devices/SixenseManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index ce6ca57c69..0a89ad0e37 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -223,7 +223,7 @@ void SixenseManager::update(float deltaTime) { palm->setJoystick(data->joystick_x, data->joystick_y); // Emulate the mouse so we can use scripts - if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) { + if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput) && !_controllersAtBase) { emulateMouse(palm, numActiveControllers - 1); } From 61dc31ffe76fafea99fa20177311bd256910ab98 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 23 Mar 2015 14:09:45 -0700 Subject: [PATCH 13/53] Update export entities to export as JSON --- 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 4ff41e1b6f..840e8388c7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1751,7 +1751,7 @@ bool Application::exportEntities(const QString& filename, const QVectorgetEntityItemID(), properties); } - exportTree.writeToSVOFile(filename.toLocal8Bit().constData()); + exportTree.writeToJSONFile(filename.toLocal8Bit().constData()); // restore the main window's active state _window->activateWindow(); From 6d932508ffbe66ddd9e2fe1066868f3d0e0b1e96 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 24 Mar 2015 10:27:53 -0700 Subject: [PATCH 14/53] Add support for .svo.json extension --- interface/src/Application.h | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/Application.h b/interface/src/Application.h index 4038b21739..6e0c3cebd2 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -95,6 +95,7 @@ static const float NODE_KILLED_BLUE = 0.0f; static const QString SNAPSHOT_EXTENSION = ".jpg"; static const QString SVO_EXTENSION = ".svo"; +static const QString SVO_JSON_EXTENSION = ".svo.json"; static const QString JS_EXTENSION = ".js"; static const QString FST_EXTENSION = ".fst"; From a901bc4b11ba199879cafa6b766012b44deab33f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 24 Mar 2015 10:28:12 -0700 Subject: [PATCH 15/53] Update edit.js to export as .svo.json --- examples/edit.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/edit.js b/examples/edit.js index 72938e5ed4..2179fe5342 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -910,8 +910,8 @@ function handeMenuEvent(menuItem) { if (!selectionManager.hasSelection()) { Window.alert("No entities have been selected."); } else { - var filename = "models__" + Window.location.hostname + "__.svo"; - filename = Window.save("Select where to save", filename, "*.svo") + var filename = "entities__" + Window.location.hostname + ".svo.json"; + filename = Window.save("Select where to save", filename, "*.json") if (filename) { var success = Clipboard.exportEntities(filename, selectionManager.selections); if (!success) { @@ -923,7 +923,7 @@ function handeMenuEvent(menuItem) { var importURL; if (menuItem == "Import Entities") { - importURL = Window.browse("Select models to import", "", "*.svo"); + importURL = Window.browse("Select models to import", "", "*.json"); } else { importURL = Window.prompt("URL of SVO to import", ""); } From 2fc0ef80d0eb4b42521355b058d04e880c0378aa Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 24 Mar 2015 10:40:46 -0700 Subject: [PATCH 16/53] Add SVO_JSON_EXTENSION to accepted extensions --- interface/src/Application.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 840e8388c7..cf9d583945 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3599,6 +3599,7 @@ void Application::initializeAcceptedFiles() { if (_acceptedExtensions.size() == 0) { _acceptedExtensions[SNAPSHOT_EXTENSION] = &Application::acceptSnapshot; _acceptedExtensions[SVO_EXTENSION] = &Application::importSVOFromURL; + _acceptedExtensions[SVO_JSON_EXTENSION] = &Application::importSVOFromURL; _acceptedExtensions[JS_EXTENSION] = &Application::askToLoadScript; _acceptedExtensions[FST_EXTENSION] = &Application::askToSetAvatarUrl; } From 1a6865b41bfe2600bc8b5e7be777d23fa6d40612 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 24 Mar 2015 12:26:32 -0700 Subject: [PATCH 17/53] send immediate location update when domain changes --- interface/src/Application.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ad6a0d86ce..c21d221303 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -382,6 +382,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : auto discoverabilityManager = DependencyManager::get(); connect(locationUpdateTimer, &QTimer::timeout, discoverabilityManager.data(), &DiscoverabilityManager::updateLocation); locationUpdateTimer->start(DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS); + + // if we get a domain change, immediately attempt update location in metaverse server + connect(&nodeList->getDomainHandler(), &DomainHandler::connectedToDomain, + discoverabilityManager.data(), &DiscoverabilityManager::updateLocation); connect(nodeList.data(), &NodeList::nodeAdded, this, &Application::nodeAdded); connect(nodeList.data(), &NodeList::nodeKilled, this, &Application::nodeKilled); @@ -3295,11 +3299,6 @@ void Application::connectedToDomain(const QString& hostname) { const QUuid& domainID = DependencyManager::get()->getDomainHandler().getUUID(); if (accountManager.isLoggedIn() && !domainID.isNull()) { - // update our data-server with the domain-server we're logged in with - QString domainPutJsonString = "{\"location\":{\"domain_id\":\"" + uuidStringWithoutCurlyBraces(domainID) + "\"}}"; - accountManager.authenticatedRequest("/api/v1/user/location", QNetworkAccessManager::PutOperation, - JSONCallbackParameters(), domainPutJsonString.toUtf8()); - _notifiedPacketVersionMismatchThisDomain = false; } } From 619428c325864f361c9b9ba17c31733c171ebc85 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 24 Mar 2015 13:32:22 -0700 Subject: [PATCH 18/53] move LOD FPS settings to Preferences --- interface/src/Application.cpp | 2 + interface/src/LODManager.cpp | 9 - interface/src/LODManager.h | 11 +- interface/src/ui/LodToolsDialog.cpp | 31 ---- interface/src/ui/LodToolsDialog.h | 2 - interface/src/ui/PreferencesDialog.cpp | 10 ++ interface/ui/preferencesDialog.ui | 218 +++++++++++++++++++++++++ 7 files changed, 233 insertions(+), 50 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ad6a0d86ce..daf2a76f5f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1786,6 +1786,7 @@ bool Application::exportEntities(const QString& filename, float x, float y, floa void Application::loadSettings() { DependencyManager::get()->loadSettings(); + DependencyManager::get()->loadSettings(); Menu::getInstance()->loadSettings(); _myAvatar->loadData(); @@ -1793,6 +1794,7 @@ void Application::loadSettings() { void Application::saveSettings() { DependencyManager::get()->saveSettings(); + DependencyManager::get()->saveSettings(); Menu::getInstance()->saveSettings(); _myAvatar->saveData(); diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 739e5f280a..5c55952e3a 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -17,11 +17,8 @@ #include "LODManager.h" -Setting::Handle automaticLODAdjust("automaticLODAdjust", true); Setting::Handle desktopLODDecreaseFPS("desktopLODDecreaseFPS", DEFAULT_DESKTOP_LOD_DOWN_FPS); -Setting::Handle desktopLODIncreaseFPS("desktopLODIncreaseFPS", DEFAULT_DESKTOP_LOD_UP_FPS); Setting::Handle hmdLODDecreaseFPS("hmdLODDecreaseFPS", DEFAULT_HMD_LOD_DOWN_FPS); -Setting::Handle hmdLODIncreaseFPS("hmdLODIncreaseFPS", DEFAULT_HMD_LOD_UP_FPS); Setting::Handle avatarLODDistanceMultiplier("avatarLODDistanceMultiplier", @@ -244,11 +241,8 @@ void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) { void LODManager::loadSettings() { - setAutomaticLODAdjust(automaticLODAdjust.get()); setDesktopLODDecreaseFPS(desktopLODDecreaseFPS.get()); - setDesktopLODIncreaseFPS(desktopLODIncreaseFPS.get()); setHMDLODDecreaseFPS(hmdLODDecreaseFPS.get()); - setHMDLODIncreaseFPS(hmdLODIncreaseFPS.get()); setAvatarLODDistanceMultiplier(avatarLODDistanceMultiplier.get()); setBoundaryLevelAdjust(boundaryLevelAdjust.get()); @@ -256,11 +250,8 @@ void LODManager::loadSettings() { } void LODManager::saveSettings() { - automaticLODAdjust.set(getAutomaticLODAdjust()); desktopLODDecreaseFPS.set(getDesktopLODDecreaseFPS()); - desktopLODIncreaseFPS.set(getDesktopLODIncreaseFPS()); hmdLODDecreaseFPS.set(getHMDLODDecreaseFPS()); - hmdLODIncreaseFPS.set(getHMDLODIncreaseFPS()); avatarLODDistanceMultiplier.set(getAvatarLODDistanceMultiplier()); boundaryLevelAdjust.set(getBoundaryLevelAdjust()); diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 57b03cba42..7d63fbd172 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -18,9 +18,8 @@ #include const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 30.0; -const float DEFAULT_DESKTOP_LOD_UP_FPS = 50.0; const float DEFAULT_HMD_LOD_DOWN_FPS = 60.0; -const float DEFAULT_HMD_LOD_UP_FPS = 65.0; +const float INCREASE_LOD_GAP = 5.0f; const quint64 ADJUST_LOD_DOWN_DELAY = 1000 * 1000 * 0.5; // Consider adjusting LOD down after half a second const quint64 ADJUST_LOD_UP_DELAY = ADJUST_LOD_DOWN_DELAY * 2; @@ -53,13 +52,11 @@ public: Q_INVOKABLE void setDesktopLODDecreaseFPS(float value) { _desktopLODDecreaseFPS = value; } Q_INVOKABLE float getDesktopLODDecreaseFPS() const { return _desktopLODDecreaseFPS; } - Q_INVOKABLE void setDesktopLODIncreaseFPS(float value) { _desktopLODIncreaseFPS = value; } - Q_INVOKABLE float getDesktopLODIncreaseFPS() const { return _desktopLODIncreaseFPS; } + Q_INVOKABLE float getDesktopLODIncreaseFPS() const { return _desktopLODDecreaseFPS + INCREASE_LOD_GAP; } Q_INVOKABLE void setHMDLODDecreaseFPS(float value) { _hmdLODDecreaseFPS = value; } Q_INVOKABLE float getHMDLODDecreaseFPS() const { return _hmdLODDecreaseFPS; } - Q_INVOKABLE void setHMDLODIncreaseFPS(float value) { _hmdLODIncreaseFPS = value; } - Q_INVOKABLE float getHMDLODIncreaseFPS() const { return _hmdLODIncreaseFPS; } + Q_INVOKABLE float getHMDLODIncreaseFPS() const { return _hmdLODDecreaseFPS + INCREASE_LOD_GAP; } Q_INVOKABLE void setAvatarLODDistanceMultiplier(float multiplier) { _avatarLODDistanceMultiplier = multiplier; } Q_INVOKABLE float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; } @@ -94,9 +91,7 @@ private: bool _automaticLODAdjust = true; float _desktopLODDecreaseFPS = DEFAULT_DESKTOP_LOD_DOWN_FPS; - float _desktopLODIncreaseFPS = DEFAULT_DESKTOP_LOD_UP_FPS; float _hmdLODDecreaseFPS = DEFAULT_HMD_LOD_DOWN_FPS; - float _hmdLODIncreaseFPS = DEFAULT_HMD_LOD_UP_FPS; float _avatarLODDistanceMultiplier = DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER; diff --git a/interface/src/ui/LodToolsDialog.cpp b/interface/src/ui/LodToolsDialog.cpp index af434d5565..7635012bc2 100644 --- a/interface/src/ui/LodToolsDialog.cpp +++ b/interface/src/ui/LodToolsDialog.cpp @@ -50,26 +50,6 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) : _automaticLODAdjust->setChecked(lodManager->getAutomaticLODAdjust()); connect(_automaticLODAdjust, SIGNAL(toggled(bool)), SLOT(updateAutomaticLODAdjust())); - form->addRow("Desktop Decrease LOD Below FPS:", _desktopLODDecreaseFPS = new QDoubleSpinBox(this)); - _desktopLODDecreaseFPS->setValue(lodManager->getDesktopLODDecreaseFPS()); - _desktopLODDecreaseFPS->setDecimals(0); - connect(_desktopLODDecreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateLODValues())); - - form->addRow("Desktop Increase LOD Above FPS:", _desktopLODIncreaseFPS = new QDoubleSpinBox(this)); - _desktopLODIncreaseFPS->setValue(lodManager->getDesktopLODIncreaseFPS()); - _desktopLODIncreaseFPS->setDecimals(0); - connect(_desktopLODIncreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateLODValues())); - - form->addRow("HMD Decrease LOD Below FPS:", _hmdLODDecreaseFPS = new QDoubleSpinBox(this)); - _hmdLODDecreaseFPS->setValue(lodManager->getHMDLODDecreaseFPS()); - _hmdLODDecreaseFPS->setDecimals(0); - connect(_hmdLODDecreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateLODValues())); - - form->addRow("HMD Increase LOD Above FPS:", _hmdLODIncreaseFPS = new QDoubleSpinBox(this)); - _hmdLODIncreaseFPS->setValue(lodManager->getHMDLODIncreaseFPS()); - _hmdLODIncreaseFPS->setDecimals(0); - connect(_hmdLODIncreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateLODValues())); - form->addRow("Avatar LOD:", _avatarLOD = new QDoubleSpinBox(this)); _avatarLOD->setDecimals(3); _avatarLOD->setRange(1.0 / MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, 1.0 / MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER); @@ -123,12 +103,6 @@ void LodToolsDialog::updateLODValues() { auto lodManager = DependencyManager::get(); lodManager->setAutomaticLODAdjust(_automaticLODAdjust->isChecked()); - - lodManager->setDesktopLODDecreaseFPS(_desktopLODDecreaseFPS->value()); - lodManager->setDesktopLODIncreaseFPS(_desktopLODIncreaseFPS->value()); - lodManager->setHMDLODDecreaseFPS(_hmdLODDecreaseFPS->value()); - lodManager->setHMDLODIncreaseFPS(_hmdLODIncreaseFPS->value()); - lodManager->setAvatarLODDistanceMultiplier(1.0 / _avatarLOD->value()); } @@ -145,11 +119,6 @@ void LodToolsDialog::resetClicked(bool checked) { int sliderValue = DEFAULT_OCTREE_SIZE_SCALE / TREE_SCALE; _lodSize->setValue(sliderValue); _automaticLODAdjust->setChecked(true); - _desktopLODDecreaseFPS->setValue(DEFAULT_DESKTOP_LOD_DOWN_FPS); - _desktopLODIncreaseFPS->setValue(DEFAULT_DESKTOP_LOD_UP_FPS); - _hmdLODDecreaseFPS->setValue(DEFAULT_HMD_LOD_DOWN_FPS); - _hmdLODIncreaseFPS->setValue(DEFAULT_HMD_LOD_UP_FPS); - _avatarLOD->setValue(1.0 / DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER); updateLODValues(); // tell our LOD manager about the reset diff --git a/interface/src/ui/LodToolsDialog.h b/interface/src/ui/LodToolsDialog.h index 2e85b3f5a5..709357fddd 100644 --- a/interface/src/ui/LodToolsDialog.h +++ b/interface/src/ui/LodToolsDialog.h @@ -47,10 +47,8 @@ private: QCheckBox* _automaticLODAdjust; QDoubleSpinBox* _desktopLODDecreaseFPS; - QDoubleSpinBox* _desktopLODIncreaseFPS; QDoubleSpinBox* _hmdLODDecreaseFPS; - QDoubleSpinBox* _hmdLODIncreaseFPS; QDoubleSpinBox* _avatarLOD; diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index fa63079290..a07de371a2 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -19,6 +19,7 @@ #include "Application.h" #include "MainWindow.h" +#include "LODManager.h" #include "Menu.h" #include "ModelsBrowser.h" #include "PreferencesDialog.h" @@ -174,6 +175,10 @@ void PreferencesDialog::loadPreferences() { ui.sixenseReticleMoveSpeedSpin->setValue(sixense.getReticleMoveSpeed()); ui.invertSixenseButtonsCheckBox->setChecked(sixense.getInvertButtons()); + // LOD items + auto lodManager = DependencyManager::get(); + ui.desktopMinimumFPSSpin->setValue(lodManager->getDesktopLODDecreaseFPS()); + ui.hmdMinimumFPSSpin->setValue(lodManager->getHMDLODDecreaseFPS()); } void PreferencesDialog::savePreferences() { @@ -275,4 +280,9 @@ void PreferencesDialog::savePreferences() { audio->setOutputStarveDetectionPeriod(ui.outputStarveDetectionPeriodSpinner->value()); Application::getInstance()->resizeGL(glCanvas->width(), glCanvas->height()); + + // LOD items + auto lodManager = DependencyManager::get(); + lodManager->setDesktopLODDecreaseFPS(ui.desktopMinimumFPSSpin->value()); + lodManager->setHMDLODDecreaseFPS(ui.hmdMinimumFPSSpin->value()); } diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui index 13894a2592..d295d094c2 100644 --- a/interface/ui/preferencesDialog.ui +++ b/interface/ui/preferencesDialog.ui @@ -701,6 +701,219 @@ + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + Arial + 18 + 75 + true + + + + color:#29967e + + + Level of Detail Tuning + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + + 0 + + + 7 + + + 0 + + + 7 + + + + + + Arial + + + + + + + Minimum Desktop FPS + + + 0 + + + + + + + + + Arial + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + 100 + 0 + + + + + 95 + 36 + + + + + Arial + + + + 0 + + + 120 + + + + + + + + + + 0 + + + 7 + + + 0 + + + 7 + + + + + + Arial + + + + + + + Minimum HMD FPS + + + 0 + + + + + + + + + Arial + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + 100 + 0 + + + + + 95 + 36 + + + + + Arial + + + + 0 + + + 120 + + + + + + + @@ -717,6 +930,7 @@ + @@ -738,6 +952,7 @@ + @@ -820,6 +1035,9 @@ + + + From 6c941d73d5a503671bc8f600273f7043ec4bb5ff Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 24 Mar 2015 13:34:14 -0700 Subject: [PATCH 19/53] Update edit.js help --- .../html/edit-entities-commands.html | 3832 +++++++++-------- 1 file changed, 1927 insertions(+), 1905 deletions(-) diff --git a/interface/resources/html/edit-entities-commands.html b/interface/resources/html/edit-entities-commands.html index afa662f089..65b985fb6a 100644 --- a/interface/resources/html/edit-entities-commands.html +++ b/interface/resources/html/edit-entities-commands.html @@ -2,2035 +2,2057 @@
- + - Edit Entity Help + - - - - - + - - - - - - - - - + + + + + + - - - - - - - + + - - - + + + - + - - - + + + - - + + - - - + + + - - - - + S213.7,23.8,213.7,25.1z"/> + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + - + + + + + + + + + + + + + + + + + + - + + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - + + + - + c0.2-0.2,0.5-0.2,0.8,0l1.8,1.2l3.1-4.4l-4.4-3.1L58,205c-0.1,0.2-0.3,0.3-0.4,0.3c-0.1,0-0.2,0-0.3,0c-0.3-0.1-0.5-0.3-0.5-0.5 + l-0.9-4.7c-0.1-0.4,0.2-0.7,0.6-0.8l4.7-0.9c0.3-0.1,0.5,0.1,0.7,0.3c0.2,0.2,0.2,0.5,0,0.8l-1.2,1.8l4.4,3.1l3.1-4.4l-1.8-1.2 + c-0.2-0.2-0.3-0.4-0.3-0.7c0.1-0.3,0.3-0.5,0.5-0.5l4.7-0.9c0.4-0.1,0.7,0.2,0.8,0.6l0.9,4.7c0.1,0.3-0.1,0.5-0.3,0.7 + c-0.1,0-0.2,0.1-0.3,0.1c-0.2,0-0.4,0-0.5-0.1l-1.8-1.2L67.1,205.6z"/> - + c-0.1,0-0.2,0.1-0.3,0.1c-0.2,0-0.4,0-0.5-0.1l-1.8-1.2L67.1,269.3z"/> - + c-0.1,0-0.2,0.1-0.3,0.1c-0.2,0-0.4,0-0.5-0.1l-1.8-1.2L67.1,332.3z"/> - - - - + + + + - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + c-0.1,0-0.2,0.1-0.3,0.1c-0.2,0-0.4,0-0.5-0.1l-1.8-1.2L687.1,208.4z"/> - - - - - + + + + + + + + - - - - - - + + + + + - - - - - - - - - - - - - - - + - + + + + + + + + + + - + + + + + + + + - - - - + + + + + + + + + + + + + c-0.1,0-0.2,0.1-0.3,0.1c-0.2,0-0.4,0-0.5-0.1l-1.8-1.2L631.5,270.6z"/> - + - + - + - + - - - - + + + + - + - + - + - + - - - + + +
From 3f986229d150875275a868ab940a37766a11988b Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 24 Mar 2015 13:43:10 -0700 Subject: [PATCH 20/53] Rename edit-entities-commands.html to edit-commands.html --- .../html/{edit-entities-commands.html => edit-commands.html} | 0 interface/src/Application.h | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename interface/resources/html/{edit-entities-commands.html => edit-commands.html} (100%) diff --git a/interface/resources/html/edit-entities-commands.html b/interface/resources/html/edit-commands.html similarity index 100% rename from interface/resources/html/edit-entities-commands.html rename to interface/resources/html/edit-commands.html diff --git a/interface/src/Application.h b/interface/src/Application.h index 4038b21739..898db76f07 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -113,7 +113,7 @@ static const float MIRROR_FIELD_OF_VIEW = 30.0f; static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS_PER_SECOND; static const QString INFO_HELP_PATH = "html/interface-welcome.html"; -static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-entities-commands.html"; +static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-commands.html"; #ifdef Q_OS_WIN static const UINT UWM_IDENTIFY_INSTANCES = From 3563efb584d7b56b25beee653ded7b39ddabd05d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 24 Mar 2015 21:52:53 +0100 Subject: [PATCH 21/53] extra ; --- libraries/entities/src/EntityItemID.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityItemID.cpp b/libraries/entities/src/EntityItemID.cpp index aaf6e33128..cd2202eead 100644 --- a/libraries/entities/src/EntityItemID.cpp +++ b/libraries/entities/src/EntityItemID.cpp @@ -25,7 +25,7 @@ EntityItemID::EntityItemID() : creatorTokenID(UNKNOWN_ENTITY_TOKEN), isKnownID(false) { -}; +} EntityItemID::EntityItemID(const EntityItemID& other) : id(other.id), From f43b8bbe8edc744d99f3d43fc665d014ee6f001d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 24 Mar 2015 13:59:46 -0700 Subject: [PATCH 22/53] make AvatarLODMultiplier based on octreeSizeScale --- interface/src/LODManager.cpp | 46 +++++++---------------------- interface/src/LODManager.h | 14 ++++----- interface/src/ui/LodToolsDialog.cpp | 13 -------- interface/src/ui/LodToolsDialog.h | 2 -- 4 files changed, 16 insertions(+), 59 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 5c55952e3a..6d08b8e242 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -20,13 +20,14 @@ Setting::Handle desktopLODDecreaseFPS("desktopLODDecreaseFPS", DEFAULT_DESKTOP_LOD_DOWN_FPS); Setting::Handle hmdLODDecreaseFPS("hmdLODDecreaseFPS", DEFAULT_HMD_LOD_DOWN_FPS); - -Setting::Handle avatarLODDistanceMultiplier("avatarLODDistanceMultiplier", - DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER); Setting::Handle boundaryLevelAdjust("boundaryLevelAdjust", 0); Setting::Handle octreeSizeScale("octreeSizeScale", DEFAULT_OCTREE_SIZE_SCALE); +LODManager::LODManager() { + calculateAvatarLODDistanceMultiplier(); +} + float LODManager::getLODDecreaseFPS() { if (Application::getInstance()->isHMDMode()) { return getHMDLODDecreaseFPS(); @@ -64,21 +65,6 @@ void LODManager::autoAdjustLOD(float currentFPS) { // LOD Downward adjustment if (elapsed > ADJUST_LOD_DOWN_DELAY && _fpsAverage.getAverage() < getLODDecreaseFPS()) { - // Avatars... attempt to lower the detail in proportion to the fps difference - float targetFps = (getLODDecreaseFPS() + getLODIncreaseFPS()) * 0.5f; - float averageFps = _fastFPSAverage.getAverage(); - const float MAXIMUM_MULTIPLIER_SCALE = 2.0f; - float oldAvatarLODDistanceMultiplier = _avatarLODDistanceMultiplier; - _avatarLODDistanceMultiplier = qMin(MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, _avatarLODDistanceMultiplier * - (averageFps < EPSILON ? MAXIMUM_MULTIPLIER_SCALE : - qMin(MAXIMUM_MULTIPLIER_SCALE, targetFps / averageFps))); - - if (oldAvatarLODDistanceMultiplier != _avatarLODDistanceMultiplier) { - qDebug() << "adjusting LOD down... average fps for last approximately 5 seconds=" << _fpsAverage.getAverage() - << "_avatarLODDistanceMultiplier=" << _avatarLODDistanceMultiplier; - changed = true; - } - // Octree items... stepwise adjustment if (_octreeSizeScale > ADJUST_LOD_MIN_SIZE_SCALE) { _octreeSizeScale *= ADJUST_LOD_DOWN_BY; @@ -100,20 +86,6 @@ void LODManager::autoAdjustLOD(float currentFPS) { // LOD Upward adjustment if (elapsed > ADJUST_LOD_UP_DELAY && _fpsAverage.getAverage() > getLODIncreaseFPS()) { - // Avatars... let the detail level creep slowly upwards - if (_avatarLODDistanceMultiplier < MAXIMUM_AUTO_ADJUST_AVATAR_LOD_DISTANCE_MULTIPLIER) { - const float DISTANCE_DECREASE_RATE = 0.05f; - float oldAvatarLODDistanceMultiplier = _avatarLODDistanceMultiplier; - _avatarLODDistanceMultiplier = qMax(MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, - _avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE); - - if (oldAvatarLODDistanceMultiplier != _avatarLODDistanceMultiplier) { - qDebug() << "adjusting LOD up... average fps for last approximately 5 seconds=" << _fpsAverage.getAverage() - << "_avatarLODDistanceMultiplier=" << _avatarLODDistanceMultiplier; - changed = true; - } - } - // Octee items... stepwise adjustment if (_octreeSizeScale < ADJUST_LOD_MAX_SIZE_SCALE) { if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) { @@ -137,6 +109,7 @@ void LODManager::autoAdjustLOD(float currentFPS) { } if (changed) { + calculateAvatarLODDistanceMultiplier(); _shouldRenderTableNeedsRebuilding = true; auto lodToolsDialog = DependencyManager::get()->getLodToolsDialog(); if (lodToolsDialog) { @@ -231,9 +204,14 @@ bool LODManager::shouldRenderMesh(float largestDimension, float distanceToCamera void LODManager::setOctreeSizeScale(float sizeScale) { _octreeSizeScale = sizeScale; + calculateAvatarLODDistanceMultiplier(); _shouldRenderTableNeedsRebuilding = true; } +void LODManager::calculateAvatarLODDistanceMultiplier() { + _avatarLODDistanceMultiplier = AVATAR_TO_ENTITY_RATIO / (_octreeSizeScale / DEFAULT_OCTREE_SIZE_SCALE); +} + void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) { _boundaryLevelAdjust = boundaryLevelAdjust; _shouldRenderTableNeedsRebuilding = true; @@ -243,8 +221,6 @@ void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) { void LODManager::loadSettings() { setDesktopLODDecreaseFPS(desktopLODDecreaseFPS.get()); setHMDLODDecreaseFPS(hmdLODDecreaseFPS.get()); - - setAvatarLODDistanceMultiplier(avatarLODDistanceMultiplier.get()); setBoundaryLevelAdjust(boundaryLevelAdjust.get()); setOctreeSizeScale(octreeSizeScale.get()); } @@ -252,8 +228,6 @@ void LODManager::loadSettings() { void LODManager::saveSettings() { desktopLODDecreaseFPS.set(getDesktopLODDecreaseFPS()); hmdLODDecreaseFPS.set(getHMDLODDecreaseFPS()); - - avatarLODDistanceMultiplier.set(getAvatarLODDistanceMultiplier()); boundaryLevelAdjust.set(getBoundaryLevelAdjust()); octreeSizeScale.set(getOctreeSizeScale()); } diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 7d63fbd172..c14f17ca61 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -33,10 +33,9 @@ const float ADJUST_LOD_UP_BY = 1.1f; const float ADJUST_LOD_MIN_SIZE_SCALE = 1.0f; const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE; -const float MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER = 0.1f; -const float MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER = 15.0f; -const float DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER = 1.0f; -const float MAXIMUM_AUTO_ADJUST_AVATAR_LOD_DISTANCE_MULTIPLIER = DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER; +// The ratio of "visibility" of avatars to other content. A value larger than 1 will mean Avatars "cull" later than entities +// do. But both are still culled using the same angular size logic. +const float AVATAR_TO_ENTITY_RATIO = 2.0f; const int ONE_SECOND_OF_FRAMES = 60; const int FIVE_SECONDS_OF_FRAMES = 5 * ONE_SECOND_OF_FRAMES; @@ -58,7 +57,6 @@ public: Q_INVOKABLE float getHMDLODDecreaseFPS() const { return _hmdLODDecreaseFPS; } Q_INVOKABLE float getHMDLODIncreaseFPS() const { return _hmdLODDecreaseFPS + INCREASE_LOD_GAP; } - Q_INVOKABLE void setAvatarLODDistanceMultiplier(float multiplier) { _avatarLODDistanceMultiplier = multiplier; } Q_INVOKABLE float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; } // User Tweakable LOD Items @@ -87,14 +85,14 @@ signals: void LODDecreased(); private: - LODManager() {} + LODManager(); + void calculateAvatarLODDistanceMultiplier(); bool _automaticLODAdjust = true; float _desktopLODDecreaseFPS = DEFAULT_DESKTOP_LOD_DOWN_FPS; float _hmdLODDecreaseFPS = DEFAULT_HMD_LOD_DOWN_FPS; - float _avatarLODDistanceMultiplier = DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER; - + float _avatarLODDistanceMultiplier; float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE; int _boundaryLevelAdjust = 0; diff --git a/interface/src/ui/LodToolsDialog.cpp b/interface/src/ui/LodToolsDialog.cpp index 7635012bc2..97991c62a4 100644 --- a/interface/src/ui/LodToolsDialog.cpp +++ b/interface/src/ui/LodToolsDialog.cpp @@ -50,13 +50,6 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) : _automaticLODAdjust->setChecked(lodManager->getAutomaticLODAdjust()); connect(_automaticLODAdjust, SIGNAL(toggled(bool)), SLOT(updateAutomaticLODAdjust())); - form->addRow("Avatar LOD:", _avatarLOD = new QDoubleSpinBox(this)); - _avatarLOD->setDecimals(3); - _avatarLOD->setRange(1.0 / MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, 1.0 / MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER); - _avatarLOD->setSingleStep(0.001); - _avatarLOD->setValue(1.0 / lodManager->getAvatarLODDistanceMultiplier()); - connect(_avatarLOD, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues())); - _lodSize = new QSlider(Qt::Horizontal, this); const int MAX_LOD_SIZE = MAX_LOD_SIZE_MULTIPLIER; const int MIN_LOD_SIZE = ADJUST_LOD_MIN_SIZE_SCALE; @@ -89,9 +82,6 @@ void LodToolsDialog::reloadSliders() { auto lodManager = DependencyManager::get(); _lodSize->setValue(lodManager->getOctreeSizeScale() / TREE_SCALE); _feedback->setText(lodManager->getLODFeedbackText()); - - _avatarLOD->setValue(1.0 / lodManager->getAvatarLODDistanceMultiplier()); - } void LodToolsDialog::updateAutomaticLODAdjust() { @@ -101,9 +91,7 @@ void LodToolsDialog::updateAutomaticLODAdjust() { void LodToolsDialog::updateLODValues() { auto lodManager = DependencyManager::get(); - lodManager->setAutomaticLODAdjust(_automaticLODAdjust->isChecked()); - lodManager->setAvatarLODDistanceMultiplier(1.0 / _avatarLOD->value()); } void LodToolsDialog::sizeScaleValueChanged(int value) { @@ -119,7 +107,6 @@ void LodToolsDialog::resetClicked(bool checked) { int sliderValue = DEFAULT_OCTREE_SIZE_SCALE / TREE_SCALE; _lodSize->setValue(sliderValue); _automaticLODAdjust->setChecked(true); - _avatarLOD->setValue(1.0 / DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER); updateLODValues(); // tell our LOD manager about the reset } diff --git a/interface/src/ui/LodToolsDialog.h b/interface/src/ui/LodToolsDialog.h index 709357fddd..91be04e0ed 100644 --- a/interface/src/ui/LodToolsDialog.h +++ b/interface/src/ui/LodToolsDialog.h @@ -50,8 +50,6 @@ private: QDoubleSpinBox* _hmdLODDecreaseFPS; - - QDoubleSpinBox* _avatarLOD; QLabel* _feedback; }; From b67cf3af2435cd772302c1f8ce5bda7ef471c7f5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 24 Mar 2015 14:33:06 -0700 Subject: [PATCH 23/53] more tweaks to LOD tools dialog --- interface/src/LODManager.cpp | 8 -------- interface/src/ui/LodToolsDialog.cpp | 29 +++++++++++++++++------------ interface/src/ui/LodToolsDialog.h | 3 +-- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 6d08b8e242..8b942dcfe1 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -20,10 +20,6 @@ Setting::Handle desktopLODDecreaseFPS("desktopLODDecreaseFPS", DEFAULT_DESKTOP_LOD_DOWN_FPS); Setting::Handle hmdLODDecreaseFPS("hmdLODDecreaseFPS", DEFAULT_HMD_LOD_DOWN_FPS); -Setting::Handle boundaryLevelAdjust("boundaryLevelAdjust", 0); -Setting::Handle octreeSizeScale("octreeSizeScale", DEFAULT_OCTREE_SIZE_SCALE); - - LODManager::LODManager() { calculateAvatarLODDistanceMultiplier(); } @@ -221,15 +217,11 @@ void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) { void LODManager::loadSettings() { setDesktopLODDecreaseFPS(desktopLODDecreaseFPS.get()); setHMDLODDecreaseFPS(hmdLODDecreaseFPS.get()); - setBoundaryLevelAdjust(boundaryLevelAdjust.get()); - setOctreeSizeScale(octreeSizeScale.get()); } void LODManager::saveSettings() { desktopLODDecreaseFPS.set(getDesktopLODDecreaseFPS()); hmdLODDecreaseFPS.set(getHMDLODDecreaseFPS()); - boundaryLevelAdjust.set(getBoundaryLevelAdjust()); - octreeSizeScale.set(getOctreeSizeScale()); } diff --git a/interface/src/ui/LodToolsDialog.cpp b/interface/src/ui/LodToolsDialog.cpp index 97991c62a4..378a1391f4 100644 --- a/interface/src/ui/LodToolsDialog.cpp +++ b/interface/src/ui/LodToolsDialog.cpp @@ -46,9 +46,9 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) : _feedback->setFixedWidth(FEEDBACK_WIDTH); form->addRow("You can see... ", _feedback); - form->addRow("Automatic LOD Adjustment:", _automaticLODAdjust = new QCheckBox(this)); - _automaticLODAdjust->setChecked(lodManager->getAutomaticLODAdjust()); - connect(_automaticLODAdjust, SIGNAL(toggled(bool)), SLOT(updateAutomaticLODAdjust())); + form->addRow("Manually Adjust Level of Detail:", _manualLODAdjust = new QCheckBox(this)); + _manualLODAdjust->setChecked(!lodManager->getAutomaticLODAdjust()); + connect(_manualLODAdjust, SIGNAL(toggled(bool)), SLOT(updateAutomaticLODAdjust())); _lodSize = new QSlider(Qt::Horizontal, this); const int MAX_LOD_SIZE = MAX_LOD_SIZE_MULTIPLIER; @@ -65,7 +65,7 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) : _lodSize->setPageStep(PAGE_STEP_LOD_SIZE); int sliderValue = lodManager->getOctreeSizeScale() / TREE_SCALE; _lodSize->setValue(sliderValue); - form->addRow("Non-Avatar Content LOD:", _lodSize); + form->addRow("Level of Detail:", _lodSize); connect(_lodSize,SIGNAL(valueChanged(int)),this,SLOT(sizeScaleValueChanged(int))); // Add a button to reset @@ -86,12 +86,8 @@ void LodToolsDialog::reloadSliders() { void LodToolsDialog::updateAutomaticLODAdjust() { auto lodManager = DependencyManager::get(); - lodManager->setAutomaticLODAdjust(_automaticLODAdjust->isChecked()); -} - -void LodToolsDialog::updateLODValues() { - auto lodManager = DependencyManager::get(); - lodManager->setAutomaticLODAdjust(_automaticLODAdjust->isChecked()); + lodManager->setAutomaticLODAdjust(!_manualLODAdjust->isChecked()); + _lodSize->setEnabled(_manualLODAdjust->isChecked()); } void LodToolsDialog::sizeScaleValueChanged(int value) { @@ -106,9 +102,9 @@ void LodToolsDialog::resetClicked(bool checked) { int sliderValue = DEFAULT_OCTREE_SIZE_SCALE / TREE_SCALE; _lodSize->setValue(sliderValue); - _automaticLODAdjust->setChecked(true); + _manualLODAdjust->setChecked(false); - updateLODValues(); // tell our LOD manager about the reset + updateAutomaticLODAdjust(); // tell our LOD manager about the reset } void LodToolsDialog::reject() { @@ -119,6 +115,15 @@ void LodToolsDialog::reject() { void LodToolsDialog::closeEvent(QCloseEvent* event) { this->QDialog::closeEvent(event); emit closed(); + auto lodManager = DependencyManager::get(); + + // always revert back to automatic LOD adjustment when closed + lodManager->setAutomaticLODAdjust(true); + + // if the user adjusted the LOD above "normal" then always revert back to default + if (lodManager->getOctreeSizeScale() > DEFAULT_OCTREE_SIZE_SCALE) { + lodManager->setOctreeSizeScale(DEFAULT_OCTREE_SIZE_SCALE); + } } diff --git a/interface/src/ui/LodToolsDialog.h b/interface/src/ui/LodToolsDialog.h index 91be04e0ed..e5a2dae836 100644 --- a/interface/src/ui/LodToolsDialog.h +++ b/interface/src/ui/LodToolsDialog.h @@ -34,7 +34,6 @@ public slots: void resetClicked(bool checked); void reloadSliders(); void updateAutomaticLODAdjust(); - void updateLODValues(); protected: @@ -44,7 +43,7 @@ protected: private: QSlider* _lodSize; - QCheckBox* _automaticLODAdjust; + QCheckBox* _manualLODAdjust; QDoubleSpinBox* _desktopLODDecreaseFPS; From 0e441261069f5b009931ec4c9d8ddaa7dbe0e74a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 24 Mar 2015 16:38:13 -0700 Subject: [PATCH 24/53] added LOD Warnings to notifications.js --- examples/defaultScripts.js | 1 - examples/hmdDefaults.js | 1 - examples/notifications.js | 36 ++++++++-- examples/utilities/LODWarning.js | 115 ------------------------------- 4 files changed, 31 insertions(+), 122 deletions(-) delete mode 100644 examples/utilities/LODWarning.js diff --git a/examples/defaultScripts.js b/examples/defaultScripts.js index f52d6be87e..05ffb0bd3f 100644 --- a/examples/defaultScripts.js +++ b/examples/defaultScripts.js @@ -18,4 +18,3 @@ Script.load("lobby.js"); Script.load("notifications.js"); Script.load("look.js"); Script.load("users.js"); -Script.load("utilities/LODWarning.js"); diff --git a/examples/hmdDefaults.js b/examples/hmdDefaults.js index 1e96d41713..0096b11777 100644 --- a/examples/hmdDefaults.js +++ b/examples/hmdDefaults.js @@ -13,5 +13,4 @@ Script.load("progress.js"); Script.load("lobby.js"); Script.load("notifications.js"); Script.load("controllers/oculus/goTo.js"); -Script.load("utilities/LODWarning.js"); //Script.load("scripts.js"); // Not created yet diff --git a/examples/notifications.js b/examples/notifications.js index 0c2a06c878..7e56c1b50d 100644 --- a/examples/notifications.js +++ b/examples/notifications.js @@ -43,7 +43,6 @@ // after that we will send it to createNotification(text). // If the message is 42 chars or less you should bypass wordWrap() and call createNotification() directly. - // To add a keypress driven notification: // // 1. Add a key to the keyPressEvent(key). @@ -85,16 +84,19 @@ var PLAY_NOTIFICATION_SOUNDS_MENU_ITEM = "Play Notification Sounds"; var NOTIFICATION_MENU_ITEM_POST = " Notifications"; var PLAY_NOTIFICATION_SOUNDS_SETTING = "play_notification_sounds"; var PLAY_NOTIFICATION_SOUNDS_TYPE_SETTING_PRE = "play_notification_sounds_type_"; +var lodTextID = false; var NotificationType = { UNKNOWN: 0, MUTE_TOGGLE: 1, SNAPSHOT: 2, WINDOW_RESIZE: 3, + LOD_WARNING: 4, properties: [ { text: "Mute Toggle" }, { text: "Snapshot" }, - { text: "Window Resize" } + { text: "Window Resize" }, + { text: "Level of Detail" } ], getTypeFromMenuItem: function(menuItemName) { if (menuItemName.substr(menuItemName.length - NOTIFICATION_MENU_ITEM_POST.length) !== NOTIFICATION_MENU_ITEM_POST) { @@ -143,6 +145,10 @@ function createArrays(notice, button, createTime, height, myAlpha) { // This handles the final dismissal of a notification after fading function dismiss(firstNoteOut, firstButOut, firstOut) { + if (firstNoteOut == lodTextID) { + lodTextID = false; + } + Overlays.deleteOverlay(firstNoteOut); Overlays.deleteOverlay(firstButOut); notifications.splice(firstOut, 1); @@ -261,7 +267,8 @@ function notify(notice, button, height) { height: noticeHeight }); } else { - notifications.push((Overlays.addOverlay("text", notice))); + var notificationText = Overlays.addOverlay("text", notice); + notifications.push((notificationText)); buttons.push((Overlays.addOverlay("image", button))); } @@ -272,6 +279,7 @@ function notify(notice, button, height) { last = notifications.length - 1; createArrays(notifications[last], buttons[last], times[last], heights[last], myAlpha[last]); fadeIn(notifications[last], buttons[last]); + return notificationText; } // This function creates and sizes the overlays @@ -331,11 +339,15 @@ function createNotification(text, notificationType) { randomSounds.playRandom(); } - notify(noticeProperties, buttonProperties, height); + return notify(noticeProperties, buttonProperties, height); } function deleteNotification(index) { - Overlays.deleteOverlay(notifications[index]); + var notificationTextID = notifications[index]; + if (notificationTextID == lodTextID) { + lodTextID = false; + } + Overlays.deleteOverlay(notificationTextID); Overlays.deleteOverlay(buttons[index]); notifications.splice(index, 1); buttons.splice(index, 1); @@ -575,6 +587,20 @@ function menuItemEvent(menuItem) { } } +LODManager.LODDecreased.connect(function() { + var warningText = "\n" + + "Due to the complexity of the content, the \n" + + "level of detail has been decreased." + + "You can now see: \n" + + LODManager.getLODFeedbackText(); + + if (lodTextID == false) { + lodTextID = createNotification(warningText, NotificationType.LOD_WARNING); + } else { + Overlays.editOverlay(lodTextID, { text: warningText }); + } +}); + AudioDevice.muteToggled.connect(onMuteStateChanged); Controller.keyPressEvent.connect(keyPressEvent); Controller.mousePressEvent.connect(mousePressEvent); diff --git a/examples/utilities/LODWarning.js b/examples/utilities/LODWarning.js deleted file mode 100644 index 644d98ebf4..0000000000 --- a/examples/utilities/LODWarning.js +++ /dev/null @@ -1,115 +0,0 @@ -// LODWarning.js -// examples -// -// Created by Brad Hefta-Gaub on 3/17/15. -// Copyright 2015 High Fidelity, Inc. -// -// This script will display a warning when the LOD is adjusted to do scene complexity. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -var DISPLAY_WARNING_FOR = 3; // in seconds -var DISTANCE_FROM_CAMERA = 2; -var SHOW_LOD_UP_MESSAGE = false; // By default we only display the LOD message when reducing LOD - - -var warningIsVisible = false; // initially the warning is hidden -var warningShownAt = 0; -var billboardPosition = Vec3.sum(Camera.getPosition(), - Vec3.multiply(DISTANCE_FROM_CAMERA, Quat.getFront(Camera.getOrientation()))); - -var warningOverlay = Overlays.addOverlay("text3d", { - position: billboardPosition, - dimensions: { x: 2, y: 1.25 }, - width: 2, - height: 1.25, - backgroundColor: { red: 0, green: 0, blue: 0 }, - color: { red: 255, green: 255, blue: 255}, - topMargin: 0.1, - leftMargin: 0.1, - lineHeight: 0.07, - text: "", - alpha: 0.5, - backgroundAlpha: 0.7, - isFacingAvatar: true, - visible: warningIsVisible, - }); - -// Handle moving the billboard to remain in front of the camera -var billboardNeedsMoving = false; -Script.update.connect(function() { - - if (warningIsVisible) { - var bestBillboardPosition = Vec3.sum(Camera.getPosition(), - Vec3.multiply(DISTANCE_FROM_CAMERA, Quat.getFront(Camera.getOrientation()))); - - var MAX_DISTANCE = 0.5; - var CLOSE_ENOUGH = 0.01; - if (!billboardNeedsMoving && Vec3.distance(bestBillboardPosition, billboardPosition) > MAX_DISTANCE) { - billboardNeedsMoving = true; - } - - if (billboardNeedsMoving && Vec3.distance(bestBillboardPosition, billboardPosition) <= CLOSE_ENOUGH) { - billboardNeedsMoving = false; - } - - if (billboardNeedsMoving) { - // slurp the billboard to the best location - moveVector = Vec3.multiply(0.05, Vec3.subtract(bestBillboardPosition, billboardPosition)); - billboardPosition = Vec3.sum(billboardPosition, moveVector); - Overlays.editOverlay(warningOverlay, { position: billboardPosition }); - } - - var now = new Date(); - var sinceWarningShown = now - warningShownAt; - if (sinceWarningShown > 1000 * DISPLAY_WARNING_FOR) { - warningIsVisible = false; - Overlays.editOverlay(warningOverlay, { visible: warningIsVisible }); - } - } -}); - -LODManager.LODIncreased.connect(function() { - if (SHOW_LOD_UP_MESSAGE) { - // if the warning wasn't visible, then move it before showing it. - if (!warningIsVisible) { - billboardPosition = Vec3.sum(Camera.getPosition(), - Vec3.multiply(DISTANCE_FROM_CAMERA, Quat.getFront(Camera.getOrientation()))); - Overlays.editOverlay(warningOverlay, { position: billboardPosition }); - } - - warningShownAt = new Date(); - warningIsVisible = true; - warningText = "Level of detail has been increased. \n" - + "You can now see: \n" - + LODManager.getLODFeedbackText(); - - Overlays.editOverlay(warningOverlay, { visible: warningIsVisible, text: warningText }); - } -}); - -LODManager.LODDecreased.connect(function() { - // if the warning wasn't visible, then move it before showing it. - if (!warningIsVisible) { - billboardPosition = Vec3.sum(Camera.getPosition(), - Vec3.multiply(DISTANCE_FROM_CAMERA, Quat.getFront(Camera.getOrientation()))); - Overlays.editOverlay(warningOverlay, { position: billboardPosition }); - } - - warningShownAt = new Date(); - warningIsVisible = true; - warningText = "\n" - + "Due to the complexity of the content, the \n" - + "level of detail has been decreased. \n" - + "You can now see: \n" - + LODManager.getLODFeedbackText(); - - Overlays.editOverlay(warningOverlay, { visible: warningIsVisible, text: warningText }); -}); - - -Script.scriptEnding.connect(function() { - Overlays.deleteOverlay(warningOverlay); -}); \ No newline at end of file From 44eca08fa488bf653dd06dd10f51ea798323385e Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 24 Mar 2015 17:38:35 -0700 Subject: [PATCH 25/53] PhysicsEngine doesn't need AvatarData MyAvatar now owns its CharacterController fix for bug of phantom collision obj when avatar's physics are disabled --- interface/src/Application.cpp | 7 +- interface/src/avatar/MyAvatar.cpp | 14 +- interface/src/avatar/MyAvatar.h | 11 + libraries/avatars/src/AvatarData.h | 13 - libraries/physics/src/CharacterController.cpp | 229 +++++++++++------- libraries/physics/src/CharacterController.h | 16 +- libraries/physics/src/PhysicsEngine.cpp | 43 +--- libraries/physics/src/PhysicsEngine.h | 4 +- 8 files changed, 197 insertions(+), 140 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4ff41e1b6f..418407282c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1903,8 +1903,6 @@ void Application::init() { _physicsEngine.init(&_entityEditSender); - _physicsEngine.setAvatarData(_myAvatar); - auto entityScriptingInterface = DependencyManager::get(); connect(&_physicsEngine, &EntitySimulation::entityCollisionWithEntity, @@ -2191,6 +2189,7 @@ void Application::update(float deltaTime) { { PerformanceTimer perfTimer("physics"); + _myAvatar->preSimulation(); _physicsEngine.stepSimulation(); } @@ -4207,7 +4206,7 @@ void Application::checkSkeleton() { _myAvatar->setSkeletonModelURL(DEFAULT_BODY_MODEL_URL); _myAvatar->sendIdentityPacket(); } else { - _myAvatar->updateLocalAABox(); - _physicsEngine.setAvatarData(_myAvatar); + _myAvatar->updateCharacterController(); + _physicsEngine.setCharacterController(_myAvatar->getCharacterController()); } } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ab4989a651..e0de24247e 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -82,6 +82,8 @@ MyAvatar::MyAvatar() : _scriptedMotorTimescale(DEFAULT_SCRIPTED_MOTOR_TIMESCALE), _scriptedMotorFrame(SCRIPTED_MOTOR_CAMERA_FRAME), _motionBehaviors(AVATAR_MOTION_DEFAULTS), + _characterController(this), + _enablePhysics(false), _lookAtTargetAvatar(), _shouldRender(true), _billboardValid(false), @@ -954,15 +956,15 @@ glm::vec3 MyAvatar::getSkeletonPosition() const { return Avatar::getPosition(); } -void MyAvatar::updateLocalAABox() { +void MyAvatar::updateCharacterController() { + // compute localAABox const CapsuleShape& capsule = _skeletonModel.getBoundingShape(); float radius = capsule.getRadius(); float height = 2.0f * (capsule.getHalfHeight() + radius); - glm::vec3 offset = _skeletonModel.getBoundingShapeOffset(); glm::vec3 corner(-radius, -0.5f * height, -radius); - corner += offset; + corner += _skeletonModel.getBoundingShapeOffset(); glm::vec3 scale(2.0f * radius, height, 2.0f * radius); - _localAABox.setBox(corner, scale); + _characterController.setLocalBoundingBox(corner, scale); } QString MyAvatar::getScriptedMotorFrame() const { @@ -1580,6 +1582,10 @@ glm::vec3 MyAvatar::getLaserPointerTipPosition(const PalmData* palm) { return palm->getPosition(); } +void MyAvatar::preSimulation() { + _characterController.setEnabled(_enablePhysics); +} + void MyAvatar::clearDriveKeys() { for (int i = 0; i < MAX_DRIVE_KEYS; ++i) { _driveKeys[i] = 0.0f; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 08c0228f1e..1b2b2f5e46 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -13,6 +13,7 @@ #define hifi_MyAvatar_h #include +#include #include "Avatar.h" @@ -122,6 +123,8 @@ public: virtual glm::vec3 getSkeletonPosition() const; void updateLocalAABox(); + CharacterController* getCharacterController() { return &_characterController; } + void updateCharacterController(); void clearJointAnimationPriorities(); @@ -145,6 +148,11 @@ public: const RecorderPointer getRecorder() const { return _recorder; } const PlayerPointer getPlayer() const { return _player; } + + void togglePhysicsEnabled() { _enablePhysics = !_enablePhysics; } + bool isPhysicsEnabled() { return _enablePhysics; } + void setPhysicsEnabled(bool enablePhysics) { _enablePhysics = enablePhysics; } + void preSimulation(); public slots: void increaseSize(); @@ -202,6 +210,9 @@ private: int _scriptedMotorFrame; quint32 _motionBehaviors; + bool _enablePhysics; + CharacterController _characterController; + QWeakPointer _lookAtTargetAvatar; glm::vec3 _targetAvatarPosition; bool _shouldRender; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 28123124a0..a2feb98798 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -300,16 +300,6 @@ public: const AABox& getLocalAABox() const { return _localAABox; } const Referential* getReferential() const { return _referential; } - void togglePhysicsEnabled() { _enablePhysics = !_enablePhysics; } - bool isPhysicsEnabled() { return _enablePhysics; } - void setPhysicsEnabled(bool enablePhysics) { _enablePhysics = enablePhysics; } - - void lockForRead() { _lock.lockForRead(); } - bool tryLockForRead() { return _lock.tryLockForRead(); } - void lockForWrite() { _lock.lockForWrite(); } - bool tryLockForWrite() { return _lock.tryLockForWrite(); } - void unlock() { _lock.unlock(); } - void setVelocity(const glm::vec3 velocity) { _velocity = velocity; } Q_INVOKABLE glm::vec3 getVelocity() const { return _velocity; } @@ -409,9 +399,6 @@ private: // privatize the copy constructor and assignment operator so they cannot be called AvatarData(const AvatarData&); AvatarData& operator= (const AvatarData&); - - QReadWriteLock _lock; - bool _enablePhysics = false; }; Q_DECLARE_METATYPE(AvatarData*) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index d0b083fc01..be10cd1f54 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -21,6 +21,12 @@ subject to the following restrictions: #include "BulletUtil.h" #include "CharacterController.h" +const uint32_t PENDING_FLAG_ADD_TO_SIMULATION = 1U << 0; +const uint32_t PENDING_FLAG_REMOVE_FROM_SIMULATION = 1U << 1; +//const uint32_t PENDING_FLAG_ENABLE = 1U << 0; +//const uint32_t PENDING_FLAG_DISABLE = 1U << 1; +const uint32_t PENDING_FLAG_UPDATE_SHAPE = 1U << 2; +const uint32_t PENDING_FLAG_JUMP = 1U << 4; // static helper method static btVector3 getNormalizedVector(const btVector3& v) { @@ -223,11 +229,10 @@ CharacterController::CharacterController(AvatarData* avatarData) { _avatarData = avatarData; // cache the "PhysicsEnabled" state of _avatarData - _avatarData->lockForRead(); - _enabled = _avatarData->isPhysicsEnabled(); - _avatarData->unlock(); + _enabled = false; - createShapeAndGhost(); + _ghostObject = NULL; + _convexShape = NULL; _addedMargin = 0.02f; _walkDirection.setValue(0.0f,0.0f,0.0f); @@ -242,6 +247,7 @@ CharacterController::CharacterController(AvatarData* avatarData) { _wasJumping = false; setMaxSlope(btRadians(45.0f)); _lastStepUp = 0.0f; + _pendingFlags = 0; } CharacterController::~CharacterController() { @@ -349,7 +355,7 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl return penetration; } -void CharacterController::stepUp( btCollisionWorld* world) { +void CharacterController::stepUp(btCollisionWorld* world) { // phase 1: up // compute start and end @@ -416,7 +422,7 @@ void CharacterController::updateTargetPositionBasedOnCollision(const btVector3& } } -void CharacterController::stepForward( btCollisionWorld* collisionWorld, const btVector3& movement) { +void CharacterController::stepForward(btCollisionWorld* collisionWorld, const btVector3& movement) { // phase 2: forward _targetPosition = _currentPosition + movement; @@ -472,7 +478,7 @@ void CharacterController::stepForward( btCollisionWorld* collisionWorld, const b _convexShape->setMargin(margin); } -void CharacterController::stepDown( btCollisionWorld* collisionWorld, btScalar dt) { +void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt) { // phase 3: down // // The "stepDown" phase first makes a normal sweep down that cancels the lift from the "stepUp" phase. @@ -558,7 +564,7 @@ void CharacterController::setVelocityForTimeInterval(const btVector3& velocity, _velocityTimeInterval += timeInterval; } -void CharacterController::reset( btCollisionWorld* collisionWorld ) { +void CharacterController::reset(btCollisionWorld* collisionWorld) { _verticalVelocity = 0.0; _verticalOffset = 0.0; _wasOnGround = false; @@ -583,7 +589,7 @@ void CharacterController::warp(const btVector3& origin) { } -void CharacterController::preStep( btCollisionWorld* collisionWorld) { +void CharacterController::preStep(btCollisionWorld* collisionWorld) { if (!_enabled) { return; } @@ -603,7 +609,7 @@ void CharacterController::preStep( btCollisionWorld* collisionWorld) { _targetPosition = _currentPosition; } -void CharacterController::playerStep( btCollisionWorld* collisionWorld, btScalar dt) { +void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar dt) { if (!_enabled || (!_useWalkDirection && _velocityTimeInterval <= 0.0)) { return; // no motion } @@ -710,106 +716,163 @@ void CharacterController::setUpInterpolate(bool value) { // (interpolate = true, and now default behavior) or happily penetrate objects above the avatar. } +/* // protected void CharacterController::createShapeAndGhost() { // get new dimensions from avatar - _avatarData->lockForRead(); - AABox box = _avatarData->getLocalAABox(); - - // create new ghost - _ghostObject = new btPairCachingGhostObject(); - _ghostObject->setWorldTransform(btTransform(glmToBullet(_avatarData->getOrientation()), - glmToBullet(_avatarData->getPosition()))); - _avatarData->unlock(); - - const glm::vec3& diagonal = box.getScale(); - _radius = 0.5f * sqrtf(0.5f * (diagonal.x * diagonal.x + diagonal.z * diagonal.z)); - _halfHeight = 0.5f * diagonal.y - _radius; + float x = _boxScale.x; + float z = _boxScale.z; + _radius = 0.5f * sqrtf(0.5f * (x * x + z * z)); + _halfHeight = 0.5f * _boxScale.y - _radius; float MIN_HALF_HEIGHT = 0.1f; if (_halfHeight < MIN_HALF_HEIGHT) { _halfHeight = MIN_HALF_HEIGHT; } - glm::vec3 offset = box.getCorner() + 0.5f * diagonal; - _shapeLocalOffset = offset; + // NOTE: _shapeLocalOffset is already computed - // stepHeight affects the heights of ledges that the character can ascend - // however the actual ledge height is some function of _stepHeight - // due to character shape and this CharacterController algorithm - // (the function is approximately 2*_stepHeight) - _stepHeight = 0.1f * (_radius + _halfHeight) + 0.1f; - - // create new shape - _convexShape = new btCapsuleShape(_radius, 2.0f * _halfHeight); - _ghostObject->setCollisionShape(_convexShape); - _ghostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT); + if (_radius > 0.0f) { + // create new ghost + _ghostObject = new btPairCachingGhostObject(); + _ghostObject->setWorldTransform(btTransform(glmToBullet(_avatarData->getOrientation()), + glmToBullet(_avatarData->getPosition()))); + // stepHeight affects the heights of ledges that the character can ascend + // however the actual ledge height is some function of _stepHeight + // due to character shape and this CharacterController algorithm + // (the function is approximately 2*_stepHeight) + _stepHeight = 0.1f * (_radius + _halfHeight) + 0.1f; + + // create new shape + _convexShape = new btCapsuleShape(_radius, 2.0f * _halfHeight); + _ghostObject->setCollisionShape(_convexShape); + _ghostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT); + } else { + // TODO: handle this failure case + } + _pendingFlags &= ~ PENDING_FLAG_UPDATE_SHAPE; } +*/ -bool CharacterController::needsShapeUpdate() { - // get new dimensions from avatar - _avatarData->lockForRead(); - AABox box = _avatarData->getLocalAABox(); - _avatarData->unlock(); +void CharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) { + _boxScale = scale; - const glm::vec3& diagonal = box.getScale(); - float radius = 0.5f * sqrtf(0.5f * (diagonal.x * diagonal.x + diagonal.z * diagonal.z)); - float halfHeight = 0.5f * diagonal.y - radius; + float x = _boxScale.x; + float z = _boxScale.z; + float radius = 0.5f * sqrtf(0.5f * (x * x + z * z)); + float halfHeight = 0.5f * _boxScale.y - radius; float MIN_HALF_HEIGHT = 0.1f; if (halfHeight < MIN_HALF_HEIGHT) { halfHeight = MIN_HALF_HEIGHT; } - glm::vec3 offset = box.getCorner() + 0.5f * diagonal; - // compare dimensions (and offset) + // compare dimensions float radiusDelta = glm::abs(radius - _radius); float heightDelta = glm::abs(halfHeight - _halfHeight); if (radiusDelta < FLT_EPSILON && heightDelta < FLT_EPSILON) { // shape hasn't changed --> nothing to do - float offsetDelta = glm::distance(offset, _shapeLocalOffset); - if (offsetDelta > FLT_EPSILON) { - // if only the offset changes then we can update it --> no need to rebuild shape - _shapeLocalOffset = offset; - } - return false; + } else { + // we need to: remove, update, add + _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION + | PENDING_FLAG_UPDATE_SHAPE + | PENDING_FLAG_ADD_TO_SIMULATION; + } + + // it's ok to change offset immediately -- there are no thread safety issues here + _shapeLocalOffset = corner + 0.5f * _boxScale; +} + +bool CharacterController::needsAddition() const { + return (bool)(_pendingFlags & PENDING_FLAG_ADD_TO_SIMULATION); +} + +bool CharacterController::needsRemoval() const { + return (bool)(_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION); +} + +void CharacterController::setEnabled(bool enabled) { + if (enabled != _enabled) { + if (enabled) { + _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION; + } else { + _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION; + _pendingFlags &= ~ PENDING_FLAG_ADD_TO_SIMULATION; + } + _enabled = enabled; + } +} + +void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { + if (_dynamicsWorld != world) { + if (_dynamicsWorld) { + _dynamicsWorld->removeCollisionObject(getGhostObject()); + _dynamicsWorld->removeAction(this); + } + _dynamicsWorld = world; + if (_dynamicsWorld) { + _pendingFlags &= ~ PENDING_FLAG_ADD_TO_SIMULATION; + _dynamicsWorld->addCollisionObject(getGhostObject(), + btBroadphaseProxy::CharacterFilter, + btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter); + _dynamicsWorld->addAction(this); + reset(_dynamicsWorld); + } else { + _pendingFlags &= ~ PENDING_FLAG_REMOVE_FROM_SIMULATION; + } + } else { + _pendingFlags &= ~ (PENDING_FLAG_REMOVE_FROM_SIMULATION | PENDING_FLAG_ADD_TO_SIMULATION); } - return true; } void CharacterController::updateShape() { - // DANGER: make sure this CharacterController and its GhostShape have been removed from - // the PhysicsEngine before calling this. - - // delete shape and GhostObject - delete _ghostObject; - _ghostObject = NULL; - delete _convexShape; - _convexShape = NULL; - - createShapeAndGhost(); + if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { + assert(!(_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION)); + _pendingFlags &= ~ PENDING_FLAG_UPDATE_SHAPE; + // make sure there is NO pending removal from simulation at this point + // (don't want to delete _ghostObject out from under the simulation) + // delete shape and GhostObject + delete _ghostObject; + _ghostObject = NULL; + delete _convexShape; + _convexShape = NULL; + + // compute new dimensions from avatar's bounding box + float x = _boxScale.x; + float z = _boxScale.z; + _radius = 0.5f * sqrtf(0.5f * (x * x + z * z)); + _halfHeight = 0.5f * _boxScale.y - _radius; + float MIN_HALF_HEIGHT = 0.1f; + if (_halfHeight < MIN_HALF_HEIGHT) { + _halfHeight = MIN_HALF_HEIGHT; + } + // NOTE: _shapeLocalOffset is already computed + + if (_radius > 0.0f) { + // create new ghost + _ghostObject = new btPairCachingGhostObject(); + _ghostObject->setWorldTransform(btTransform(glmToBullet(_avatarData->getOrientation()), + glmToBullet(_avatarData->getPosition()))); + // stepHeight affects the heights of ledges that the character can ascend + // however the actual ledge height is some function of _stepHeight + // due to character shape and this CharacterController algorithm + // (the function is approximately 2*_stepHeight) + _stepHeight = 0.1f * (_radius + _halfHeight) + 0.1f; + + // create new shape + _convexShape = new btCapsuleShape(_radius, 2.0f * _halfHeight); + _ghostObject->setCollisionShape(_convexShape); + _ghostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT); + } else { + // TODO: handle this failure case + } + } } void CharacterController::preSimulation(btScalar timeStep) { - bool wasEnabled = _enabled; + if (_enabled && _dynamicsWorld) { + glm::quat rotation = _avatarData->getOrientation(); + glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset; + // TODO: harvest jump event here + btVector3 walkVelocity = glmToBullet(_avatarData->getVelocity()); - // lock avatarData, get everything we need from it ASAP, then unlock - _avatarData->lockForRead(); - _enabled = _avatarData->isPhysicsEnabled(); - glm::quat rotation = _avatarData->getOrientation(); - glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset; - // TODO: Andrew to implement: harvest jump event here - btVector3 walkVelocity = glmToBullet(_avatarData->getVelocity()); - - _avatarData->unlock(); - - if (wasEnabled != _enabled) { - if (_enabled) { - // TODO: Andrew to implement: add collision shape back into world - } else { - // TODO: Andrew to implement: remove collision shape from world, - // otherwise things will continue to collide with it - } - } - - if (_enabled) { _ghostObject->setWorldTransform(btTransform(glmToBullet(rotation), glmToBullet(position))); setVelocityForTimeInterval(walkVelocity, timeStep); } @@ -817,13 +880,11 @@ void CharacterController::preSimulation(btScalar timeStep) { void CharacterController::postSimulation() { if (_enabled) { - _avatarData->lockForWrite(); const btTransform& avatarTransform = _ghostObject->getWorldTransform(); glm::quat rotation = bulletToGLM(avatarTransform.getRotation()); glm::vec3 offset = rotation * _shapeLocalOffset; _avatarData->setOrientation(rotation); _avatarData->setPosition(bulletToGLM(avatarTransform.getOrigin()) - offset); - _avatarData->unlock(); } } diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index b6109eb0ff..9803d0d6ee 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -37,13 +37,13 @@ class btPairCachingGhostObject; ///It uses a ghost object and convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations. ///Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user. + ATTRIBUTE_ALIGNED16(class) CharacterController : public btCharacterControllerInterface { protected: AvatarData* _avatarData = NULL; btPairCachingGhostObject* _ghostObject; - glm::vec3 _shapeLocalOffset; btConvexShape* _convexShape;//is also in _ghostObject, but it needs to be convex, so we store it here to avoid upcast btScalar _radius; @@ -83,6 +83,12 @@ protected: bool _wasJumping; bool _useWalkDirection; btScalar _velocityTimeInterval; + uint32_t _pendingFlags; + + glm::vec3 _shapeLocalOffset; + glm::vec3 _boxScale; // used to compute capsule shape + + btDynamicsWorld* _dynamicsWorld = NULL; btVector3 computeReflectionDirection(const btVector3& direction, const btVector3& normal); btVector3 parallelComponent(const btVector3& direction, const btVector3& normal); @@ -152,7 +158,13 @@ public: bool onGround() const; void setUpInterpolate(bool value); - bool needsShapeUpdate(); + bool needsRemoval() const; + bool needsAddition() const; + void setEnabled(bool enabled); + void setDynamicsWorld(btDynamicsWorld* world); + + void setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale); + bool needsShapeUpdate() const; void updateShape(); void preSimulation(btScalar timeStep); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 447a3ab6f1..bcde3318ad 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -280,12 +280,12 @@ void PhysicsEngine::init(EntityEditPacketSender* packetSender) { void PhysicsEngine::stepSimulation() { lock(); // NOTE: the grand order of operations is: - // (1) relay incoming changes + // (1) pull incoming changes // (2) step simulation // (3) synchronize outgoing motion states // (4) send outgoing packets - // This is step (1). + // This is step (1) pull incoming changes relayIncomingChangesToSimulation(); const int MAX_NUM_SUBSTEPS = 4; @@ -296,10 +296,17 @@ void PhysicsEngine::stepSimulation() { // TODO: move character->preSimulation() into relayIncomingChanges if (_characterController) { + if (_characterController->needsRemoval()) { + _characterController->setDynamicsWorld(NULL); + } + _characterController->updateShape(); + if (_characterController->needsAddition()) { + _characterController->setDynamicsWorld(_dynamicsWorld); + } _characterController->preSimulation(timeStep); } - // This is step (2). + // This is step (2) step simulation int numSubsteps = _dynamicsWorld->stepSimulation(timeStep, MAX_NUM_SUBSTEPS, PHYSICS_ENGINE_FIXED_SUBSTEP); _numSubsteps += (uint32_t)numSubsteps; stepNonPhysicalKinematics(usecTimestampNow()); @@ -600,34 +607,10 @@ bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio return true; } -void PhysicsEngine::setAvatarData(AvatarData *avatarData) { - if (_characterController) { - bool needsShapeUpdate = _characterController->needsShapeUpdate(); - if (needsShapeUpdate) { - lock(); - // remove old info - _dynamicsWorld->removeCollisionObject(_characterController->getGhostObject()); - _dynamicsWorld->removeAction(_characterController); - // update shape - _characterController->updateShape(); - // insert new info - _dynamicsWorld->addCollisionObject(_characterController->getGhostObject(), - btBroadphaseProxy::CharacterFilter, - btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter); - _dynamicsWorld->addAction(_characterController); - _characterController->reset(_dynamicsWorld); - unlock(); - } - } else { - // initialize _characterController - assert(avatarData); // don't pass NULL argument +void PhysicsEngine::setCharacterController(CharacterController* character) { + if (!_characterController) { lock(); - _characterController = new CharacterController(avatarData); - _dynamicsWorld->addCollisionObject(_characterController->getGhostObject(), - btBroadphaseProxy::CharacterFilter, - btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter); - _dynamicsWorld->addAction(_characterController); - _characterController->reset(_dynamicsWorld); + _characterController = character; unlock(); } } diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index cb637c60b9..0661b47d3a 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -17,9 +17,7 @@ #include #include #include -//#include -#include #include #include @@ -86,7 +84,7 @@ public: /// process queue of changed from external sources void relayIncomingChangesToSimulation(); - void setAvatarData(AvatarData *avatarData); + void setCharacterController(CharacterController* character); private: /// \param motionState pointer to Object's MotionState From d49762097686af6b9400383367d8c66e6df77430 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 24 Mar 2015 23:05:46 -0700 Subject: [PATCH 26/53] avatar can jump with E key when walking --- interface/src/avatar/MyAvatar.cpp | 3 +- interface/src/avatar/MyAvatar.h | 3 +- libraries/physics/src/CharacterController.cpp | 139 ++++-------------- libraries/physics/src/CharacterController.h | 17 +-- 4 files changed, 39 insertions(+), 123 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e0de24247e..2f42544f28 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -70,7 +70,6 @@ MyAvatar::MyAvatar() : Avatar(), _turningKeyPressTime(0.0f), _gravity(0.0f, 0.0f, 0.0f), - _shouldJump(false), _wasPushing(false), _isPushing(false), _isBraking(false), @@ -82,8 +81,8 @@ MyAvatar::MyAvatar() : _scriptedMotorTimescale(DEFAULT_SCRIPTED_MOTOR_TIMESCALE), _scriptedMotorFrame(SCRIPTED_MOTOR_CAMERA_FRAME), _motionBehaviors(AVATAR_MOTION_DEFAULTS), - _characterController(this), _enablePhysics(false), + _characterController(this), _lookAtTargetAvatar(), _shouldRender(true), _billboardValid(false), diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 1b2b2f5e46..a37d1c6a30 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -89,7 +89,7 @@ public: void clearDriveKeys(); void setDriveKeys(int key, float val) { _driveKeys[key] = val; }; bool getDriveKeys(int key) { return _driveKeys[key] != 0.0f; }; - void jump() { _shouldJump = true; }; + void jump() { _characterController.jump(); } bool isMyAvatar() { return true; } @@ -194,7 +194,6 @@ private: float _turningKeyPressTime; glm::vec3 _gravity; - bool _shouldJump; float _driveKeys[MAX_DRIVE_KEYS]; bool _wasPushing; bool _isPushing; diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index be10cd1f54..fa02f81e34 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -23,10 +23,8 @@ subject to the following restrictions: const uint32_t PENDING_FLAG_ADD_TO_SIMULATION = 1U << 0; const uint32_t PENDING_FLAG_REMOVE_FROM_SIMULATION = 1U << 1; -//const uint32_t PENDING_FLAG_ENABLE = 1U << 0; -//const uint32_t PENDING_FLAG_DISABLE = 1U << 1; const uint32_t PENDING_FLAG_UPDATE_SHAPE = 1U << 2; -const uint32_t PENDING_FLAG_JUMP = 1U << 4; +const uint32_t PENDING_FLAG_JUMP = 1U << 3; // static helper method static btVector3 getNormalizedVector(const btVector3& v) { @@ -41,34 +39,6 @@ static btVector3 getNormalizedVector(const btVector3& v) { return n; } -///@todo Interact with dynamic objects, -///Ride kinematicly animated platforms properly -///More realistic (or maybe just a config option) falling -/// -> Should integrate falling velocity manually and use that in stepDown() -///Support jumping -///Support ducking - -/* This callback is unused, but we're keeping it around just in case we figure out how to use it. -class btKinematicClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback -{ -public: -btKinematicClosestNotMeRayResultCallback(btCollisionObject* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) -{ -_me = me; -} - -virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) -{ -if (rayResult.m_collisionObject == _me) -return 1.0; - -return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace); -} -protected: -btCollisionObject* _me; -}; -*/ - class btKinematicClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback { public: btKinematicClosestNotMeConvexResultCallback(btCollisionObject* me, const btVector3& up, btScalar minSlopeDot) @@ -236,13 +206,12 @@ CharacterController::CharacterController(AvatarData* avatarData) { _addedMargin = 0.02f; _walkDirection.setValue(0.0f,0.0f,0.0f); - _useWalkDirection = true; // use walk direction by default, legacy behavior _velocityTimeInterval = 0.0f; _verticalVelocity = 0.0f; _verticalOffset = 0.0f; _gravity = 9.8f; _maxFallSpeed = 55.0f; // Terminal velocity of a sky diver in m/s. - _jumpSpeed = 10.0f; // ? + _jumpSpeed = 7.0f; _wasOnGround = false; _wasJumping = false; setMaxSlope(btRadians(45.0f)); @@ -485,14 +454,9 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt // If it hits a ledge then it stops otherwise it makes another sweep down in search of a floor within // reach of the character's feet. - btScalar downSpeed = (_verticalVelocity < 0.0f) ? -_verticalVelocity : 0.0f; - if (downSpeed > 0.0f && downSpeed > _maxFallSpeed && (_wasOnGround || !_wasJumping)) { - downSpeed = _maxFallSpeed; - } - // first sweep for ledge btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); - btVector3 step = up * (-(_lastStepUp + downSpeed * dt)); + btVector3 step = (_verticalVelocity * dt - _lastStepUp) * up; StepDownConvexResultCallback callback(_ghostObject, up, @@ -517,7 +481,7 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt _verticalVelocity = 0.0f; _verticalOffset = 0.0f; _wasJumping = false; - } else { + } else if (!_wasJumping) { // sweep again for floor within downStep threshold StepDownConvexResultCallback callback2 (_ghostObject, up, @@ -548,17 +512,19 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt _currentPosition = oldPosition - _lastStepUp * up; _lastStepUp = 0.0f; } + } else { + // we're jumping, and didn't hit anything, so our target position is where we would have fallen to + _currentPosition = _targetPosition; } } void CharacterController::setWalkDirection(const btVector3& walkDirection) { - _useWalkDirection = true; - _walkDirection = walkDirection; - _normalizedDirection = getNormalizedVector(_walkDirection); + // This must be implemented to satisfy base-class interface but does nothing. + // Use setVelocityForTimeInterval() instead. + assert(false); } void CharacterController::setVelocityForTimeInterval(const btVector3& velocity, btScalar timeInterval) { - _useWalkDirection = false; _walkDirection = velocity; _normalizedDirection = getNormalizedVector(_walkDirection); _velocityTimeInterval += timeInterval; @@ -610,7 +576,7 @@ void CharacterController::preStep(btCollisionWorld* collisionWorld) { } void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar dt) { - if (!_enabled || (!_useWalkDirection && _velocityTimeInterval <= 0.0)) { + if (!_enabled) { return; // no motion } @@ -634,17 +600,15 @@ void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar // (3) step the character down looking for new ledges, the original floor, or a floor one step below where we started stepUp(collisionWorld); - if (_useWalkDirection) { - stepForward(collisionWorld, _walkDirection); - } else { - // compute substep and decrement total interval - btScalar dtMoving = (dt < _velocityTimeInterval) ? dt : _velocityTimeInterval; - _velocityTimeInterval -= dt; - // stepForward substep - btVector3 move = _walkDirection * dtMoving; - stepForward(collisionWorld, move); - } + // compute substep and decrement total interval + btScalar dtMoving = (dt < _velocityTimeInterval) ? dt : _velocityTimeInterval; + _velocityTimeInterval -= dt; + + // stepForward substep + btVector3 move = _walkDirection * dtMoving; + stepForward(collisionWorld, move); + stepDown(collisionWorld, dt); xform.setOrigin(_currentPosition); @@ -668,22 +632,7 @@ bool CharacterController::canJump() const { } void CharacterController::jump() { - if (!canJump()) { - return; - } - - _verticalVelocity = _jumpSpeed; - _wasJumping = true; - -#if 0 - currently no jumping. - btTransform xform; - _rigidBody->getMotionState()->getWorldTransform(xform); - btVector3 up = xform.getBasis()[1]; - up.normalize(); - btScalar magnitude = (btScalar(1.0)/_rigidBody->getInvMass()) * btScalar(8.0); - _rigidBody->applyCentralImpulse (up * magnitude); -#endif + _pendingFlags |= PENDING_FLAG_JUMP; } void CharacterController::setGravity(btScalar gravity) { @@ -704,7 +653,7 @@ btScalar CharacterController::getMaxSlope() const { } bool CharacterController::onGround() const { - return _enabled && _verticalVelocity == 0.0 && _verticalOffset == 0.0; + return _enabled && _verticalVelocity == 0.0f && _verticalOffset == 0.0f; } void CharacterController::debugDraw(btIDebugDraw* debugDrawer) { @@ -716,42 +665,6 @@ void CharacterController::setUpInterpolate(bool value) { // (interpolate = true, and now default behavior) or happily penetrate objects above the avatar. } -/* -// protected -void CharacterController::createShapeAndGhost() { - // get new dimensions from avatar - float x = _boxScale.x; - float z = _boxScale.z; - _radius = 0.5f * sqrtf(0.5f * (x * x + z * z)); - _halfHeight = 0.5f * _boxScale.y - _radius; - float MIN_HALF_HEIGHT = 0.1f; - if (_halfHeight < MIN_HALF_HEIGHT) { - _halfHeight = MIN_HALF_HEIGHT; - } - // NOTE: _shapeLocalOffset is already computed - - if (_radius > 0.0f) { - // create new ghost - _ghostObject = new btPairCachingGhostObject(); - _ghostObject->setWorldTransform(btTransform(glmToBullet(_avatarData->getOrientation()), - glmToBullet(_avatarData->getPosition()))); - // stepHeight affects the heights of ledges that the character can ascend - // however the actual ledge height is some function of _stepHeight - // due to character shape and this CharacterController algorithm - // (the function is approximately 2*_stepHeight) - _stepHeight = 0.1f * (_radius + _halfHeight) + 0.1f; - - // create new shape - _convexShape = new btCapsuleShape(_radius, 2.0f * _halfHeight); - _ghostObject->setCollisionShape(_convexShape); - _ghostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT); - } else { - // TODO: handle this failure case - } - _pendingFlags &= ~ PENDING_FLAG_UPDATE_SHAPE; -} -*/ - void CharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) { _boxScale = scale; @@ -808,7 +721,7 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { } _dynamicsWorld = world; if (_dynamicsWorld) { - _pendingFlags &= ~ PENDING_FLAG_ADD_TO_SIMULATION; + _pendingFlags &= ~ (PENDING_FLAG_ADD_TO_SIMULATION | PENDING_FLAG_JUMP); _dynamicsWorld->addCollisionObject(getGhostObject(), btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter); @@ -870,11 +783,17 @@ void CharacterController::preSimulation(btScalar timeStep) { if (_enabled && _dynamicsWorld) { glm::quat rotation = _avatarData->getOrientation(); glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset; - // TODO: harvest jump event here btVector3 walkVelocity = glmToBullet(_avatarData->getVelocity()); _ghostObject->setWorldTransform(btTransform(glmToBullet(rotation), glmToBullet(position))); setVelocityForTimeInterval(walkVelocity, timeStep); + if (_pendingFlags & PENDING_FLAG_JUMP) { + _pendingFlags &= ~ PENDING_FLAG_JUMP; + if (canJump()) { + _verticalVelocity = _jumpSpeed; + _wasJumping = true; + } + } } } diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index 9803d0d6ee..598bc866d5 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -81,7 +81,6 @@ protected: bool _enabled; bool _wasOnGround; bool _wasJumping; - bool _useWalkDirection; btScalar _velocityTimeInterval; uint32_t _pendingFlags; @@ -132,18 +131,19 @@ public: virtual void setVelocityForTimeInterval(const btVector3& velocity, btScalar timeInterval); - void reset(btCollisionWorld* collisionWorld ); - void warp(const btVector3& origin); + virtual void reset(btCollisionWorld* collisionWorld ); + virtual void warp(const btVector3& origin); - void preStep(btCollisionWorld* collisionWorld); - void playerStep(btCollisionWorld* collisionWorld, btScalar dt); + virtual void preStep(btCollisionWorld* collisionWorld); + virtual void playerStep(btCollisionWorld* collisionWorld, btScalar dt); + + virtual bool canJump() const; + virtual void jump(); + virtual bool onGround() const; void setMaxFallSpeed(btScalar speed); void setJumpSpeed(btScalar jumpSpeed); void setMaxJumpHeight(btScalar maxJumpHeight); - bool canJump() const; - - void jump(); void setGravity(btScalar gravity); btScalar getGravity() const; @@ -155,7 +155,6 @@ public: btPairCachingGhostObject* getGhostObject(); - bool onGround() const; void setUpInterpolate(bool value); bool needsRemoval() const; From 430158c1095ed8c191d3d731bf083ffdbd8d269f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 24 Mar 2015 23:35:09 -0700 Subject: [PATCH 27/53] updateShapeIfNecessary() is a more correct name --- libraries/physics/src/CharacterController.cpp | 2 +- libraries/physics/src/CharacterController.h | 2 +- libraries/physics/src/PhysicsEngine.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index fa02f81e34..c26ffa3339 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -735,7 +735,7 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { } } -void CharacterController::updateShape() { +void CharacterController::updateShapeIfNecessary() { if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { assert(!(_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION)); _pendingFlags &= ~ PENDING_FLAG_UPDATE_SHAPE; diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index 598bc866d5..740940ce53 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -164,7 +164,7 @@ public: void setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale); bool needsShapeUpdate() const; - void updateShape(); + void updateShapeIfNecessary(); void preSimulation(btScalar timeStep); void postSimulation(); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index bcde3318ad..9ca718e19a 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -299,7 +299,7 @@ void PhysicsEngine::stepSimulation() { if (_characterController->needsRemoval()) { _characterController->setDynamicsWorld(NULL); } - _characterController->updateShape(); + _characterController->updateShapeIfNecessary(); if (_characterController->needsAddition()) { _characterController->setDynamicsWorld(_dynamicsWorld); } From 92d394404463012c6c2ef9e05d774545c4efa725 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 25 Mar 2015 15:01:22 +0100 Subject: [PATCH 28/53] Use preOp function for all common checks/updates --- examples/entityScripts/lightController.js | 70 ++++++++++++++--------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/examples/entityScripts/lightController.js b/examples/entityScripts/lightController.js index 624fc929b3..1ff41df16c 100644 --- a/examples/entityScripts/lightController.js +++ b/examples/entityScripts/lightController.js @@ -4,6 +4,27 @@ this.lightID = null; this.sound = null; + var DEFAULT_USER_DATA = { + creatingLight: false, + lightID: null, + lightDefaultProperties: { + type: "Light", + position: { x: 0, y: 0, z: 0 }, + dimensions: { x: 5, y: 5, z: 5 }, + isSpotlight: false, + color: { red: 255, green: 48, blue: 0 }, + diffuseColor: { red: 255, green: 255, blue: 255 }, + ambientColor: { red: 255, green: 255, blue: 255 }, + specularColor: { red: 0, green: 0, blue: 0 }, + constantAttenuation: 1, + linearAttenuation: 0, + quadraticAttenuation: 0, + intensity: 10, + exponent: 0, + cutoff: 180, // in degrees + } + }; + function copyObject(object) { return JSON.parse(JSON.stringify(object)); } @@ -30,6 +51,19 @@ Entities.editEntity(entityID, { userData: JSON.stringify(userData) }); } + // Checks whether the userData is well-formed and updates it if not + this.checkUserData = function() { + var userData = getUserData(this.entityID); + if (!userData) { + userData = DEFAULT_USER_DATA; + } else if (!userData.lightDefaultProperties) { + userData.lightDefaultProperties = DEFAULT_USER_DATA.lightDefaultProperties; + } else if (typeof userData.creatingLight == 'undefined') { + userData.creatingLight = DEFAULT_USER_DATA.creatingLight; + } + updateUserData(this.entityID, userData); + } + // Download sound if needed this.maybeDownloadSound = function() { if (this.sound === null) { @@ -76,28 +110,6 @@ this.updateLightID = function() { var userData = getUserData(this.entityID); - if (!userData) { - userData = { - lightID: null, - lightDefaultProperties: { - type: "Light", - position: { x: 0, y: 0, z: 0 }, - dimensions: { x: 5, y: 5, z: 5 }, - isSpotlight: false, - color: { red: 255, green: 48, blue: 0 }, - diffuseColor: { red: 255, green: 255, blue: 255 }, - ambientColor: { red: 255, green: 255, blue: 255 }, - specularColor: { red: 0, green: 0, blue: 0 }, - constantAttenuation: 1, - linearAttenuation: 0, - quadraticAttenuation: 0, - intensity: 10, - exponent: 0, - cutoff: 180, // in degrees - } - }; - updateUserData(this.entityID, userData); - } // Find valid light if (doesEntityExistNow(this.lightID)) { @@ -168,15 +180,21 @@ updateUserData(this.entityID, userData); print("Relative properties of light entity saved."); } - - this.preload = function(entityID) { + + // This function should be called before any callback is executed + this.preOperation = function(entityID) { this.entityID = entityID; this.maybeDownloadSound(); + + this.checkUserData(); + } + + this.preload = function(entityID) { + this.preOperation(entityID); }; this.clickReleaseOnEntity = function(entityID, mouseEvent) { - this.entityID = entityID; - this.maybeDownloadSound(); + this.preOperation(entityID); if (mouseEvent.isLeftButton) { this.updateLightID(); From afb96709f19df414534ae6ec60c0e4d021a25989 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 25 Mar 2015 15:44:37 +0100 Subject: [PATCH 29/53] Only update userData when light entity is identified --- examples/entityScripts/lightController.js | 91 +++++++++++++---------- 1 file changed, 53 insertions(+), 38 deletions(-) diff --git a/examples/entityScripts/lightController.js b/examples/entityScripts/lightController.js index 1ff41df16c..f4ebd17715 100644 --- a/examples/entityScripts/lightController.js +++ b/examples/entityScripts/lightController.js @@ -1,6 +1,5 @@ (function() { this.entityID = null; - this.properties = null; this.lightID = null; this.sound = null; @@ -51,19 +50,6 @@ Entities.editEntity(entityID, { userData: JSON.stringify(userData) }); } - // Checks whether the userData is well-formed and updates it if not - this.checkUserData = function() { - var userData = getUserData(this.entityID); - if (!userData) { - userData = DEFAULT_USER_DATA; - } else if (!userData.lightDefaultProperties) { - userData.lightDefaultProperties = DEFAULT_USER_DATA.lightDefaultProperties; - } else if (typeof userData.creatingLight == 'undefined') { - userData.creatingLight = DEFAULT_USER_DATA.creatingLight; - } - updateUserData(this.entityID, userData); - } - // Download sound if needed this.maybeDownloadSound = function() { if (this.sound === null) { @@ -81,17 +67,21 @@ print("Warning: Couldn't play sound."); } } - - // Toggles the associated light entity - this.toggleLight = function() { - if (this.lightID) { - var lightProperties = Entities.getEntityProperties(this.lightID); - Entities.editEntity(this.lightID, { visible: !lightProperties.visible }); - } else { - print("Warning: No light to turn on/off"); + + // Checks whether the userData is well-formed and updates it if not + this.checkUserData = function() { + var userData = getUserData(this.entityID); + if (!userData) { + userData = DEFAULT_USER_DATA; + } else if (!userData.lightDefaultProperties) { + userData.lightDefaultProperties = DEFAULT_USER_DATA.lightDefaultProperties; + } else if (typeof userData.creatingLight == 'undefined') { + userData.creatingLight = DEFAULT_USER_DATA.creatingLight; } + updateUserData(this.entityID, userData); } + // Create a Light entity this.createLight = function(userData) { var lightProperties = copyObject(userData.lightDefaultProperties); if (lightProperties) { @@ -108,34 +98,48 @@ } } + // Tries to find a valid light, creates one otherwise this.updateLightID = function() { - var userData = getUserData(this.entityID); - // Find valid light if (doesEntityExistNow(this.lightID)) { - if (!didEntityExist(this.lightID)) { - // Light now has an ID, so update it in userData - this.lightID = getTrueID(this.lightID); - userData.lightID = this.lightID; - updateUserData(this.entityID, userData); - } return; } + var userData = getUserData(this.entityID); if (doesEntityExistNow(userData.lightID)) { - this.lightID = getTrueID(userData.lightID); + this.lightID = userData.lightID; return; } - // No valid light, create one - this.lightID = this.createLight(userData); - print("Created new light entity"); - - // Update user data with new ID + if (!userData.creatingLight) { + // No valid light, create one + userData.creatingLight = true; + updateUserData(this.entityID, userData); + this.lightID = this.createLight(userData); + this.maybeUpdateLightIDInUserData(); + print("Created new light entity"); + } + } + + this.maybeUpdateLightIDInUserData = function() { + this.lightID = getTrueID(this.lightID); + if (this.lightID.isKnownID) { + this.updateLightIDInUserData(); + } else { + var that = this; + Script.setTimeout(function() { that.maybeUpdateLightIDInUserData() }, 500); + } + } + + // Update user data with new lightID + this.updateLightIDInUserData = function() { + var userData = getUserData(this.entityID); userData.lightID = this.lightID; + userData.creatingLight = false; updateUserData(this.entityID, userData); } + // Moves light entity if the lamp entity moved this.maybeMoveLight = function() { var entityProperties = Entities.getEntityProperties(this.entityID); var lightProperties = Entities.getEntityProperties(this.lightID); @@ -151,8 +155,9 @@ } } + // Stores light entity relative position in the lamp metadata this.updateRelativeLightPosition = function() { - if (!doesEntityExistNow(this.entityID) || !doesEntityExistNow(this.lightID)) { + if (!doesEntityExistNow(this.lightID)) { print("Warning: ID invalid, couldn't save relative position."); return; } @@ -189,6 +194,17 @@ this.checkUserData(); } + // Toggles the associated light entity + this.toggleLight = function() { + if (this.lightID) { + var lightProperties = Entities.getEntityProperties(this.lightID); + Entities.editEntity(this.lightID, { visible: !lightProperties.visible }); + this.playSound(); + } else { + print("Warning: No light to turn on/off"); + } + } + this.preload = function(entityID) { this.preOperation(entityID); }; @@ -200,7 +216,6 @@ this.updateLightID(); this.maybeMoveLight(); this.toggleLight(); - this.playSound(); } else if (mouseEvent.isRightButton) { this.updateRelativeLightPosition(); } From 19886bd33c91f6c8a79b51aad7c21f8b834c354e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 25 Mar 2015 16:38:27 +0100 Subject: [PATCH 30/53] Better handling of callback --- examples/entityScripts/lightController.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/entityScripts/lightController.js b/examples/entityScripts/lightController.js index f4ebd17715..5b2e2ae8b1 100644 --- a/examples/entityScripts/lightController.js +++ b/examples/entityScripts/lightController.js @@ -75,8 +75,6 @@ userData = DEFAULT_USER_DATA; } else if (!userData.lightDefaultProperties) { userData.lightDefaultProperties = DEFAULT_USER_DATA.lightDefaultProperties; - } else if (typeof userData.creatingLight == 'undefined') { - userData.creatingLight = DEFAULT_USER_DATA.creatingLight; } updateUserData(this.entityID, userData); } @@ -122,8 +120,8 @@ } this.maybeUpdateLightIDInUserData = function() { - this.lightID = getTrueID(this.lightID); - if (this.lightID.isKnownID) { + if (getTrueID(this.lightID).isKnownID) { + this.lightID = getTrueID(this.lightID); this.updateLightIDInUserData(); } else { var that = this; From 674b2c97a28ec5d5000a6e597325d9cef152ea36 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 25 Mar 2015 08:53:33 -0700 Subject: [PATCH 31/53] added comments to zlib license --- libraries/physics/src/CharacterController.cpp | 1 + libraries/physics/src/CharacterController.h | 1 + 2 files changed, 2 insertions(+) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index c26ffa3339..277d9748cd 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -1,6 +1,7 @@ /* Bullet Continuous Collision Detection and Physics Library Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com +2015.03.25 -- modified by Andrew Meadows andrew@highfidelity.io This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index 740940ce53..323529b1cd 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -1,6 +1,7 @@ /* Bullet Continuous Collision Detection and Physics Library Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com +2015.03.25 -- modified by Andrew Meadows andrew@highfidelity.io This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. From 715fe1096f2331d2c7fcfae55752f3a92c892091 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 25 Mar 2015 17:33:27 +0100 Subject: [PATCH 32/53] Random but persistant switch sound --- examples/entityScripts/lightController.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/examples/entityScripts/lightController.js b/examples/entityScripts/lightController.js index 5b2e2ae8b1..e6e4998aef 100644 --- a/examples/entityScripts/lightController.js +++ b/examples/entityScripts/lightController.js @@ -2,6 +2,9 @@ this.entityID = null; this.lightID = null; this.sound = null; + this.soundURLs = ["https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_1.wav", + "https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav", + "https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_3.wav"] var DEFAULT_USER_DATA = { creatingLight: false, @@ -21,7 +24,8 @@ intensity: 10, exponent: 0, cutoff: 180, // in degrees - } + }, + soundIndex: Math.floor(Math.random() * this.soundURLs.length) }; function copyObject(object) { @@ -53,7 +57,8 @@ // Download sound if needed this.maybeDownloadSound = function() { if (this.sound === null) { - this.sound = SoundCache.getSound("http://public.highfidelity.io/sounds/Footsteps/FootstepW3Left-12db.wav"); + var soundIndex = getUserData(this.entityID).soundIndex; + this.sound = SoundCache.getSound(this.soundURLs[soundIndex]); } } // Play switch sound @@ -75,6 +80,8 @@ userData = DEFAULT_USER_DATA; } else if (!userData.lightDefaultProperties) { userData.lightDefaultProperties = DEFAULT_USER_DATA.lightDefaultProperties; + } else if (!userData.soundIndex) { + userData.soundIndex = DEFAULT_USER_DATA.soundIndex; } updateUserData(this.entityID, userData); } @@ -187,9 +194,9 @@ // This function should be called before any callback is executed this.preOperation = function(entityID) { this.entityID = entityID; - this.maybeDownloadSound(); this.checkUserData(); + this.maybeDownloadSound(); } // Toggles the associated light entity From 2128f213082ccc8e49865d9a9eae069f8be72db5 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 25 Mar 2015 11:02:48 -0700 Subject: [PATCH 33/53] only set ADD bit with UPDATE_SHAPE when enabled --- libraries/physics/src/CharacterController.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 277d9748cd..88d26110a7 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -684,10 +684,13 @@ void CharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm if (radiusDelta < FLT_EPSILON && heightDelta < FLT_EPSILON) { // shape hasn't changed --> nothing to do } else { - // we need to: remove, update, add + // we always need to: REMOVE when UPDATE_SHAPE, to avoid deleting shapes out from under the PhysicsEngine _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION - | PENDING_FLAG_UPDATE_SHAPE - | PENDING_FLAG_ADD_TO_SIMULATION; + | PENDING_FLAG_UPDATE_SHAPE; + // but only need to ADD back when we happen to be enabled + if (_enabled) { + _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION; + } } // it's ok to change offset immediately -- there are no thread safety issues here @@ -705,8 +708,12 @@ bool CharacterController::needsRemoval() const { void CharacterController::setEnabled(bool enabled) { if (enabled != _enabled) { if (enabled) { + // Don't bother clearing REMOVE bit since it might be paired with an UPDATE_SHAPE bit. + // Setting the ADD bit here works for all cases so we don't even bother checking other bits. _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION; } else { + // Always set REMOVE bit when going disabled, and we always clear the ADD bit just in case + // it was previously set by something else (e.g. an UPDATE_SHAPE event). _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION; _pendingFlags &= ~ PENDING_FLAG_ADD_TO_SIMULATION; } From 2440c47648f355e6d48bf1148c31f1ea9ff7ed37 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 25 Mar 2015 11:06:19 -0700 Subject: [PATCH 34/53] remove extra whitespace --- libraries/physics/src/CharacterController.cpp | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 88d26110a7..e84df7d644 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -5,12 +5,12 @@ Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. - If you use this software in a product, an acknowledgment in the product documentation would be appreciated +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. + If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. @@ -29,7 +29,7 @@ const uint32_t PENDING_FLAG_JUMP = 1U << 3; // static helper method static btVector3 getNormalizedVector(const btVector3& v) { - // NOTE: check the length first, then normalize + // NOTE: check the length first, then normalize // --> avoids assert when trying to normalize zero-length vectors btScalar vLength = v.length(); if (vLength < FLT_EPSILON) { @@ -87,8 +87,8 @@ protected: class StepDownConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback { // special convex sweep callback for character during the stepDown() phase public: - StepDownConvexResultCallback(btCollisionObject* me, - const btVector3& up, + StepDownConvexResultCallback(btCollisionObject* me, + const btVector3& up, const btVector3& start, const btVector3& step, const btVector3& pushDirection, @@ -144,7 +144,7 @@ class StepDownConvexResultCallback : public btCollisionWorld::ClosestConvexResul btVector3 side(_radius, - (_halfHeight - _step.length() + fractionalStep.dot(_up)), 0.0f); btScalar maxAngle = side.angle(-_up); - // Ignore hits that are larger than maxAngle. Effectively what is happening here is: + // Ignore hits that are larger than maxAngle. Effectively what is happening here is: // we're ignoring hits at contacts that have non-vertical normals... if they hit higher // than the character's "feet". Ignoring the contact allows the character to slide down // for these hits. In other words, vertical walls against the character's torso will @@ -238,9 +238,9 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl btVector3 minAabb, maxAabb; _convexShape->getAabb(_ghostObject->getWorldTransform(), minAabb, maxAabb); - collisionWorld->getBroadphase()->setAabb(_ghostObject->getBroadphaseHandle(), - minAabb, - maxAabb, + collisionWorld->getBroadphase()->setAabb(_ghostObject->getBroadphaseHandle(), + minAabb, + maxAabb, collisionWorld->getDispatcher()); bool penetration = false; @@ -299,14 +299,14 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl if (collisionHeight < _lastStepUp) { // This contact is below the lastStepUp, so we ignore it for penetration resolution, - // otherwise it may prevent the character from getting close enough to find any available + // otherwise it may prevent the character from getting close enough to find any available // horizontal foothold that would allow it to climbe the ledge. In other words, we're // making the character's "feet" soft for collisions against steps, but not floors. useContact = false; - } + } } if (useContact) { - + if (dist < maxPen) { maxPen = dist; _floorNormal = normal; @@ -382,7 +382,7 @@ void CharacterController::updateTargetPositionBasedOnCollision(const btVector3& //if (tangentMag != 0.0) { if (0) { btVector3 parComponent = parallelDir * btScalar(tangentMag * movementLength); - _targetPosition += parComponent; + _targetPosition += parComponent; } if (normalMag != 0.0) { @@ -451,7 +451,7 @@ void CharacterController::stepForward(btCollisionWorld* collisionWorld, const bt void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt) { // phase 3: down // - // The "stepDown" phase first makes a normal sweep down that cancels the lift from the "stepUp" phase. + // The "stepDown" phase first makes a normal sweep down that cancels the lift from the "stepUp" phase. // If it hits a ledge then it stops otherwise it makes another sweep down in search of a floor within // reach of the character's feet. @@ -459,11 +459,11 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); btVector3 step = (_verticalVelocity * dt - _lastStepUp) * up; - StepDownConvexResultCallback callback(_ghostObject, - up, - _currentPosition, step, + StepDownConvexResultCallback callback(_ghostObject, + up, + _currentPosition, step, _walkDirection, - _maxSlopeCosine, + _maxSlopeCosine, _radius, _halfHeight); callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; @@ -484,11 +484,11 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt _wasJumping = false; } else if (!_wasJumping) { // sweep again for floor within downStep threshold - StepDownConvexResultCallback callback2 (_ghostObject, - up, + StepDownConvexResultCallback callback2 (_ghostObject, + up, _currentPosition, step, _walkDirection, - _maxSlopeCosine, + _maxSlopeCosine, _radius, _halfHeight); callback2.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; @@ -542,8 +542,8 @@ void CharacterController::reset(btCollisionWorld* collisionWorld) { //clear pair cache btHashedOverlappingPairCache *cache = _ghostObject->getOverlappingPairCache(); while (cache->getOverlappingPairArray().size() > 0) { - cache->removeOverlappingPair(cache->getOverlappingPairArray()[0].m_pProxy0, - cache->getOverlappingPairArray()[0].m_pProxy1, + cache->removeOverlappingPair(cache->getOverlappingPairArray()[0].m_pProxy0, + cache->getOverlappingPairArray()[0].m_pProxy1, collisionWorld->getDispatcher()); } } @@ -712,7 +712,7 @@ void CharacterController::setEnabled(bool enabled) { // Setting the ADD bit here works for all cases so we don't even bother checking other bits. _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION; } else { - // Always set REMOVE bit when going disabled, and we always clear the ADD bit just in case + // Always set REMOVE bit when going disabled, and we always clear the ADD bit just in case // it was previously set by something else (e.g. an UPDATE_SHAPE event). _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION; _pendingFlags &= ~ PENDING_FLAG_ADD_TO_SIMULATION; @@ -754,7 +754,7 @@ void CharacterController::updateShapeIfNecessary() { _ghostObject = NULL; delete _convexShape; _convexShape = NULL; - + // compute new dimensions from avatar's bounding box float x = _boxScale.x; float z = _boxScale.z; @@ -765,18 +765,18 @@ void CharacterController::updateShapeIfNecessary() { _halfHeight = MIN_HALF_HEIGHT; } // NOTE: _shapeLocalOffset is already computed - + if (_radius > 0.0f) { // create new ghost _ghostObject = new btPairCachingGhostObject(); _ghostObject->setWorldTransform(btTransform(glmToBullet(_avatarData->getOrientation()), glmToBullet(_avatarData->getPosition()))); // stepHeight affects the heights of ledges that the character can ascend - // however the actual ledge height is some function of _stepHeight - // due to character shape and this CharacterController algorithm + // however the actual ledge height is some function of _stepHeight + // due to character shape and this CharacterController algorithm // (the function is approximately 2*_stepHeight) _stepHeight = 0.1f * (_radius + _halfHeight) + 0.1f; - + // create new shape _convexShape = new btCapsuleShape(_radius, 2.0f * _halfHeight); _ghostObject->setCollisionShape(_convexShape); @@ -807,11 +807,11 @@ void CharacterController::preSimulation(btScalar timeStep) { void CharacterController::postSimulation() { if (_enabled) { - const btTransform& avatarTransform = _ghostObject->getWorldTransform(); + const btTransform& avatarTransform = _ghostObject->getWorldTransform(); glm::quat rotation = bulletToGLM(avatarTransform.getRotation()); glm::vec3 offset = rotation * _shapeLocalOffset; _avatarData->setOrientation(rotation); - _avatarData->setPosition(bulletToGLM(avatarTransform.getOrigin()) - offset); + _avatarData->setPosition(bulletToGLM(avatarTransform.getOrigin()) - offset); } } From 045dbb11a369ba3b4e7e0675e41dbc5a12f6f955 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 25 Mar 2015 11:07:19 -0700 Subject: [PATCH 35/53] Putting the GLERRORCHECK only in debug --- libraries/gpu/src/gpu/GLBackendShared.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/gpu/src/gpu/GLBackendShared.h b/libraries/gpu/src/gpu/GLBackendShared.h index 1853573522..f51e455447 100644 --- a/libraries/gpu/src/gpu/GLBackendShared.h +++ b/libraries/gpu/src/gpu/GLBackendShared.h @@ -49,7 +49,10 @@ static const GLenum _elementTypeToGLType[NUM_TYPES]= { GL_UNSIGNED_BYTE }; +#if _DEBUG #define CHECK_GL_ERROR() ::gpu::GLBackend::checkGLError() -//#define CHECK_GL_ERROR() +#else +#define CHECK_GL_ERROR() +#endif #endif From dec89ba96f1ef02e03cc456487174fa7dcb0e78e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 25 Mar 2015 11:22:07 -0700 Subject: [PATCH 36/53] Disable duplicating locked entities --- examples/libraries/entitySelectionTool.js | 24 +++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index c261e0d8a6..b6c536f063 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -1263,11 +1263,13 @@ SelectionDisplay = (function () { duplicatedEntityIDs = []; for (var otherEntityID in SelectionManager.savedProperties) { var properties = SelectionManager.savedProperties[otherEntityID]; - var entityID = Entities.addEntity(properties); - duplicatedEntityIDs.push({ - entityID: entityID, - properties: properties, - }); + if (!properties.locked) { + var entityID = Entities.addEntity(properties); + duplicatedEntityIDs.push({ + entityID: entityID, + properties: properties, + }); + } } } else { duplicatedEntityIDs = null; @@ -1361,11 +1363,13 @@ SelectionDisplay = (function () { duplicatedEntityIDs = []; for (var otherEntityID in SelectionManager.savedProperties) { var properties = SelectionManager.savedProperties[otherEntityID]; - var entityID = Entities.addEntity(properties); - duplicatedEntityIDs.push({ - entityID: entityID, - properties: properties, - }); + if (!properties.locked) { + var entityID = Entities.addEntity(properties); + duplicatedEntityIDs.push({ + entityID: entityID, + properties: properties, + }); + } } } else { duplicatedEntityIDs = null; From 5b4b78043aa0192eb1e2af1057cb86bd8d20e6fc Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 25 Mar 2015 11:22:28 -0700 Subject: [PATCH 37/53] Remove unneeded print messages --- examples/look.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/look.js b/examples/look.js index bcdfcf9e44..6bba57e3ad 100644 --- a/examples/look.js +++ b/examples/look.js @@ -80,7 +80,6 @@ function touchBeginEvent(event) { yawFromTouch = 0; pitchFromTouch = 0; startedTouching = true; - print("TOUCH BEGIN"); } function touchEndEvent(event) { @@ -88,7 +87,6 @@ function touchEndEvent(event) { print("touchEndEvent event.x,y=" + event.x + ", " + event.y); } startedTouching = false; - print("TOUCH END"); } function touchUpdateEvent(event) { From c3c1d4a5ae3d1c4d1d7c1c65ee56657fac0f5b34 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Wed, 25 Mar 2015 12:36:37 -0600 Subject: [PATCH 38/53] Switching to .com --- interface/src/ui/LoginDialog.cpp | 2 +- interface/ui/loginDialog.ui | 4 ++-- libraries/networking/src/LimitedNodeList.cpp | 2 +- libraries/script-engine/src/XMLHttpRequestClass.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index 004f863901..4e7a4a7dc9 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -23,7 +23,7 @@ #include "LoginDialog.h" #include "UIUtil.h" -const QString FORGOT_PASSWORD_URL = "https://metaverse.highfidelity.io/users/password/new"; +const QString FORGOT_PASSWORD_URL = "https://metaverse.highfidelity.com/users/password/new"; LoginDialog::LoginDialog(QWidget* parent) : FramelessDialog(parent, 0, FramelessDialog::POSITION_TOP), diff --git a/interface/ui/loginDialog.ui b/interface/ui/loginDialog.ui index c986db7f50..58ff353a16 100644 --- a/interface/ui/loginDialog.ui +++ b/interface/ui/loginDialog.ui @@ -136,7 +136,7 @@ <style type="text/css"> a { text-decoration: none; color: #267077;} </style> -Invalid username or password. <a href="https://metaverse.highfidelity.io/password/new">Recover?</a> +Invalid username or password. <a href="https://metaverse.highfidelity.com/password/new">Recover?</a>
Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter @@ -458,7 +458,7 @@ border-radius: 4px; padding-top: 1px; <style type="text/css"> a { text-decoration: none; color: #267077;} </style> -<a href="https://metaverse.highfidelity.io/password/new">Recover password?</a> +<a href="https://metaverse.highfidelity.com/password/new">Recover password?</a> true diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 98e1ed0572..ebd10b67a6 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -36,7 +36,7 @@ const char SOLO_NODE_TYPES[2] = { NodeType::AudioMixer }; -const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://metaverse.highfidelity.io"); +const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://metaverse.highfidelity.com"); LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort) : linkedDataCreateCallback(NULL), diff --git a/libraries/script-engine/src/XMLHttpRequestClass.cpp b/libraries/script-engine/src/XMLHttpRequestClass.cpp index 116548db61..8755527860 100644 --- a/libraries/script-engine/src/XMLHttpRequestClass.cpp +++ b/libraries/script-engine/src/XMLHttpRequestClass.cpp @@ -207,7 +207,7 @@ void XMLHttpRequestClass::open(const QString& method, const QString& url, bool a notImplemented(); } } else { - if (url.toLower().left(33) == "https://metaverse.highfidelity.io/api/") { + if (url.toLower().left(33) == "https://metaverse.highfidelity.com/api/") { AccountManager& accountManager = AccountManager::getInstance(); if (accountManager.hasValidAccessToken()) { From 89e5fef808ee7b56546620fb22306fc1251ff98a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 25 Mar 2015 11:46:08 -0700 Subject: [PATCH 39/53] send friends_only key for discoverability --- interface/src/DiscoverabilityManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/DiscoverabilityManager.cpp b/interface/src/DiscoverabilityManager.cpp index 49850e4ef6..76081b1293 100644 --- a/interface/src/DiscoverabilityManager.cpp +++ b/interface/src/DiscoverabilityManager.cpp @@ -61,6 +61,9 @@ void DiscoverabilityManager::updateLocation() { uuidStringWithoutCurlyBraces(domainHandler.getUUID())); } + const QString FRIENDS_ONLY_KEY_IN_LOCATION = "friends_only"; + locationObject.insert(FRIENDS_ONLY_KEY_IN_LOCATION, (_mode.get() == Discoverability::Friends)); + rootObject.insert(LOCATION_KEY_IN_ROOT, locationObject); accountManager.authenticatedRequest(API_USER_LOCATION_PATH, QNetworkAccessManager::PutOperation, From 4bf8e9f6254a6b86dcc61ea6ddd6ac8d9dd494f2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 25 Mar 2015 12:04:04 -0700 Subject: [PATCH 40/53] change AccountManager request API, leverage in networking and DS --- domain-server/src/DomainServer.cpp | 20 +++-- libraries/networking/src/AccountManager.cpp | 74 ++++++++----------- libraries/networking/src/AccountManager.h | 38 +++++----- libraries/networking/src/AddressManager.cpp | 18 ++--- .../networking/src/UserActivityLogger.cpp | 9 +-- 5 files changed, 71 insertions(+), 88 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 57e133c599..0918b85a63 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -814,8 +814,9 @@ void DomainServer::requestUserPublicKey(const QString& username) { qDebug() << "Requesting public key for user" << username; - AccountManager::getInstance().unauthenticatedRequest(USER_PUBLIC_KEY_PATH.arg(username), - QNetworkAccessManager::GetOperation, callbackParams); + AccountManager::getInstance().sendRequest(USER_PUBLIC_KEY_PATH.arg(username), + AccountManagerAuth::None, + QNetworkAccessManager::GetOperation, callbackParams); } QUrl DomainServer::oauthRedirectURL() { @@ -1116,8 +1117,10 @@ void DomainServer::sendPendingTransactionsToServer() { transactionCallbackParams.jsonCallbackMethod = "transactionJSONCallback"; while (i != _pendingAssignmentCredits.end()) { - accountManager.authenticatedRequest("api/v1/transactions", QNetworkAccessManager::PostOperation, - transactionCallbackParams, i.value()->postJson().toJson()); + accountManager.sendRequest("api/v1/transactions", + AccountManagerAuth::Required, + QNetworkAccessManager::PostOperation, + transactionCallbackParams, i.value()->postJson().toJson()); // set this transaction to finalized so we don't add additional credits to it i.value()->setIsFinalized(true); @@ -1240,10 +1243,11 @@ void DomainServer::sendHeartbeatToDataServer(const QString& networkAddress) { QString domainUpdateJSON = QString("{\"domain\": %1 }").arg(QString(QJsonDocument(domainObject).toJson())); - AccountManager::getInstance().authenticatedRequest(DOMAIN_UPDATE.arg(uuidStringWithoutCurlyBraces(domainID)), - QNetworkAccessManager::PutOperation, - JSONCallbackParameters(), - domainUpdateJSON.toUtf8()); + AccountManager::getInstance().sendRequest(DOMAIN_UPDATE.arg(uuidStringWithoutCurlyBraces(domainID)), + AccountManagerAuth::Required, + QNetworkAccessManager::PutOperation, + JSONCallbackParameters(), + domainUpdateJSON.toUtf8()); } // todo: have data-web respond with ice-server hostname to use diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 2a809f2a7c..5858c0926d 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -115,7 +115,7 @@ void AccountManager::updateBalance() { callbackParameters.jsonCallbackReceiver = &_accountInfo; callbackParameters.jsonCallbackMethod = "setBalanceFromJSON"; - authenticatedRequest("/api/v1/wallets/mine", QNetworkAccessManager::GetOperation, callbackParameters); + sendRequest("/api/v1/wallets/mine", AccountManagerAuth::Required, QNetworkAccessManager::GetOperation, callbackParameters); } } @@ -159,50 +159,30 @@ void AccountManager::setAuthURL(const QUrl& authURL) { } } -void AccountManager::authenticatedRequest(const QString& path, QNetworkAccessManager::Operation operation, - const JSONCallbackParameters& callbackParams, - const QByteArray& dataByteArray, - QHttpMultiPart* dataMultiPart, - const QVariantMap& propertyMap) { +void AccountManager::sendRequest(const QString& path, + AccountManagerAuth::Type authType, + QNetworkAccessManager::Operation operation, + const JSONCallbackParameters& callbackParams, + const QByteArray& dataByteArray, + QHttpMultiPart* dataMultiPart, + const QVariantMap& propertyMap) { - QMetaObject::invokeMethod(this, "invokedRequest", - Q_ARG(const QString&, path), - Q_ARG(bool, true), - Q_ARG(QNetworkAccessManager::Operation, operation), - Q_ARG(const JSONCallbackParameters&, callbackParams), - Q_ARG(const QByteArray&, dataByteArray), - Q_ARG(QHttpMultiPart*, dataMultiPart), - Q_ARG(QVariantMap, propertyMap)); -} - -void AccountManager::unauthenticatedRequest(const QString& path, QNetworkAccessManager::Operation operation, - const JSONCallbackParameters& callbackParams, - const QByteArray& dataByteArray, - QHttpMultiPart* dataMultiPart, - const QVariantMap& propertyMap) { + if (thread() != QThread::currentThread()) { + QMetaObject::invokeMethod(this, "sendRequest", + Q_ARG(const QString&, path), + Q_ARG(AccountManagerAuth::Type, AccountManagerAuth::Required), + Q_ARG(QNetworkAccessManager::Operation, operation), + Q_ARG(const JSONCallbackParameters&, callbackParams), + Q_ARG(const QByteArray&, dataByteArray), + Q_ARG(QHttpMultiPart*, dataMultiPart), + Q_ARG(QVariantMap, propertyMap)); + } - QMetaObject::invokeMethod(this, "invokedRequest", - Q_ARG(const QString&, path), - Q_ARG(bool, false), - Q_ARG(QNetworkAccessManager::Operation, operation), - Q_ARG(const JSONCallbackParameters&, callbackParams), - Q_ARG(const QByteArray&, dataByteArray), - Q_ARG(QHttpMultiPart*, dataMultiPart), - Q_ARG(QVariantMap, propertyMap)); -} - -void AccountManager::invokedRequest(const QString& path, - bool requiresAuthentication, - QNetworkAccessManager::Operation operation, - const JSONCallbackParameters& callbackParams, - const QByteArray& dataByteArray, QHttpMultiPart* dataMultiPart, - const QVariantMap& propertyMap) { - QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); - + QNetworkRequest networkRequest; networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); - + QUrl requestURL = _authURL; if (path.startsWith("/")) { @@ -211,13 +191,17 @@ void AccountManager::invokedRequest(const QString& path, requestURL.setPath("/" + path); } - if (requiresAuthentication) { + if (authType != AccountManagerAuth::None ) { if (hasValidAccessToken()) { networkRequest.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER, _accountInfo.getAccessToken().authorizationHeaderValue()); } else { - qDebug() << "No valid access token present. Bailing on authenticated invoked request."; - return; + if (authType == AccountManagerAuth::Required) { + qDebug() << "No valid access token present. Bailing on invoked request to" + << path << "that requires authentication"; + return; + } + } } @@ -540,8 +524,8 @@ void AccountManager::processGeneratedKeypair(const QByteArray& publicKey, const requestMultiPart->append(keyPart); - authenticatedRequest(PUBLIC_KEY_UPDATE_PATH, QNetworkAccessManager::PutOperation, - JSONCallbackParameters(), QByteArray(), requestMultiPart); + sendRequest(PUBLIC_KEY_UPDATE_PATH, AccountManagerAuth::Required, QNetworkAccessManager::PutOperation, + JSONCallbackParameters(), QByteArray(), requestMultiPart); // get rid of the keypair generator now that we don't need it anymore sender()->deleteLater(); diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index 2c9a441db1..b9c85d71e0 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -37,6 +37,16 @@ public: QString updateSlot; }; +namespace AccountManagerAuth { + enum Type { + None, + Required, + Optional + }; +} + +Q_DECLARE_METATYPE(AccountManagerAuth::Type); + const QByteArray ACCESS_TOKEN_AUTHORIZATION_HEADER = "Authorization"; class AccountManager : public QObject { @@ -44,19 +54,13 @@ class AccountManager : public QObject { public: static AccountManager& getInstance(bool forceReset = false); - void authenticatedRequest(const QString& path, - QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation, - const JSONCallbackParameters& callbackParams = JSONCallbackParameters(), - const QByteArray& dataByteArray = QByteArray(), - QHttpMultiPart* dataMultiPart = NULL, - const QVariantMap& propertyMap = QVariantMap()); - - void unauthenticatedRequest(const QString& path, - QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation, - const JSONCallbackParameters& callbackParams = JSONCallbackParameters(), - const QByteArray& dataByteArray = QByteArray(), - QHttpMultiPart* dataMultiPart = NULL, - const QVariantMap& propertyMap = QVariantMap()) ; + Q_INVOKABLE void sendRequest(const QString& path, + AccountManagerAuth::Type authType, + QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation, + const JSONCallbackParameters& callbackParams = JSONCallbackParameters(), + const QByteArray& dataByteArray = QByteArray(), + QHttpMultiPart* dataMultiPart = NULL, + const QVariantMap& propertyMap = QVariantMap()); const QUrl& getAuthURL() const { return _authURL; } void setAuthURL(const QUrl& authURL); @@ -107,14 +111,6 @@ private: void passSuccessToCallback(QNetworkReply* reply); void passErrorToCallback(QNetworkReply* reply); - Q_INVOKABLE void invokedRequest(const QString& path, - bool requiresAuthentication, - QNetworkAccessManager::Operation operation, - const JSONCallbackParameters& callbackParams, - const QByteArray& dataByteArray, - QHttpMultiPart* dataMultiPart, - const QVariantMap& propertyMap); - QUrl _authURL; QMap _pendingCallbackMap; diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 0458a5e912..3c27c4644c 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -294,12 +294,11 @@ void AddressManager::attemptPlaceNameLookup(const QString& lookupString, const Q requestParams.insert(OVERRIDE_PATH_KEY, overridePath); } - AccountManager::getInstance().unauthenticatedRequest(GET_PLACE.arg(placeName), - QNetworkAccessManager::GetOperation, - apiCallbackParameters(), - QByteArray(), - NULL, - requestParams); + AccountManager::getInstance().sendRequest(GET_PLACE.arg(placeName), + AccountManagerAuth::None, + QNetworkAccessManager::GetOperation, + apiCallbackParameters(), + QByteArray(), NULL, requestParams); } bool AddressManager::handleNetworkAddress(const QString& lookupString) { @@ -439,9 +438,10 @@ void AddressManager::setDomainInfo(const QString& hostname, quint16 port) { void AddressManager::goToUser(const QString& username) { QString formattedUsername = QUrl::toPercentEncoding(username); // this is a username - pull the captured name and lookup that user's location - AccountManager::getInstance().unauthenticatedRequest(GET_USER_LOCATION.arg(formattedUsername), - QNetworkAccessManager::GetOperation, - apiCallbackParameters()); + AccountManager::getInstance().sendRequest(GET_USER_LOCATION.arg(formattedUsername), + AccountManagerAuth::Optional, + QNetworkAccessManager::GetOperation, + apiCallbackParameters()); } void AddressManager::copyAddress() { diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index 64828708b2..89c0bd34bd 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -62,11 +62,10 @@ void UserActivityLogger::logAction(QString action, QJsonObject details, JSONCall params.errorCallbackMethod = "requestError"; } - accountManager.authenticatedRequest(USER_ACTIVITY_URL, - QNetworkAccessManager::PostOperation, - params, - NULL, - multipart); + accountManager.sendRequest(USER_ACTIVITY_URL, + AccountManagerAuth::Required, + QNetworkAccessManager::PostOperation, + params, NULL, multipart); } void UserActivityLogger::requestFinished(QNetworkReply& requestReply) { From 7a9c1e20abaac807136f6ef4d5aa073c32d06f91 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 25 Mar 2015 12:04:47 -0700 Subject: [PATCH 41/53] use new AccountManager API in DiscoverabilityManager --- interface/src/DiscoverabilityManager.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/src/DiscoverabilityManager.cpp b/interface/src/DiscoverabilityManager.cpp index 76081b1293..791e5667c4 100644 --- a/interface/src/DiscoverabilityManager.cpp +++ b/interface/src/DiscoverabilityManager.cpp @@ -66,15 +66,16 @@ void DiscoverabilityManager::updateLocation() { rootObject.insert(LOCATION_KEY_IN_ROOT, locationObject); - accountManager.authenticatedRequest(API_USER_LOCATION_PATH, QNetworkAccessManager::PutOperation, - JSONCallbackParameters(), QJsonDocument(rootObject).toJson()); + accountManager.sendRequest(API_USER_LOCATION_PATH, AccountManagerAuth::Required, + QNetworkAccessManager::PutOperation, + JSONCallbackParameters(), QJsonDocument(rootObject).toJson()); } } } void DiscoverabilityManager::removeLocation() { AccountManager& accountManager = AccountManager::getInstance(); - accountManager.authenticatedRequest(API_USER_LOCATION_PATH, QNetworkAccessManager::DeleteOperation); + accountManager.sendRequest(API_USER_LOCATION_PATH, AccountManagerAuth::Required, QNetworkAccessManager::DeleteOperation); } void DiscoverabilityManager::setDiscoverabilityMode(Discoverability::Mode discoverabilityMode) { From d1d183e190b58205d811a507bf0c10ecd06d9df6 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Wed, 25 Mar 2015 13:05:10 -0600 Subject: [PATCH 42/53] More .com changes --- domain-server/resources/describe-settings.json | 4 ++-- domain-server/resources/web/js/settings.js | 6 +++--- examples/edit.js | 2 +- examples/libraries/modelUploader.js | 6 +++--- examples/lobby.js | 2 +- examples/users.js | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 4636c61367..0082bd84ae 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -6,7 +6,7 @@ { "name": "access_token", "label": "Access Token", - "help": "This is an access token generated on the My Security page of your High Fidelity account.
Generate a token with the 'domains' scope and paste it here.
This is required to associate this domain-server with a domain in your account." + "help": "This is an access token generated on the My Security page of your High Fidelity account.
Generate a token with the 'domains' scope and paste it here.
This is required to associate this domain-server with a domain in your account." }, { "name": "id", @@ -30,7 +30,7 @@ }, { "value": "disabled", - "label": "None: use the network information I have entered for this domain at metaverse.highfidelity.io" + "label": "None: use the network information I have entered for this domain at metaverse.highfidelity.com" } ] }, diff --git a/domain-server/resources/web/js/settings.js b/domain-server/resources/web/js/settings.js index f62515c863..4fac753959 100644 --- a/domain-server/resources/web/js/settings.js +++ b/domain-server/resources/web/js/settings.js @@ -652,7 +652,7 @@ function chooseFromHighFidelityDomains(clickedButton) { clickedButton.attr('disabled', 'disabled') // get a list of user domains from data-web - data_web_domains_url = "https://metaverse.highfidelity.io/api/v1/domains?access_token=" + data_web_domains_url = "https://metaverse.highfidelity.com/api/v1/domains?access_token=" $.getJSON(data_web_domains_url + Settings.initialValues.metaverse.access_token, function(data){ modal_buttons = { @@ -682,7 +682,7 @@ function chooseFromHighFidelityDomains(clickedButton) { modal_buttons["success"] = { label: 'Create new domain', callback: function() { - window.open("https://metaverse.highfidelity.io/user/domains", '_blank'); + window.open("https://metaverse.highfidelity.com/user/domains", '_blank'); } } modal_body = "

You do not have any domains in your High Fidelity account." + @@ -708,4 +708,4 @@ function chooseFromHighFidelityDomains(clickedButton) { title: "Access token required" }) } -} \ No newline at end of file +} diff --git a/examples/edit.js b/examples/edit.js index 72938e5ed4..70e51823b2 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -130,7 +130,7 @@ var importingSVOTextOverlay = Overlays.addOverlay("text", { visible: false, }); -var MARKETPLACE_URL = "https://metaverse.highfidelity.io/marketplace"; +var MARKETPLACE_URL = "https://metaverse.highfidelity.com/marketplace"; var marketplaceWindow = new WebWindow('Marketplace', MARKETPLACE_URL, 900, 700, false); marketplaceWindow.setVisible(false); diff --git a/examples/libraries/modelUploader.js b/examples/libraries/modelUploader.js index fcc96854ab..64a9e91203 100644 --- a/examples/libraries/modelUploader.js +++ b/examples/libraries/modelUploader.js @@ -21,8 +21,8 @@ modelUploader = (function () { //svoBuffer, mapping, geometry, - API_URL = "https://metaverse.highfidelity.io/api/v1/models", - MODEL_URL = "http://public.highfidelity.io/models/content", + API_URL = "https://metaverse.highfidelity.com/api/v1/models", + MODEL_URL = "http://public.highfidelity.com/models/content", NAME_FIELD = "name", SCALE_FIELD = "scale", FILENAME_FIELD = "filename", @@ -690,4 +690,4 @@ modelUploader = (function () { }; return that; -}()); \ No newline at end of file +}()); diff --git a/examples/lobby.js b/examples/lobby.js index 5d687dc07a..381107d65a 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -158,7 +158,7 @@ var places = {}; function changeLobbyTextures() { var req = new XMLHttpRequest(); - req.open("GET", "https://metaverse.highfidelity.io/api/v1/places?limit=21", false); + req.open("GET", "https://metaverse.highfidelity.com/api/v1/places?limit=21", false); req.send(); places = JSON.parse(req.responseText).data.places; diff --git a/examples/users.js b/examples/users.js index dec141127e..22fe89389f 100644 --- a/examples/users.js +++ b/examples/users.js @@ -34,7 +34,7 @@ var usersWindow = (function () { usersOnline, // Raw users data linesOfUsers = [], // Array of indexes pointing into usersOnline - API_URL = "https://metaverse.highfidelity.io/api/v1/users?status=online", + API_URL = "https://metaverse.highfidelity.com/api/v1/users?status=online", HTTP_GET_TIMEOUT = 60000, // ms = 1 minute usersRequest, processUsers, From ea3ec91f715542a4f7c49e49dac83051428c4587 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 25 Mar 2015 12:27:15 -0700 Subject: [PATCH 43/53] Remove inspect tool from edit.js --- examples/edit.js | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/examples/edit.js b/examples/edit.js index 03137310b6..da0a226b93 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -76,7 +76,6 @@ var DEFAULT_DIMENSIONS = { var DEFAULT_LIGHT_DIMENSIONS = Vec3.multiply(20, DEFAULT_DIMENSIONS); -var MENU_INSPECT_TOOL_ENABLED = "Inspect Tool"; var MENU_AUTO_FOCUS_ON_SELECT = "Auto Focus on Select"; var MENU_EASE_ON_FOCUS = "Ease Orientation on Focus"; var MENU_SHOW_LIGHTS_IN_EDIT_MODE = "Show Lights in Edit Mode"; @@ -553,18 +552,6 @@ function mousePressEvent(event) { // Event handled; do nothing. return; } - } else if (Menu.isOptionChecked(MENU_INSPECT_TOOL_ENABLED)) { - var result = findClickedEntity(event); - if (event.isRightButton) { - if (result !== null) { - var currentProperties = Entities.getEntityProperties(result.entityID); - cameraManager.enable(); - cameraManager.focus(currentProperties.position, null, Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); - cameraManager.mousePressEvent(event); - } - } else { - cameraManager.mousePressEvent(event); - } } } @@ -780,7 +767,7 @@ function setupModelMenus() { Menu.addMenuItem({ menuName: "File", menuItemName: "Import Entities", shortcutKey: "CTRL+META+I", afterItem: "Export Entities" }); Menu.addMenuItem({ menuName: "File", menuItemName: "Import Entities from URL", shortcutKey: "CTRL+META+U", afterItem: "Import Entities" }); - Menu.addMenuItem({ menuName: "View", menuItemName: MENU_AUTO_FOCUS_ON_SELECT, afterItem: MENU_INSPECT_TOOL_ENABLED, + Menu.addMenuItem({ menuName: "View", menuItemName: MENU_AUTO_FOCUS_ON_SELECT, isCheckable: true, isChecked: Settings.getValue(SETTING_AUTO_FOCUS_ON_SELECT) == "true" }); Menu.addMenuItem({ menuName: "View", menuItemName: MENU_EASE_ON_FOCUS, afterItem: MENU_AUTO_FOCUS_ON_SELECT, isCheckable: true, isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) == "true" }); @@ -811,7 +798,6 @@ function cleanupModelMenus() { Menu.removeMenuItem("File", "Import Entities"); Menu.removeMenuItem("File", "Import Entities from URL"); - Menu.removeMenuItem("View", MENU_INSPECT_TOOL_ENABLED); Menu.removeMenuItem("View", MENU_AUTO_FOCUS_ON_SELECT); Menu.removeMenuItem("View", MENU_EASE_ON_FOCUS); Menu.removeMenuItem("View", MENU_SHOW_LIGHTS_IN_EDIT_MODE); From 8eed2b6603ddc160502d052e259c697c139c7df0 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 25 Mar 2015 12:28:56 -0700 Subject: [PATCH 44/53] Add PopupMenu to edit.js --- examples/edit.js | 123 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/examples/edit.js b/examples/edit.js index da0a226b93..fc427a3add 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -1210,4 +1210,127 @@ PropertiesTool = function(opts) { return that; }; +PopupMenu = function() { + var self = this; + + var MENU_ITEM_HEIGHT = 21; + var MENU_ITEM_SPACING = 1; + var TEXT_MARGIN = 7; + + var overlays = []; + var overlayInfo = {}; + + var upColor = { red: 0, green: 0, blue: 0 }; + var downColor = { red: 192, green: 192, blue: 192 }; + var overColor = { red: 128, green: 128, blue: 128 }; + + self.onSelectMenuItem = function() { }; + + self.addMenuItem = function(name) { + var id = Overlays.addOverlay("text", { + text: name, + backgroundAlpha: 1.0, + backgroundColor: upColor, + topMargin: TEXT_MARGIN, + leftMargin: TEXT_MARGIN, + width: 210, + height: MENU_ITEM_HEIGHT, + font: { size: 12 }, + visible: false, + }); + overlays.push(id); + overlayInfo[id] = { name: name }; + return id; + }; + + self.updateMenuItemText = function(id, newText) { + Overlays.editOverlay(id, { text: newText }); + }; + + self.setPosition = function(x, y) { + for (var key in overlayInfo) { + Overlays.editOverlay(key, { + x: x, + y: y, + }); + y += MENU_ITEM_HEIGHT + MENU_ITEM_SPACING; + } + }; + + self.onSelected = function() { }; + + var pressingOverlay = null; + var hoveringOverlay = null; + + self.mousePressEvent = function(event) { + if (event.isLeftButton) { + var overlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); + if (overlay in overlayInfo) { + pressingOverlay = overlay; + Overlays.editOverlay(pressingOverlay, { backgroundColor: downColor }); + } else { + self.hide(); + } + return false; + } + }; + self.mouseMoveEvent = function(event) { + if (visible) { + var overlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); + if (!pressingOverlay) { + if (hoveringOverlay != null && overlay != hoveringOverlay) { + Overlays.editOverlay(hoveringOverlay, { backgroundColor: upColor}); + hoveringOverlay = null; + } + if (overlay != hoveringOverlay && overlay in overlayInfo) { + Overlays.editOverlay(overlay, { backgroundColor: overColor }); + hoveringOverlay = overlay; + } + } + } + return false; + }; + self.mouseReleaseEvent = function(event) { + var overlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); + if (pressingOverlay != null) { + if (overlay == pressingOverlay) { + self.onSelectMenuItem(overlayInfo[overlay].name); + } + Overlays.editOverlay(pressingOverlay, { backgroundColor: upColor }); + pressingOverlay = null; + self.hide(); + } + }; + + var visible = false; + + self.setVisible = function(newVisible) { + if (newVisible != visible) { + visible = newVisible; + for (var key in overlayInfo) { + Overlays.editOverlay(key, { visible: newVisible }); + } + } + } + self.show = function() { + self.setVisible(true); + } + self.hide = function() { + self.setVisible(false); + } + + function cleanup() { + for (var i = 0; i < overlays.length; i++) { + Overlays.deleteOverlay(overlays[i]); + } + } + + Controller.mousePressEvent.connect(self.mousePressEvent); + Controller.mouseMoveEvent.connect(self.mouseMoveEvent); + Controller.mouseReleaseEvent.connect(self.mouseReleaseEvent); + Script.scriptEnding.connect(cleanup); + + return this; +}; + propertiesTool = PropertiesTool(); From d07acfe9aceb675e548a378812f94b52a2a97484 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 25 Mar 2015 12:29:38 -0700 Subject: [PATCH 45/53] Add right-click marketplace popup --- examples/edit.js | 177 ++++++++++++++++++++++++++++------------------- 1 file changed, 107 insertions(+), 70 deletions(-) diff --git a/examples/edit.js b/examples/edit.js index fc427a3add..cdc3822fb2 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -543,7 +543,7 @@ function mousePressEvent(event) { mouseHasMovedSincePress = false; mouseCapturedByTool = false; - if (toolBar.mousePressEvent(event) || progressDialog.mousePressEvent(event)) { + if (propertyMenu.mousePressEvent(event) || toolBar.mousePressEvent(event) || progressDialog.mousePressEvent(event)) { mouseCapturedByTool = true; return; } @@ -563,6 +563,8 @@ var IDLE_MOUSE_TIMEOUT = 200; var DEFAULT_ENTITY_DRAG_DROP_DISTANCE = 2.0; function mouseMoveEvent(event) { + mouseHasMovedSincePress = true; + if (placingEntityID) { if (!placingEntityID.isKnownID) { placingEntityID = Entities.identifyEntity(placingEntityID); @@ -583,10 +585,8 @@ function mouseMoveEvent(event) { Script.clearTimeout(idleMouseTimerId); } - mouseHasMovedSincePress = true; - // allow the selectionDisplay and cameraManager to handle the event first, if it doesn't handle it, then do our own thing - if (selectionDisplay.mouseMoveEvent(event) || cameraManager.mouseMoveEvent(event)) { + if (selectionDisplay.mouseMoveEvent(event) || propertyMenu.mouseMoveEvent(event) || cameraManager.mouseMoveEvent(event)) { return; } @@ -631,7 +631,7 @@ function highlightEntityUnderCursor(position, accurateRay) { function mouseReleaseEvent(event) { - if (toolBar.mouseReleaseEvent(event)) { + if (propertyMenu.mouseReleaseEvent(event) || toolBar.mouseReleaseEvent(event)) { return true; } if (placingEntityID) { @@ -655,74 +655,94 @@ function mouseReleaseEvent(event) { } function mouseClickEvent(event) { - if (!event.isLeftButton || !isActive) { - return; - } - - var result = findClickedEntity(event); - if (result === null) { - if (!event.isShifted) { - selectionManager.clearSelections(); - } - return; - } - toolBar.setActive(true); - var pickRay = result.pickRay; - var foundEntity = result.entityID; - - var properties = Entities.getEntityProperties(foundEntity); - if (isLocked(properties)) { - print("Model locked " + properties.id); - } else { - var halfDiagonal = Vec3.length(properties.dimensions) / 2.0; - - print("Checking properties: " + properties.id + " " + properties.isKnownID + " - Half Diagonal:" + halfDiagonal); - // P P - Model - // /| A - Palm - // / | d B - unit vector toward tip - // / | X - base of the perpendicular line - // A---X----->B d - distance fom axis - // x x - distance from A - // - // |X-A| = (P-A).B - // X == A + ((P-A).B)B - // d = |P-X| - - var A = pickRay.origin; - var B = Vec3.normalize(pickRay.direction); - var P = properties.position; - - var x = Vec3.dot(Vec3.subtract(P, A), B); - var X = Vec3.sum(A, Vec3.multiply(B, x)); - var d = Vec3.length(Vec3.subtract(P, X)); - var halfDiagonal = Vec3.length(properties.dimensions) / 2.0; - - var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(), properties.position)) * 180 / 3.14; - - var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE) - && (allowSmallModels || angularSize > MIN_ANGULAR_SIZE); - - if (0 < x && sizeOK) { - entitySelected = true; - selectedEntityID = foundEntity; - orientation = MyAvatar.orientation; - intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation)); - - + print("CLICK"); + if (isActive && event.isLeftButton) { + var result = findClickedEntity(event); + if (result === null) { if (!event.isShifted) { - selectionManager.setSelections([foundEntity]); + selectionManager.clearSelections(); + } + return; + } + toolBar.setActive(true); + var pickRay = result.pickRay; + var foundEntity = result.entityID; + + var properties = Entities.getEntityProperties(foundEntity); + if (isLocked(properties)) { + print("Model locked " + properties.id); + } else { + var halfDiagonal = Vec3.length(properties.dimensions) / 2.0; + + print("Checking properties: " + properties.id + " " + properties.isKnownID + " - Half Diagonal:" + halfDiagonal); + // P P - Model + // /| A - Palm + // / | d B - unit vector toward tip + // / | X - base of the perpendicular line + // A---X----->B d - distance fom axis + // x x - distance from A + // + // |X-A| = (P-A).B + // X == A + ((P-A).B)B + // d = |P-X| + + var A = pickRay.origin; + var B = Vec3.normalize(pickRay.direction); + var P = properties.position; + + var x = Vec3.dot(Vec3.subtract(P, A), B); + var X = Vec3.sum(A, Vec3.multiply(B, x)); + var d = Vec3.length(Vec3.subtract(P, X)); + var halfDiagonal = Vec3.length(properties.dimensions) / 2.0; + + var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(), properties.position)) * 180 / 3.14; + + var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE) + && (allowSmallModels || angularSize > MIN_ANGULAR_SIZE); + + if (0 < x && sizeOK) { + entitySelected = true; + selectedEntityID = foundEntity; + orientation = MyAvatar.orientation; + intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation)); + + + if (!event.isShifted) { + selectionManager.setSelections([foundEntity]); + } else { + selectionManager.addEntity(foundEntity, true); + } + + print("Model selected: " + foundEntity.id); + selectionDisplay.select(selectedEntityID, event); + + if (Menu.isOptionChecked(MENU_AUTO_FOCUS_ON_SELECT)) { + cameraManager.focus(selectionManager.worldPosition, + selectionManager.worldDimensions, + Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + } + } + } + } else if (event.isRightButton) { + var result = findClickedEntity(event); + if (result) { + var properties = Entities.getEntityProperties(result.entityID); + var data = {}; + try { + data = JSON.parse(properties.attribution); + } catch (e) { + } + if (data.marketplaceID) { + propertyMenu.marketplaceID = data.marketplaceID; + propertyMenu.updateMenuItemText(showMenuItem, "Show in Marketplace"); } else { - selectionManager.addEntity(foundEntity, true); - } - - print("Model selected: " + foundEntity.id); - selectionDisplay.select(selectedEntityID, event); - - if (Menu.isOptionChecked(MENU_AUTO_FOCUS_ON_SELECT)) { - cameraManager.focus(selectionManager.worldPosition, - selectionManager.worldDimensions, - Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + propertyMenu.marketplaceID = null; + propertyMenu.updateMenuItemText(showMenuItem, "No marketplace info"); } + propertyMenu.setPosition(event.x, event.y); + propertyMenu.show(); + } else { + propertyMenu.hide(); } } } @@ -1137,6 +1157,8 @@ PropertiesTool = function(opts) { if (marketplaceWindow.url != data.url) { marketplaceWindow.setURL(data.url); } + marketplaceWindow.setVisible(true); + marketplaceWindow.raise(); } else if (data.type == "action") { if (data.action == "moveSelectionToGrid") { if (selectionManager.hasSelection()) { @@ -1333,4 +1355,19 @@ PopupMenu = function() { return this; }; +var propertyMenu = PopupMenu(); + +propertyMenu.onSelectMenuItem = function(name) { + if (propertyMenu.marketplaceID) { + var url = "https://metaverse.highfidelity.io/marketplace/items/" + propertyMenu.marketplaceID; + if (marketplaceWindow.url != url) { + marketplaceWindow.setURL(url); + } + marketplaceWindow.setVisible(true); + marketplaceWindow.raise(); + } +}; + +var showMenuItem = propertyMenu.addMenuItem("Show in Marketplace"); + propertiesTool = PropertiesTool(); From b8174b164f06d49fc708ecb7c200ef305dc62d51 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 25 Mar 2015 12:29:57 -0700 Subject: [PATCH 46/53] Update marketplace popup to hide on position or orientation change --- examples/edit.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/edit.js b/examples/edit.js index cdc3822fb2..fd197349aa 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -839,11 +839,21 @@ Script.scriptEnding.connect(function() { Overlays.deleteOverlay(importingSVOTextOverlay); }); +var lastOrientation = null; +var lastPosition = null; + // Do some stuff regularly, like check for placement of various overlays Script.update.connect(function (deltaTime) { toolBar.move(); progressDialog.move(); selectionDisplay.checkMove(); + var dOrientation = Math.abs(Quat.dot(Camera.orientation, lastOrientation) - 1); + var dPosition = Vec3.distance(Camera.position, lastPosition); + if (dOrientation > 0.001 || dPosition > 0.001) { + propertyMenu.hide(); + lastOrientation = Camera.orientation; + lastPosition = Camera.position; + } }); function insideBox(center, dimensions, point) { From b5b1c5a90b10ebcb10bb6a519b70c1efcec93099 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 25 Mar 2015 12:30:42 -0700 Subject: [PATCH 47/53] Remove extraneous print --- examples/edit.js | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/edit.js b/examples/edit.js index fd197349aa..80415ab418 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -655,7 +655,6 @@ function mouseReleaseEvent(event) { } function mouseClickEvent(event) { - print("CLICK"); if (isActive && event.isLeftButton) { var result = findClickedEntity(event); if (result === null) { From ec2b11640ce7606e004cc6909d85b6a9bd3cd390 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 25 Mar 2015 12:51:13 -0700 Subject: [PATCH 48/53] more tweaks to LOD logic --- interface/src/LODManager.cpp | 101 ++++++++++++++++++++++++----------- interface/src/LODManager.h | 39 +++++++++----- 2 files changed, 95 insertions(+), 45 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 8b942dcfe1..751bea8c23 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -40,26 +40,38 @@ float LODManager::getLODIncreaseFPS() { void LODManager::autoAdjustLOD(float currentFPS) { + // NOTE: our first ~100 samples at app startup are completely all over the place, and we don't // really want to count them in our average, so we will ignore the real frame rates and stuff // our moving average with simulated good data const int IGNORE_THESE_SAMPLES = 100; - const float ASSUMED_FPS = 60.0f; - if (_fpsAverage.getSampleCount() < IGNORE_THESE_SAMPLES) { + //const float ASSUMED_FPS = 60.0f; + if (_fpsAverageUpWindow.getSampleCount() < IGNORE_THESE_SAMPLES) { currentFPS = ASSUMED_FPS; + _lastUpShift = _lastDownShift = usecTimestampNow(); } - _fpsAverage.updateAverage(currentFPS); - _fastFPSAverage.updateAverage(currentFPS); + _fpsAverageStartWindow.updateAverage(currentFPS); + _fpsAverageDownWindow.updateAverage(currentFPS); + _fpsAverageUpWindow.updateAverage(currentFPS); quint64 now = usecTimestampNow(); bool changed = false; bool octreeChanged = false; - quint64 elapsed = now - _lastAdjust; + quint64 elapsedSinceDownShift = now - _lastDownShift; + quint64 elapsedSinceUpShift = now - _lastUpShift; if (_automaticLODAdjust) { - // LOD Downward adjustment - if (elapsed > ADJUST_LOD_DOWN_DELAY && _fpsAverage.getAverage() < getLODDecreaseFPS()) { + + // LOD Downward adjustment + // If our last adjust was an upshift, then we don't want to consider any downshifts until we've delayed at least + // our START_DELAY_WINDOW_IN_SECS + bool doDownShift = _lastAdjustWasUpShift + ? (elapsedSinceUpShift > START_SHIFT_ELPASED && _fpsAverageStartWindow.getAverage() < getLODDecreaseFPS()) + : (elapsedSinceDownShift > DOWN_SHIFT_ELPASED && _fpsAverageDownWindow.getAverage() < getLODDecreaseFPS()); + + + if (doDownShift) { // Octree items... stepwise adjustment if (_octreeSizeScale > ADJUST_LOD_MIN_SIZE_SCALE) { @@ -70,37 +82,58 @@ void LODManager::autoAdjustLOD(float currentFPS) { octreeChanged = changed = true; } - if (changed) { - _lastAdjust = now; - qDebug() << "adjusting LOD down... average fps for last approximately 5 seconds=" << _fpsAverage.getAverage() - << "_octreeSizeScale=" << _octreeSizeScale; + if (changed) { + if (_lastAdjustWasUpShift) { + qDebug() << "adjusting LOD DOWN after initial delay..." + << "average fps for last "<< START_DELAY_WINDOW_IN_SECS <<"seconds was " + << _fpsAverageStartWindow.getAverage() + << "minimum is:" << getLODDecreaseFPS() + << "elapsedSinceUpShift:" << elapsedSinceUpShift + << " NEW _octreeSizeScale=" << _octreeSizeScale; + } else { + qDebug() << "adjusting LOD DOWN..." + << "average fps for last "<< DOWN_SHIFT_WINDOW_IN_SECS <<"seconds was " + << _fpsAverageDownWindow.getAverage() + << "minimum is:" << getLODDecreaseFPS() + << "elapsedSinceDownShift:" << elapsedSinceDownShift + << " NEW _octreeSizeScale=" << _octreeSizeScale; + } + + _lastDownShift = now; + _lastAdjustWasUpShift = false; emit LODDecreased(); } - } + } else { - // LOD Upward adjustment - if (elapsed > ADJUST_LOD_UP_DELAY && _fpsAverage.getAverage() > getLODIncreaseFPS()) { + // LOD Upward adjustment + if (elapsedSinceUpShift > UP_SHIFT_ELPASED && _fpsAverageUpWindow.getAverage() > getLODIncreaseFPS()) { - // Octee items... stepwise adjustment - if (_octreeSizeScale < ADJUST_LOD_MAX_SIZE_SCALE) { - if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) { - _octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE; - } else { - _octreeSizeScale *= ADJUST_LOD_UP_BY; + // Octee items... stepwise adjustment + if (_octreeSizeScale < ADJUST_LOD_MAX_SIZE_SCALE) { + if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) { + _octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE; + } else { + _octreeSizeScale *= ADJUST_LOD_UP_BY; + } + if (_octreeSizeScale > ADJUST_LOD_MAX_SIZE_SCALE) { + _octreeSizeScale = ADJUST_LOD_MAX_SIZE_SCALE; + } + octreeChanged = changed = true; } - if (_octreeSizeScale > ADJUST_LOD_MAX_SIZE_SCALE) { - _octreeSizeScale = ADJUST_LOD_MAX_SIZE_SCALE; - } - octreeChanged = changed = true; - } - if (changed) { - _lastAdjust = now; - qDebug() << "adjusting LOD up... average fps for last approximately 5 seconds=" << _fpsAverage.getAverage() - << "_octreeSizeScale=" << _octreeSizeScale; + if (changed) { + qDebug() << "adjusting LOD UP... average fps for last "<< UP_SHIFT_WINDOW_IN_SECS <<"seconds was " + << _fpsAverageUpWindow.getAverage() + << "upshift point is:" << getLODIncreaseFPS() + << "elapsedSinceUpShift:" << elapsedSinceUpShift + << " NEW _octreeSizeScale=" << _octreeSizeScale; - emit LODIncreased(); + _lastUpShift = now; + _lastAdjustWasUpShift = true; + + emit LODIncreased(); + } } } @@ -116,9 +149,13 @@ void LODManager::autoAdjustLOD(float currentFPS) { } void LODManager::resetLODAdjust() { - _fpsAverage.reset(); - _fastFPSAverage.reset(); + + // TODO: Do we need this??? + /* + _fpsAverageDownWindow.reset(); + _fpsAverageUpWindow.reset(); _lastAdjust = usecTimestampNow(); + */ } QString LODManager::getLODFeedbackText() { diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index c14f17ca61..3f9d2046c1 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -19,10 +19,22 @@ const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 30.0; const float DEFAULT_HMD_LOD_DOWN_FPS = 60.0; -const float INCREASE_LOD_GAP = 5.0f; +const float MAX_LIKELY_DESKTOP_FPS = 59.0; // this is essentially, V-synch - 1 fps +const float MAX_LIKELY_HMD_FPS = 74.0; // this is essentially, V-synch - 1 fps +const float INCREASE_LOD_GAP = 15.0f; -const quint64 ADJUST_LOD_DOWN_DELAY = 1000 * 1000 * 0.5; // Consider adjusting LOD down after half a second -const quint64 ADJUST_LOD_UP_DELAY = ADJUST_LOD_DOWN_DELAY * 2; +const float START_DELAY_WINDOW_IN_SECS = 3.0f; // wait at least this long after steady state/last upshift to consider downshifts +const float DOWN_SHIFT_WINDOW_IN_SECS = 0.5f; +const float UP_SHIFT_WINDOW_IN_SECS = 2.5f; + +const int ASSUMED_FPS = 60; +const quint64 START_SHIFT_ELPASED = USECS_PER_SECOND * START_DELAY_WINDOW_IN_SECS; +const quint64 DOWN_SHIFT_ELPASED = USECS_PER_SECOND * DOWN_SHIFT_WINDOW_IN_SECS; // Consider adjusting LOD down after half a second +const quint64 UP_SHIFT_ELPASED = USECS_PER_SECOND * UP_SHIFT_WINDOW_IN_SECS; + +const int START_DELAY_SAMPLES_OF_FRAMES = ASSUMED_FPS * START_DELAY_WINDOW_IN_SECS; +const int DOWN_SHIFT_SAMPLES_OF_FRAMES = ASSUMED_FPS * DOWN_SHIFT_WINDOW_IN_SECS; +const int UP_SHIFT_SAMPLES_OF_FRAMES = ASSUMED_FPS * UP_SHIFT_WINDOW_IN_SECS; const float ADJUST_LOD_DOWN_BY = 0.9f; const float ADJUST_LOD_UP_BY = 1.1f; @@ -37,9 +49,6 @@ const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE; // do. But both are still culled using the same angular size logic. const float AVATAR_TO_ENTITY_RATIO = 2.0f; -const int ONE_SECOND_OF_FRAMES = 60; -const int FIVE_SECONDS_OF_FRAMES = 5 * ONE_SECOND_OF_FRAMES; - class LODManager : public QObject, public Dependency { Q_OBJECT @@ -51,11 +60,11 @@ public: Q_INVOKABLE void setDesktopLODDecreaseFPS(float value) { _desktopLODDecreaseFPS = value; } Q_INVOKABLE float getDesktopLODDecreaseFPS() const { return _desktopLODDecreaseFPS; } - Q_INVOKABLE float getDesktopLODIncreaseFPS() const { return _desktopLODDecreaseFPS + INCREASE_LOD_GAP; } + Q_INVOKABLE float getDesktopLODIncreaseFPS() const { return glm::min(_desktopLODDecreaseFPS + INCREASE_LOD_GAP, MAX_LIKELY_DESKTOP_FPS); } Q_INVOKABLE void setHMDLODDecreaseFPS(float value) { _hmdLODDecreaseFPS = value; } Q_INVOKABLE float getHMDLODDecreaseFPS() const { return _hmdLODDecreaseFPS; } - Q_INVOKABLE float getHMDLODIncreaseFPS() const { return _hmdLODDecreaseFPS + INCREASE_LOD_GAP; } + Q_INVOKABLE float getHMDLODIncreaseFPS() const { return glm::min(_hmdLODDecreaseFPS + INCREASE_LOD_GAP, MAX_LIKELY_HMD_FPS); } Q_INVOKABLE float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; } @@ -68,8 +77,8 @@ public: Q_INVOKABLE int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; } Q_INVOKABLE void resetLODAdjust(); - Q_INVOKABLE float getFPSAverage() const { return _fpsAverage.getAverage(); } - Q_INVOKABLE float getFastFPSAverage() const { return _fastFPSAverage.getAverage(); } + //Q_INVOKABLE float getFPSAverage() const { return _fpsAverage.getAverage(); } + //Q_INVOKABLE float getFastFPSAverage() const { return _fastFPSAverage.getAverage(); } Q_INVOKABLE float getLODDecreaseFPS(); Q_INVOKABLE float getLODIncreaseFPS(); @@ -96,9 +105,13 @@ private: float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE; int _boundaryLevelAdjust = 0; - quint64 _lastAdjust = 0; - SimpleMovingAverage _fpsAverage = FIVE_SECONDS_OF_FRAMES; - SimpleMovingAverage _fastFPSAverage = ONE_SECOND_OF_FRAMES; + quint64 _lastDownShift = 0; + quint64 _lastUpShift = 0; + bool _lastAdjustWasUpShift = true; // start out as if we've just upshifted + + SimpleMovingAverage _fpsAverageStartWindow = START_DELAY_SAMPLES_OF_FRAMES; + SimpleMovingAverage _fpsAverageDownWindow = DOWN_SHIFT_SAMPLES_OF_FRAMES; + SimpleMovingAverage _fpsAverageUpWindow = UP_SHIFT_SAMPLES_OF_FRAMES; bool _shouldRenderTableNeedsRebuilding = true; QMap _shouldRenderTable; From ef0281ab436e74ddf3de0c3e3c0b493daee49cbd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 25 Mar 2015 15:30:03 -0700 Subject: [PATCH 49/53] use the new placename entry as entry point --- libraries/networking/src/AddressManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index bfc3ace657..a2522afcbc 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -23,7 +23,7 @@ #include "AccountManager.h" const QString HIFI_URL_SCHEME = "hifi"; -const QString DEFAULT_HIFI_ADDRESS = "hifi://sandbox"; +const QString DEFAULT_HIFI_ADDRESS = "hifi://entry"; typedef const glm::vec3& (*PositionGetter)(); typedef glm::quat (*OrientationGetter)(); From 68e730af454938854d4220c92de521c53b399a18 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 25 Mar 2015 15:48:50 -0700 Subject: [PATCH 50/53] handle throttle render case and clean up code logic to be more obvious --- interface/src/LODManager.cpp | 46 ++++++++++++++++++++---------------- interface/src/LODManager.h | 2 +- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 751bea8c23..e1a82372d2 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -50,6 +50,7 @@ void LODManager::autoAdjustLOD(float currentFPS) { currentFPS = ASSUMED_FPS; _lastUpShift = _lastDownShift = usecTimestampNow(); } + _fpsAverageStartWindow.updateAverage(currentFPS); _fpsAverageDownWindow.updateAverage(currentFPS); _fpsAverageUpWindow.updateAverage(currentFPS); @@ -64,12 +65,17 @@ void LODManager::autoAdjustLOD(float currentFPS) { if (_automaticLODAdjust) { // LOD Downward adjustment - // If our last adjust was an upshift, then we don't want to consider any downshifts until we've delayed at least - // our START_DELAY_WINDOW_IN_SECS - bool doDownShift = _lastAdjustWasUpShift - ? (elapsedSinceUpShift > START_SHIFT_ELPASED && _fpsAverageStartWindow.getAverage() < getLODDecreaseFPS()) - : (elapsedSinceDownShift > DOWN_SHIFT_ELPASED && _fpsAverageDownWindow.getAverage() < getLODDecreaseFPS()); + // If we've been downshifting, we watch a shorter downshift window so that we will quickly move toward our + // target frame rate. But if we haven't just done a downshift (either because our last shift was an upshift, + // or because we've just started out) then we look at a much longer window to consider whether or not to start + // downshifting. + bool doDownShift = false; + if (_isDownshifting) { + doDownShift = (elapsedSinceDownShift > DOWN_SHIFT_ELPASED && _fpsAverageDownWindow.getAverage() < getLODDecreaseFPS()); + } else { + doDownShift = (elapsedSinceUpShift > START_SHIFT_ELPASED && _fpsAverageStartWindow.getAverage() < getLODDecreaseFPS()); + } if (doDownShift) { @@ -83,24 +89,26 @@ void LODManager::autoAdjustLOD(float currentFPS) { } if (changed) { - if (_lastAdjustWasUpShift) { - qDebug() << "adjusting LOD DOWN after initial delay..." - << "average fps for last "<< START_DELAY_WINDOW_IN_SECS <<"seconds was " - << _fpsAverageStartWindow.getAverage() - << "minimum is:" << getLODDecreaseFPS() - << "elapsedSinceUpShift:" << elapsedSinceUpShift - << " NEW _octreeSizeScale=" << _octreeSizeScale; - } else { + if (_isDownshifting) { + // subsequent downshift qDebug() << "adjusting LOD DOWN..." << "average fps for last "<< DOWN_SHIFT_WINDOW_IN_SECS <<"seconds was " << _fpsAverageDownWindow.getAverage() << "minimum is:" << getLODDecreaseFPS() << "elapsedSinceDownShift:" << elapsedSinceDownShift << " NEW _octreeSizeScale=" << _octreeSizeScale; + } else { + // first downshift + qDebug() << "adjusting LOD DOWN after initial delay..." + << "average fps for last "<< START_DELAY_WINDOW_IN_SECS <<"seconds was " + << _fpsAverageStartWindow.getAverage() + << "minimum is:" << getLODDecreaseFPS() + << "elapsedSinceUpShift:" << elapsedSinceUpShift + << " NEW _octreeSizeScale=" << _octreeSizeScale; } _lastDownShift = now; - _lastAdjustWasUpShift = false; + _isDownshifting = true; emit LODDecreased(); } @@ -130,7 +138,7 @@ void LODManager::autoAdjustLOD(float currentFPS) { << " NEW _octreeSizeScale=" << _octreeSizeScale; _lastUpShift = now; - _lastAdjustWasUpShift = true; + _isDownshifting = false; emit LODIncreased(); } @@ -149,13 +157,11 @@ void LODManager::autoAdjustLOD(float currentFPS) { } void LODManager::resetLODAdjust() { - - // TODO: Do we need this??? - /* + _fpsAverageStartWindow.reset(); _fpsAverageDownWindow.reset(); _fpsAverageUpWindow.reset(); - _lastAdjust = usecTimestampNow(); - */ + _lastUpShift = _lastDownShift = usecTimestampNow(); + _isDownshifting = false; } QString LODManager::getLODFeedbackText() { diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 3f9d2046c1..d3765c164a 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -107,7 +107,7 @@ private: quint64 _lastDownShift = 0; quint64 _lastUpShift = 0; - bool _lastAdjustWasUpShift = true; // start out as if we've just upshifted + bool _isDownshifting = false; // start out as if we're not downshifting SimpleMovingAverage _fpsAverageStartWindow = START_DELAY_SAMPLES_OF_FRAMES; SimpleMovingAverage _fpsAverageDownWindow = DOWN_SHIFT_SAMPLES_OF_FRAMES; From f46067b634b7530ba7f84dc24d4e8469c79ab515 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 25 Mar 2015 16:30:33 -0700 Subject: [PATCH 51/53] better tracking of being done with downshifting --- interface/src/LODManager.cpp | 51 +++++++++++++++++++++++------------- interface/src/LODManager.h | 1 + 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index e1a82372d2..d12fe9147a 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -48,7 +48,7 @@ void LODManager::autoAdjustLOD(float currentFPS) { //const float ASSUMED_FPS = 60.0f; if (_fpsAverageUpWindow.getSampleCount() < IGNORE_THESE_SAMPLES) { currentFPS = ASSUMED_FPS; - _lastUpShift = _lastDownShift = usecTimestampNow(); + _lastStable = _lastUpShift = _lastDownShift = usecTimestampNow(); } _fpsAverageStartWindow.updateAverage(currentFPS); @@ -58,9 +58,11 @@ void LODManager::autoAdjustLOD(float currentFPS) { quint64 now = usecTimestampNow(); bool changed = false; - bool octreeChanged = false; quint64 elapsedSinceDownShift = now - _lastDownShift; quint64 elapsedSinceUpShift = now - _lastUpShift; + + quint64 lastStableOrUpshift = glm::max(_lastUpShift, _lastStable); + quint64 elapsedSinceStableOrUpShift = now - lastStableOrUpshift; if (_automaticLODAdjust) { @@ -72,9 +74,19 @@ void LODManager::autoAdjustLOD(float currentFPS) { bool doDownShift = false; if (_isDownshifting) { - doDownShift = (elapsedSinceDownShift > DOWN_SHIFT_ELPASED && _fpsAverageDownWindow.getAverage() < getLODDecreaseFPS()); + // only consider things if our DOWN_SHIFT time has elapsed... + if (elapsedSinceDownShift > DOWN_SHIFT_ELPASED) { + doDownShift = _fpsAverageDownWindow.getAverage() < getLODDecreaseFPS(); + + if (!doDownShift) { + qDebug() << "---- WE APPEAR TO BE DONE DOWN SHIFTING -----"; + _isDownshifting = false; + _lastStable = now; + } + } } else { - doDownShift = (elapsedSinceUpShift > START_SHIFT_ELPASED && _fpsAverageStartWindow.getAverage() < getLODDecreaseFPS()); + doDownShift = (elapsedSinceStableOrUpShift > START_SHIFT_ELPASED + && _fpsAverageStartWindow.getAverage() < getLODDecreaseFPS()); } if (doDownShift) { @@ -85,7 +97,7 @@ void LODManager::autoAdjustLOD(float currentFPS) { if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) { _octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE; } - octreeChanged = changed = true; + changed = true; } if (changed) { @@ -109,25 +121,28 @@ void LODManager::autoAdjustLOD(float currentFPS) { _lastDownShift = now; _isDownshifting = true; - + emit LODDecreased(); } } else { // LOD Upward adjustment - if (elapsedSinceUpShift > UP_SHIFT_ELPASED && _fpsAverageUpWindow.getAverage() > getLODIncreaseFPS()) { + if (elapsedSinceUpShift > UP_SHIFT_ELPASED) { + + if (_fpsAverageUpWindow.getAverage() > getLODIncreaseFPS()) { - // Octee items... stepwise adjustment - if (_octreeSizeScale < ADJUST_LOD_MAX_SIZE_SCALE) { - if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) { - _octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE; - } else { - _octreeSizeScale *= ADJUST_LOD_UP_BY; + // Octee items... stepwise adjustment + if (_octreeSizeScale < ADJUST_LOD_MAX_SIZE_SCALE) { + if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) { + _octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE; + } else { + _octreeSizeScale *= ADJUST_LOD_UP_BY; + } + if (_octreeSizeScale > ADJUST_LOD_MAX_SIZE_SCALE) { + _octreeSizeScale = ADJUST_LOD_MAX_SIZE_SCALE; + } + changed = true; } - if (_octreeSizeScale > ADJUST_LOD_MAX_SIZE_SCALE) { - _octreeSizeScale = ADJUST_LOD_MAX_SIZE_SCALE; - } - octreeChanged = changed = true; } if (changed) { @@ -139,7 +154,7 @@ void LODManager::autoAdjustLOD(float currentFPS) { _lastUpShift = now; _isDownshifting = false; - + emit LODIncreased(); } } diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index d3765c164a..4003d09344 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -107,6 +107,7 @@ private: quint64 _lastDownShift = 0; quint64 _lastUpShift = 0; + quint64 _lastStable = 0; bool _isDownshifting = false; // start out as if we're not downshifting SimpleMovingAverage _fpsAverageStartWindow = START_DELAY_SAMPLES_OF_FRAMES; From 19feeacc51e7db68ac03399be13bb845b9c2829d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 25 Mar 2015 16:38:57 -0700 Subject: [PATCH 52/53] dead code --- interface/src/LODManager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index d12fe9147a..cb4913df72 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -45,7 +45,6 @@ void LODManager::autoAdjustLOD(float currentFPS) { // really want to count them in our average, so we will ignore the real frame rates and stuff // our moving average with simulated good data const int IGNORE_THESE_SAMPLES = 100; - //const float ASSUMED_FPS = 60.0f; if (_fpsAverageUpWindow.getSampleCount() < IGNORE_THESE_SAMPLES) { currentFPS = ASSUMED_FPS; _lastStable = _lastUpShift = _lastDownShift = usecTimestampNow(); From c031ce15a7908d32496803332b52f8657e3ab47a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 25 Mar 2015 16:45:51 -0700 Subject: [PATCH 53/53] dead code --- interface/src/LODManager.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 4003d09344..77f156531a 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -76,10 +76,6 @@ public: Q_INVOKABLE void setBoundaryLevelAdjust(int boundaryLevelAdjust); Q_INVOKABLE int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; } - Q_INVOKABLE void resetLODAdjust(); - //Q_INVOKABLE float getFPSAverage() const { return _fpsAverage.getAverage(); } - //Q_INVOKABLE float getFastFPSAverage() const { return _fastFPSAverage.getAverage(); } - Q_INVOKABLE float getLODDecreaseFPS(); Q_INVOKABLE float getLODIncreaseFPS(); @@ -88,6 +84,7 @@ public: void loadSettings(); void saveSettings(); + void resetLODAdjust(); signals: void LODIncreased();