From 8e83943efd4840f25166c2d12ffa482f38938d12 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 28 Oct 2015 15:43:36 -0700 Subject: [PATCH 01/13] Don't play other avatar's collision sounds. https://app.asana.com/0/32622044445063/61104546898252 --- libraries/physics/src/PhysicsEngine.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index d6772f8d36..0efa0c0f39 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -352,16 +352,16 @@ const CollisionEvents& PhysicsEngine::getCollisionEvents() { glm::vec3 velocityChange = (motionStateA ? motionStateA->getObjectLinearVelocityChange() : glm::vec3(0.0f)) + (motionStateB ? motionStateB->getObjectLinearVelocityChange() : glm::vec3(0.0f)); - if (motionStateA && motionStateA->getType() == MOTIONSTATE_TYPE_ENTITY) { + if (motionStateA) { QUuid idA = motionStateA->getObjectID(); QUuid idB; - if (motionStateB && motionStateB->getType() == MOTIONSTATE_TYPE_ENTITY) { + if (motionStateB) { idB = motionStateB->getObjectID(); } glm::vec3 position = bulletToGLM(contact.getPositionWorldOnB()) + _originOffset; glm::vec3 penetration = bulletToGLM(contact.distance * contact.normalWorldOnB); _collisionEvents.push_back(Collision(type, idA, idB, position, penetration, velocityChange)); - } else if (motionStateB && motionStateB->getType() == MOTIONSTATE_TYPE_ENTITY) { + } else if (motionStateB) { QUuid idB = motionStateB->getObjectID(); glm::vec3 position = bulletToGLM(contact.getPositionWorldOnA()) + _originOffset; // NOTE: we're flipping the order of A and B (so that the first objectID is never NULL) From 792fed0090a7f633e92e7912d0297b8d9134e4be Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 29 Oct 2015 22:15:26 -0700 Subject: [PATCH 02/13] We weren't setting type for avatar motion states. --- interface/src/avatar/AvatarMotionState.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/avatar/AvatarMotionState.cpp b/interface/src/avatar/AvatarMotionState.cpp index cabe545f5a..acd9a45aab 100644 --- a/interface/src/avatar/AvatarMotionState.cpp +++ b/interface/src/avatar/AvatarMotionState.cpp @@ -18,6 +18,7 @@ AvatarMotionState::AvatarMotionState(Avatar* avatar, btCollisionShape* shape) : ObjectMotionState(shape), _avatar(avatar) { assert(_avatar); + _type = MOTIONSTATE_TYPE_AVATAR; if (_shape) { _mass = 100.0f; // HACK } From ce1d0fe07c1d89e3bff075a2e31455d5e58688a1 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Fri, 30 Oct 2015 11:25:54 -0700 Subject: [PATCH 03/13] Git rid of unused (un-emitted and intended to be removed long ago) script signal. --- libraries/entities/src/EntityScriptingInterface.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index d764cd7bab..156f16cf46 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -152,7 +152,6 @@ public slots: Q_INVOKABLE glm::vec3 localCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 localCoords); signals: - void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); void canAdjustLocksChanged(bool canAdjustLocks); From fc63fa6f7b963acc1c6c481a35009c8a5b9e939b Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Sun, 1 Nov 2015 18:55:43 -0800 Subject: [PATCH 04/13] Update comments, and don't continue through collisions after finding one for our avatar. --- interface/src/avatar/AvatarManager.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index b0da8faeca..4b9bfd21a3 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -286,10 +286,10 @@ void AvatarManager::handleOutgoingChanges(const VectorOfMotionStates& motionStat void AvatarManager::handleCollisionEvents(const CollisionEvents& collisionEvents) { for (Collision collision : collisionEvents) { - // TODO: Current physics uses null idA or idB for non-entities. The plan is to handle MOTIONSTATE_TYPE_AVATAR, - // and then MOTIONSTATE_TYPE_MYAVATAR. As it is, this code only covers the case of my avatar (in which case one - // if the ids will be null), and the behavior for other avatars is not specified. This has to be fleshed - // out as soon as we use the new motionstates. + // TODO: The plan is to handle MOTIONSTATE_TYPE_AVATAR, and then MOTIONSTATE_TYPE_MYAVATAR. As it is, other + // people's avatars will have an id that doesn't match any entities, and one's own avatar will have + // an id of null. Thus this code handles any collision in which one of the participating objects is + // my avatar. (Other user machines will make a similar analysis and inject sound for their collisions.) if (collision.idA.isNull() || collision.idB.isNull()) { MyAvatar* myAvatar = getMyAvatar(); const QString& collisionSoundURL = myAvatar->getCollisionSoundURL(); @@ -299,9 +299,7 @@ void AvatarManager::handleCollisionEvents(const CollisionEvents& collisionEvents const bool isSound = (collision.type == CONTACT_EVENT_TYPE_START) && (velocityChange > MIN_AVATAR_COLLISION_ACCELERATION); if (!isSound) { - // TODO: When the new motion states are used, we'll probably break from the whole loop as soon as we hit our own avatar - // (regardless of isSound), because other users should inject for their own avatars. - continue; + return; // No sense iterating for others. We only have one avatar. } // Your avatar sound is personal to you, so let's say the "mass" part of the kinetic energy is already accounted for. const float energy = velocityChange * velocityChange; @@ -314,7 +312,7 @@ void AvatarManager::handleCollisionEvents(const CollisionEvents& collisionEvents AudioInjector::playSound(collisionSoundURL, energyFactorOfFull, AVATAR_STRETCH_FACTOR, myAvatar->getPosition()); myAvatar->collisionWithEntity(collision); - } + return; } } } } From 0c12bb5a4ea613697599d77ad3970cdb0390596f Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 2 Nov 2015 18:47:18 -0800 Subject: [PATCH 05/13] Remove idleTimer and call idle directly from paintGL. --- interface/src/Application.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6d41679bea..4c55e05b01 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -160,7 +160,6 @@ static QTimer balanceUpdateTimer; static QTimer identityPacketTimer; static QTimer billboardPacketTimer; static QTimer checkFPStimer; -static QTimer idleTimer; static const QString SNAPSHOT_EXTENSION = ".jpg"; static const QString SVO_EXTENSION = ".svo"; @@ -844,7 +843,6 @@ void Application::cleanupBeforeQuit() { identityPacketTimer.stop(); billboardPacketTimer.stop(); checkFPStimer.stop(); - idleTimer.stop(); QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection); // save state @@ -982,9 +980,6 @@ void Application::initializeGL() { connect(&checkFPStimer, &QTimer::timeout, this, &Application::checkFPS); checkFPStimer.start(1000); - // call our idle function whenever we can - connect(&idleTimer, &QTimer::timeout, this, &Application::idle); - idleTimer.start(TARGET_SIM_FRAME_PERIOD_MS); _idleLoopStdev.reset(); // update before the first render @@ -1048,6 +1043,9 @@ void Application::initializeUi() { } void Application::paintGL() { + + idle(); + PROFILE_RANGE(__FUNCTION__); PerformanceTimer perfTimer("paintGL"); From c139b62217742ce96ee43c712db6e5c40f0cc012 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 3 Nov 2015 11:19:49 -0800 Subject: [PATCH 06/13] fps calculation now based on moving average fps stat is now calcualted the same way as simRate and avatarRate are calculated, based on a moving average that is sampled once a second. Also, Removed unused constants and renamed Application::checkFPS to Application::ping --- interface/src/Application.cpp | 39 +++++++++++++++++++++-------------- interface/src/Application.h | 4 +++- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4c55e05b01..1f04338f99 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -159,7 +159,7 @@ static QTimer locationUpdateTimer; static QTimer balanceUpdateTimer; static QTimer identityPacketTimer; static QTimer billboardPacketTimer; -static QTimer checkFPStimer; +static QTimer pingTimer; static const QString SNAPSHOT_EXTENSION = ".jpg"; static const QString SVO_EXTENSION = ".svo"; @@ -183,9 +183,7 @@ static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS static const QString INFO_HELP_PATH = "html/interface-welcome.html"; static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-commands.html"; -static const unsigned int TARGET_SIM_FRAMERATE = 60; static const unsigned int THROTTLED_SIM_FRAMERATE = 15; -static const int TARGET_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / TARGET_SIM_FRAMERATE; static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SIM_FRAMERATE; #ifndef __APPLE__ @@ -842,7 +840,7 @@ void Application::cleanupBeforeQuit() { balanceUpdateTimer.stop(); identityPacketTimer.stop(); billboardPacketTimer.stop(); - checkFPStimer.stop(); + pingTimer.stop(); QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection); // save state @@ -977,8 +975,8 @@ void Application::initializeGL() { _entityEditSender.initialize(_enableProcessOctreeThread); // call our timer function every second - connect(&checkFPStimer, &QTimer::timeout, this, &Application::checkFPS); - checkFPStimer.start(1000); + connect(&pingTimer, &QTimer::timeout, this, &Application::ping); + pingTimer.start(1000); _idleLoopStdev.reset(); @@ -1312,7 +1310,6 @@ void Application::paintGL() { { PerformanceTimer perfTimer("makeCurrent"); _offscreenContext->makeCurrent(); - _frameCount++; Stats::getInstance()->setRenderDetails(renderArgs._details); // Reset the gpu::Context Stages @@ -1321,6 +1318,24 @@ void Application::paintGL() { batch.resetStages(); }); } + + // update fps moving average + { + uint64_t now = usecTimestampNow(); + static uint64_t lastPaintEnd{ now }; + uint64_t diff = now - lastPaintEnd; + if (diff != 0) { + _framesPerSecond.updateAverage((float)USECS_PER_SECOND / (float)diff); + } + lastPaintEnd = now; + + // update fps once a second + if (now - _lastFramesPerSecondUpdate > USECS_PER_SECOND) { + _fps = _framesPerSecond.getAverage(); + _lastFramesPerSecondUpdate = now; + } + _frameCount++; + } } void Application::runTests() { @@ -2085,17 +2100,11 @@ bool Application::acceptSnapshot(const QString& urlString) { return true; } -// Every second, check the frame rates and other stuff -void Application::checkFPS() { +// Every second, send a ping, if menu item is checked. +void Application::ping() { if (Menu::getInstance()->isOptionChecked(MenuOption::TestPing)) { DependencyManager::get()->sendPingPackets(); } - - float diffTime = (float)_timerStart.nsecsElapsed() / 1000000000.0f; - - _fps = (float)_frameCount / diffTime; - _frameCount = 0; - _timerStart.start(); } void Application::idle() { diff --git a/interface/src/Application.h b/interface/src/Application.h index dfc904e0ef..0fd8c74494 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -306,7 +306,7 @@ public slots: private slots: void clearDomainOctreeDetails(); - void checkFPS(); + void ping(); void idle(); void aboutToQuit(); @@ -541,6 +541,8 @@ private: EntityItemID _keyboardFocusedItem; quint64 _lastAcceptedKeyPress = 0; + SimpleMovingAverage _framesPerSecond{10}; + quint64 _lastFramesPerSecondUpdate = 0; SimpleMovingAverage _simsPerSecond{10}; int _simsPerSecondReport = 0; quint64 _lastSimsPerSecondUpdate = 0; From 12ff9734e05391cfe3124cd3f24c6fe4a1ffbf8c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 3 Nov 2015 11:26:49 -0800 Subject: [PATCH 07/13] init _bodySensorMatrix in ctor --- interface/src/avatar/MyAvatar.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 00870c62c6..4376aa6d79 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -121,6 +121,12 @@ MyAvatar::MyAvatar(RigPointer rig) : connect(DependencyManager::get().data(), &AddressManager::locationChangeRequired, this, &MyAvatar::goToLocation); _characterController.setEnabled(true); + + _hmdSensorMatrix = glm::mat4(); + _hmdSensorPosition = extractTranslation(_hmdSensorMatrix); + _hmdSensorOrientation = glm::quat_cast(_hmdSensorMatrix); + _bodySensorMatrix = deriveBodyFromHMDSensor(); + updateSensorToWorldMatrix(); } MyAvatar::~MyAvatar() { From e160e2a7ae88a1d7ca632fa6c15ad69196811987 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 3 Nov 2015 11:37:30 -0800 Subject: [PATCH 08/13] the minimal fix --- interface/src/avatar/MyAvatar.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4376aa6d79..a5b39ef6e9 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -122,11 +122,7 @@ MyAvatar::MyAvatar(RigPointer rig) : this, &MyAvatar::goToLocation); _characterController.setEnabled(true); - _hmdSensorMatrix = glm::mat4(); - _hmdSensorPosition = extractTranslation(_hmdSensorMatrix); - _hmdSensorOrientation = glm::quat_cast(_hmdSensorMatrix); _bodySensorMatrix = deriveBodyFromHMDSensor(); - updateSensorToWorldMatrix(); } MyAvatar::~MyAvatar() { From b83b24b096a35d217d944844229405f6bf64628c Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 3 Nov 2015 13:42:18 -0800 Subject: [PATCH 09/13] remove strange test file --- examples/tests/timerStressTest.js | 68 ------------------------------- 1 file changed, 68 deletions(-) delete mode 100644 examples/tests/timerStressTest.js diff --git a/examples/tests/timerStressTest.js b/examples/tests/timerStressTest.js deleted file mode 100644 index a1cf76c5a6..0000000000 --- a/examples/tests/timerStressTest.js +++ /dev/null @@ -1,68 +0,0 @@ -// createBoxes.js -// part of bubblewand -// -// Created by James B. Pollack @imgntn -- 09/07/2015 -// Copyright 2015 High Fidelity, Inc. -// -// Loads a wand model and attaches the bubble wand behavior. -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html - - - -Script.include("https://raw.githubusercontent.com/highfidelity/hifi/master/examples/utilities.js"); -Script.include("https://raw.githubusercontent.com/highfidelity/hifi/master/examples/libraries/utils.js"); - -var bubbleModel = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/bubble/bubble.fbx?' + randInt(0, 10000);; -//var scriptURL'http://hifi-public.s3.amazonaws.com/james/bubblewand/scripts/wand.js?'+randInt(0,10000); - -//for local testing -//var scriptURL = "http://localhost:8080/scripts/setRecurringTimeout.js?" + randInt(0, 10000); - - -var scriptURL='http://hifi-public.s3.amazonaws.com/james/debug/timeouts/setRecurringTimeout.js?'+ randInt(0, 10000); -//create the wand in front of the avatar - -var boxes=[]; -var TEST_ENTITY_NAME = "TimerScript"; - - -var TOTAL_ENTITIES = 100; -for (var i = 0; i < TOTAL_ENTITIES; i++) { - var box = Entities.addEntity({ - type: "Box", - name: TEST_ENTITY_NAME, - position: { - x: randInt(0, 100) - 50 + MyAvatar.position.x, - y: randInt(0, 100) - 50 + MyAvatar.position.x, - z: randInt(0, 100) - 50 + MyAvatar.position.x, - }, - dimensions: { - x: 1, - y: 1, - z: 1, - }, - color: { - red: 255, - green: 0, - blue: 0, - }, - //must be enabled to be grabbable in the physics engine - collisionsWillMove: true, - shapeType: 'box', - lifetime:60, - script: scriptURL - }); - boxes.push(box) -} - - -function cleanup() { - while (boxes.length > 0) { - Entities.deleteEntity(boxes.pop()); - - } -} - - -Script.scriptEnding.connect(cleanup); \ No newline at end of file From d544b7a645a779d95caed858b36b1440a5f9dc5a Mon Sep 17 00:00:00 2001 From: "U-GAPOS\\andrew" Date: Tue, 3 Nov 2015 13:59:15 -0800 Subject: [PATCH 10/13] fix bug: avatar can't walking when HMD at rest --- interface/src/avatar/MyAvatar.cpp | 37 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index a5b39ef6e9..741a82fdb8 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -347,23 +347,6 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { } void MyAvatar::updateHMDFollowVelocity() { - bool isMoving; - if (_lastIsMoving) { - const float MOVE_EXIT_SPEED_THRESHOLD = 0.07f; // m/sec - isMoving = glm::length(_velocity) >= MOVE_EXIT_SPEED_THRESHOLD; - } else { - const float MOVE_ENTER_SPEED_THRESHOLD = 0.2f; // m/sec - isMoving = glm::length(_velocity) > MOVE_ENTER_SPEED_THRESHOLD; - } - - bool justStartedMoving = (_lastIsMoving != isMoving) && isMoving; - _lastIsMoving = isMoving; - - bool hmdIsAtRest = _hmdAtRestDetector.update(_hmdSensorPosition, _hmdSensorOrientation); - if (hmdIsAtRest || justStartedMoving) { - _isFollowingHMD = true; - } - // compute offset to body's target position (in sensor-frame) auto sensorBodyMatrix = deriveBodyFromHMDSensor(); _hmdFollowOffset = extractTranslation(sensorBodyMatrix) - extractTranslation(_bodySensorMatrix); @@ -372,13 +355,29 @@ void MyAvatar::updateHMDFollowVelocity() { // don't pull the body DOWN to match the target (allow animation system to squat) truncatedOffset.y = 0.0f; } + float truncatedOffsetDistance = glm::length(truncatedOffset); + + bool isMoving; + if (_lastIsMoving) { + const float MOVE_EXIT_SPEED_THRESHOLD = 0.07f; // m/sec + isMoving = glm::length(_velocity) >= MOVE_EXIT_SPEED_THRESHOLD; + } else { + const float MOVE_ENTER_SPEED_THRESHOLD = 0.2f; // m/sec + isMoving = glm::length(_velocity) > MOVE_ENTER_SPEED_THRESHOLD; + } + bool justStartedMoving = (_lastIsMoving != isMoving) && isMoving; + _lastIsMoving = isMoving; + bool hmdIsAtRest = _hmdAtRestDetector.update(_hmdSensorPosition, _hmdSensorOrientation); + const float MIN_HMD_HIP_SHIFT = 0.05f; + if (justStartedMoving || (hmdIsAtRest && truncatedOffsetDistance > MIN_HMD_HIP_SHIFT)) { + _isFollowingHMD = true; + } bool needNewFollowSpeed = (_isFollowingHMD && _hmdFollowSpeed == 0.0f); if (!needNewFollowSpeed) { // check to see if offset has exceeded its threshold - float distance = glm::length(truncatedOffset); const float MAX_HMD_HIP_SHIFT = 0.2f; - if (distance > MAX_HMD_HIP_SHIFT) { + if (truncatedOffsetDistance > MAX_HMD_HIP_SHIFT) { _isFollowingHMD = true; needNewFollowSpeed = true; } From 8346ce27b322aa2d422045b6a4a97d7a0d309ab3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 3 Nov 2015 14:22:41 -0800 Subject: [PATCH 11/13] allow a non-colliding grab of locked entities --- examples/controllers/handControllerGrab.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index edb9fe05bd..936a00db07 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -291,7 +291,7 @@ function MyController(hand) { return this.triggerValue < TRIGGER_OFF_VALUE; }; - this.triggerSqueezed = function() { + this.triggerSqueezed = function() { var triggerValue = this.rawTriggerValue; return triggerValue > TRIGGER_ON_VALUE; }; @@ -352,7 +352,7 @@ function MyController(hand) { var intersection = Entities.findRayIntersection(pickRayBacked, true); - if (intersection.intersects && !intersection.properties.locked) { + if (intersection.intersects) { // the ray is intersecting something we can move. var intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection); this.grabbedEntity = intersection.entityID; @@ -381,7 +381,7 @@ function MyController(hand) { // the hand is very close to the intersected object. go into close-grabbing mode. if (grabbableData.wantsTrigger) { this.setState(STATE_NEAR_GRABBING_NON_COLLIDING); - } else { + } else if (!intersection.properties.locked) { this.setState(STATE_NEAR_GRABBING); } } else { @@ -390,7 +390,8 @@ function MyController(hand) { this.grabbedEntity = null; } else { // the hand is far from the intersected object. go into distance-holding mode - if (intersection.properties.collisionsWillMove) { + if (intersection.properties.collisionsWillMove + && !intersection.properties.locked) { this.setState(STATE_DISTANCE_HOLDING); } else { this.setState(STATE_FAR_GRABBING_NON_COLLIDING); @@ -502,7 +503,7 @@ function MyController(hand) { // How far did the avatar turn this timestep? // Note: The following code is too long because we need a Quat.quatBetween() function - // that returns the minimum quaternion between two quaternions. + // that returns the minimum quaternion between two quaternions. var currentOrientation = MyAvatar.orientation; if (Quat.dot(currentOrientation, this.currentAvatarOrientation) < 0.0) { var negativeCurrentOrientation = { From 31f361d49ca445ce84ca7c0a3ca8875554f42a7a Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 3 Nov 2015 15:51:18 -0800 Subject: [PATCH 12/13] Moved fps timing to beginning of paintGL This should improve accuracy. However the fps displayed can still sometimes be slightly greater then the vsync, this is either due to timer accuracy problems or QTimer delay within OpenGLDisplayPlugin. --- interface/src/Application.cpp | 40 +++++++++++++++++------------------ interface/src/Application.h | 2 +- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1f04338f99..d31d9de4a0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1041,8 +1041,25 @@ void Application::initializeUi() { } void Application::paintGL() { + _frameCount++; - idle(); + // update fps moving average + uint64_t now = usecTimestampNow(); + static uint64_t lastPaintBegin{ now }; + uint64_t diff = now - lastPaintBegin; + if (diff != 0) { + _framesPerSecond.updateAverage((float)USECS_PER_SECOND / (float)diff); + } + + lastPaintBegin = now; + + // update fps once a second + if (now - _lastFramesPerSecondUpdate > USECS_PER_SECOND) { + _fps = _framesPerSecond.getAverage(); + _lastFramesPerSecondUpdate = now; + } + + idle(now); PROFILE_RANGE(__FUNCTION__); PerformanceTimer perfTimer("paintGL"); @@ -1318,24 +1335,6 @@ void Application::paintGL() { batch.resetStages(); }); } - - // update fps moving average - { - uint64_t now = usecTimestampNow(); - static uint64_t lastPaintEnd{ now }; - uint64_t diff = now - lastPaintEnd; - if (diff != 0) { - _framesPerSecond.updateAverage((float)USECS_PER_SECOND / (float)diff); - } - lastPaintEnd = now; - - // update fps once a second - if (now - _lastFramesPerSecondUpdate > USECS_PER_SECOND) { - _fps = _framesPerSecond.getAverage(); - _lastFramesPerSecondUpdate = now; - } - _frameCount++; - } } void Application::runTests() { @@ -2107,7 +2106,7 @@ void Application::ping() { } } -void Application::idle() { +void Application::idle(uint64_t now) { if (_aboutToQuit) { return; // bail early, nothing to do here. } @@ -2130,7 +2129,6 @@ void Application::idle() { { PROFILE_RANGE(__FUNCTION__); - uint64_t now = usecTimestampNow(); static uint64_t lastIdleStart{ now }; uint64_t idleStartToStartDuration = now - lastIdleStart; if (idleStartToStartDuration != 0) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 0fd8c74494..212687c11e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -307,7 +307,7 @@ public slots: private slots: void clearDomainOctreeDetails(); void ping(); - void idle(); + void idle(uint64_t now); void aboutToQuit(); void handleScriptEngineLoaded(const QString& scriptFilename); From d8797ef9d76ca112746c974e6f885d38200ef93f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 3 Nov 2015 15:56:37 -0800 Subject: [PATCH 13/13] Initialize relativePosition/Rotation --- examples/controllers/handControllerGrab.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 936a00db07..a8919105d1 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -176,6 +176,9 @@ function MyController(hand) { this.pointer = null; // entity-id of line object this.triggerValue = 0; // rolling average of trigger value this.rawTriggerValue = 0; + + this.offsetPosition = { x: 0.0, y: 0.0, z: 0.0 }; + this.offsetRotation = { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }; var _this = this;