From 6b9b4d4e6e38d6c8428261c1699f3074ecedc570 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 26 Oct 2015 10:44:39 -0700 Subject: [PATCH 01/44] Add libraries/line.js --- examples/libraries/line.js | 149 +++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 examples/libraries/line.js diff --git a/examples/libraries/line.js b/examples/libraries/line.js new file mode 100644 index 0000000000..62811e50bc --- /dev/null +++ b/examples/libraries/line.js @@ -0,0 +1,149 @@ +function error(message) { + print("[ERROR] " + message); +} + +// PolyLine +var LINE_DIMENSIONS = { x: 2000, y: 2000, z: 2000 }; +var MAX_LINE_LENGTH = 40; // This must be 2 or greater; +var PolyLine = function(position, color, defaultStrokeWidth) { + this.position = position; + this.color = color; + this.defaultStrokeWidth = 0.10; + this.points = [ + { x: 0, y: 0, z: 0 } + ]; + this.strokeWidths = [ + this.defaultStrokeWidth + ]; + this.normals = [ + { x: 1, y: 0, z: 0 } + ] + this.entityID = Entities.addEntity({ + type: "PolyLine", + position: position, + linePoints: this.points, + normals: this.normals, + strokeWidths: this.strokeWidths, + dimensions: LINE_DIMENSIONS, + color: color, + lifetime: 20, + }); +}; + +PolyLine.prototype.enqueuePoint = function(position) { + if (this.isFull()) { + error("Hit max PolyLine size"); + return; + } + + position = Vec3.subtract(position, this.position); + this.points.push(position); + this.normals.push({ x: 1, y: 0, z: 0 }); + this.strokeWidths.push(this.defaultStrokeWidth * Math.min(1.0, this.points.length / 10)); + Entities.editEntity(this.entityID, { + linePoints: this.points, + normals: this.normals, + strokeWidths: this.strokeWidths, + }); +}; + +PolyLine.prototype.dequeuePoint = function() { + if (this.points.length == 0) { + error("Hit min PolyLine size"); + return; + } + + this.points = this.points.slice(1); + this.normals = this.normals.slice(1); + this.strokeWidths = this.strokeWidths.slice(1); + + Entities.editEntity(this.entityID, { + linePoints: this.points, + normals: this.normals, + strokeWidths: this.strokeWidths, + }); +}; + +PolyLine.prototype.getFirstPoint = function() { + return Vec3.sum(this.position, this.points[0]); +}; + +PolyLine.prototype.getLastPoint = function() { + return Vec3.sum(this.position, this.points[this.points.length - 1]); +}; + +PolyLine.prototype.getSize = function() { + return this.points.length; +} + +PolyLine.prototype.isFull = function() { + return this.points.length >= MAX_LINE_LENGTH; +}; + +PolyLine.prototype.destroy = function() { + Entities.deleteEntity(this.entityID); + this.points = []; +}; + + + +// InfiniteLine +InfiniteLine = function(position, color) { + this.position = position; + this.color = color; + this.lines = [new PolyLine(position, color)]; + this.size = 0; +}; + +InfiniteLine.prototype.enqueuePoint = function(position) { + var currentLine; + + if (this.lines.length == 0) { + currentLine = new PolyLine(position, this.color); + this.lines.push(currentLine); + } else { + currentLine = this.lines[this.lines.length - 1]; + } + + if (currentLine.isFull()) { + var newLine = new PolyLine(currentLine.getLastPoint(), this.color); + this.lines.push(newLine); + currentLine = newLine; + } + + currentLine.enqueuePoint(position); + + ++this.size; +}; + +InfiniteLine.prototype.dequeuePoint = function() { + if (this.lines.length == 0) { + error("Trying to dequeue from InfiniteLine when no points are left"); + return; + } + + var lastLine = this.lines[0]; + lastLine.dequeuePoint(); + + if (lastLine.getSize() <= 1) { + this.lines = this.lines.slice(1); + } + + --this.size; +}; + +InfiniteLine.prototype.getFirstPoint = function() { + return this.lines.length > 0 ? this.lines[0].getFirstPoint() : null; +}; + +InfiniteLine.prototype.getLastPoint = function() { + return this.lines.length > 0 ? this.lines[lines.length - 1].getLastPoint() : null; +}; + +InfiniteLine.prototype.destroy = function() { + for (var i = 0; i < this.lines.length; ++i) { + this.lines[i].destroy(); + } + + this.size = 0; +}; From d6230fbed329f5db5780adca536012939d035a4c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 26 Oct 2015 10:46:36 -0700 Subject: [PATCH 02/44] Remove trailing commas in line.js --- examples/libraries/line.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/libraries/line.js b/examples/libraries/line.js index 62811e50bc..0834c6176e 100644 --- a/examples/libraries/line.js +++ b/examples/libraries/line.js @@ -26,7 +26,7 @@ var PolyLine = function(position, color, defaultStrokeWidth) { strokeWidths: this.strokeWidths, dimensions: LINE_DIMENSIONS, color: color, - lifetime: 20, + lifetime: 20 }); }; @@ -43,7 +43,7 @@ PolyLine.prototype.enqueuePoint = function(position) { Entities.editEntity(this.entityID, { linePoints: this.points, normals: this.normals, - strokeWidths: this.strokeWidths, + strokeWidths: this.strokeWidths }); }; @@ -60,7 +60,7 @@ PolyLine.prototype.dequeuePoint = function() { Entities.editEntity(this.entityID, { linePoints: this.points, normals: this.normals, - strokeWidths: this.strokeWidths, + strokeWidths: this.strokeWidths }); }; From 1a1ab29978e04302fb49aff32a2afcfd3611b147 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 26 Oct 2015 16:45:43 -0700 Subject: [PATCH 03/44] Add lineExample.js --- examples/example/lineExample.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 examples/example/lineExample.js diff --git a/examples/example/lineExample.js b/examples/example/lineExample.js new file mode 100644 index 0000000000..6642e499fb --- /dev/null +++ b/examples/example/lineExample.js @@ -0,0 +1,12 @@ +Script.include("../libraries/line.js"); + +var basePosition = MyAvatar.position; +var line = new InfiniteLine(basePosition); + +for (var i = 0; i < (16 * Math.PI); i += 0.05) { + var x = 0 + var y = 0.25 * Math.sin(i); + var z = i / 10; + + line.enqueuePoint(Vec3.sum(basePosition, { x: x, y: y, z: z })); +} From 2abb6a2fd5921f474a999eba368296fb00def4b4 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 26 Oct 2015 16:45:58 -0700 Subject: [PATCH 04/44] Clean up line.js --- examples/libraries/line.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/examples/libraries/line.js b/examples/libraries/line.js index 0834c6176e..991b691ae8 100644 --- a/examples/libraries/line.js +++ b/examples/libraries/line.js @@ -8,15 +8,12 @@ var MAX_LINE_LENGTH = 40; // This must be 2 or greater; var PolyLine = function(position, color, defaultStrokeWidth) { this.position = position; this.color = color; - this.defaultStrokeWidth = 0.10; + this.defaultStrokeWidth = defaultStrokeWidth; this.points = [ - { x: 0, y: 0, z: 0 } ]; this.strokeWidths = [ - this.defaultStrokeWidth ]; this.normals = [ - { x: 1, y: 0, z: 0 } ] this.entityID = Entities.addEntity({ type: "PolyLine", @@ -39,7 +36,7 @@ PolyLine.prototype.enqueuePoint = function(position) { position = Vec3.subtract(position, this.position); this.points.push(position); this.normals.push({ x: 1, y: 0, z: 0 }); - this.strokeWidths.push(this.defaultStrokeWidth * Math.min(1.0, this.points.length / 10)); + this.strokeWidths.push(this.defaultStrokeWidth); Entities.editEntity(this.entityID, { linePoints: this.points, normals: this.normals, @@ -91,7 +88,7 @@ PolyLine.prototype.destroy = function() { InfiniteLine = function(position, color) { this.position = position; this.color = color; - this.lines = [new PolyLine(position, color)]; + this.lines = [new PolyLine(position, color, 0.01)]; this.size = 0; }; @@ -99,14 +96,15 @@ InfiniteLine.prototype.enqueuePoint = function(position) { var currentLine; if (this.lines.length == 0) { - currentLine = new PolyLine(position, this.color); + currentLine = new PolyLine(position, this.color, 0.01); this.lines.push(currentLine); } else { currentLine = this.lines[this.lines.length - 1]; } if (currentLine.isFull()) { - var newLine = new PolyLine(currentLine.getLastPoint(), this.color); + var newLine = new PolyLine(currentLine.getLastPoint(), this.color, 0.01); + newLine.enqueuePoint(currentLine.getLastPoint()); this.lines.push(newLine); currentLine = newLine; } From 983c551ce35c0ff5c153d31fa4294a89f38d422c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 27 Oct 2015 09:13:16 -0700 Subject: [PATCH 05/44] Clean up line.js and make lifetime settable --- examples/example/lineExample.js | 7 +++++-- examples/libraries/line.js | 27 +++++++++++++++------------ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/examples/example/lineExample.js b/examples/example/lineExample.js index 6642e499fb..e6c3d90cba 100644 --- a/examples/example/lineExample.js +++ b/examples/example/lineExample.js @@ -1,12 +1,15 @@ Script.include("../libraries/line.js"); var basePosition = MyAvatar.position; -var line = new InfiniteLine(basePosition); +var color = { red: 128, green: 220, blue: 190 }; +var strokeWidth = 0.01; +var line = new InfiniteLine(basePosition, color, 20); for (var i = 0; i < (16 * Math.PI); i += 0.05) { var x = 0 var y = 0.25 * Math.sin(i); var z = i / 10; - line.enqueuePoint(Vec3.sum(basePosition, { x: x, y: y, z: z })); + var position = Vec3.sum(basePosition, { x: x, y: y, z: z }); + line.enqueuePoint(position, strokeWidth); } diff --git a/examples/libraries/line.js b/examples/libraries/line.js index 991b691ae8..77cb13c124 100644 --- a/examples/libraries/line.js +++ b/examples/libraries/line.js @@ -5,10 +5,13 @@ function error(message) { // PolyLine var LINE_DIMENSIONS = { x: 2000, y: 2000, z: 2000 }; var MAX_LINE_LENGTH = 40; // This must be 2 or greater; -var PolyLine = function(position, color, defaultStrokeWidth) { +var DEFAULT_STROKE_WIDTH = 0.1; +var DEFAULT_LIFETIME = 20; +var DEFAULT_COLOR = { red: 255, green: 255, blue: 255 }; +var PolyLine = function(position, color, lifetime) { this.position = position; this.color = color; - this.defaultStrokeWidth = defaultStrokeWidth; + this.lifetime = lifetime === undefined ? DEFAULT_LIFETIME : lifetime; this.points = [ ]; this.strokeWidths = [ @@ -23,11 +26,11 @@ var PolyLine = function(position, color, defaultStrokeWidth) { strokeWidths: this.strokeWidths, dimensions: LINE_DIMENSIONS, color: color, - lifetime: 20 + lifetime: lifetime }); }; -PolyLine.prototype.enqueuePoint = function(position) { +PolyLine.prototype.enqueuePoint = function(position, strokeWidth) { if (this.isFull()) { error("Hit max PolyLine size"); return; @@ -36,7 +39,7 @@ PolyLine.prototype.enqueuePoint = function(position) { position = Vec3.subtract(position, this.position); this.points.push(position); this.normals.push({ x: 1, y: 0, z: 0 }); - this.strokeWidths.push(this.defaultStrokeWidth); + this.strokeWidths.push(strokeWidth); Entities.editEntity(this.entityID, { linePoints: this.points, normals: this.normals, @@ -83,33 +86,33 @@ PolyLine.prototype.destroy = function() { }; - // InfiniteLine -InfiniteLine = function(position, color) { +InfiniteLine = function(position, color, lifetime) { this.position = position; this.color = color; + this.lifetime = lifetime === undefined ? DEFAULT_LIFETIME : lifetime; this.lines = [new PolyLine(position, color, 0.01)]; this.size = 0; }; -InfiniteLine.prototype.enqueuePoint = function(position) { +InfiniteLine.prototype.enqueuePoint = function(position, strokeWidth) { var currentLine; if (this.lines.length == 0) { - currentLine = new PolyLine(position, this.color, 0.01); + currentLine = new PolyLine(position, this.color, this.lifetime); this.lines.push(currentLine); } else { currentLine = this.lines[this.lines.length - 1]; } if (currentLine.isFull()) { - var newLine = new PolyLine(currentLine.getLastPoint(), this.color, 0.01); - newLine.enqueuePoint(currentLine.getLastPoint()); + var newLine = new PolyLine(currentLine.getLastPoint(), this.color, this.lifetime); + newLine.enqueuePoint(currentLine.getLastPoint(), strokeWidth); this.lines.push(newLine); currentLine = newLine; } - currentLine.enqueuePoint(position); + currentLine.enqueuePoint(position, strokeWidth); ++this.size; }; From 2cd2af2b13421341224910654921e9413bccd6f6 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 27 Oct 2015 09:49:52 -0700 Subject: [PATCH 06/44] Add headers to line.js and lineExample.js --- examples/example/lineExample.js | 11 +++++++++++ examples/libraries/line.js | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/examples/example/lineExample.js b/examples/example/lineExample.js index e6c3d90cba..d424d4f9f3 100644 --- a/examples/example/lineExample.js +++ b/examples/example/lineExample.js @@ -1,3 +1,14 @@ +// +// lineExample.js +// examples/example +// +// Created by Ryan Huffman on October 27, 2015 +// Copyright 2015 High Fidelity, Inc. +// +// 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("../libraries/line.js"); var basePosition = MyAvatar.position; diff --git a/examples/libraries/line.js b/examples/libraries/line.js index 77cb13c124..d31a34867b 100644 --- a/examples/libraries/line.js +++ b/examples/libraries/line.js @@ -1,3 +1,14 @@ +// +// line.js +// examples/libraries +// +// Created by Ryan Huffman on October 27, 2015 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + function error(message) { print("[ERROR] " + message); } From 93503d0a216019cff88a2b08441f88539881932f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 30 Oct 2015 11:03:13 -0700 Subject: [PATCH 07/44] make kinematic grab set entities kinematic in bullet and update entity position --- examples/controllers/handControllerGrab.js | 24 ++++++++++++++++------ interface/src/avatar/AvatarActionHold.cpp | 5 +++++ libraries/physics/src/ObjectAction.cpp | 15 +++++++++++++- libraries/physics/src/ObjectMotionState.h | 9 ++++++++ 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index cb445a0960..9ee9ed1e04 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -55,6 +55,7 @@ var NEAR_GRABBING_VELOCITY_SMOOTH_RATIO = 1.0; // adjust time-averaging of held var NEAR_PICK_MAX_DISTANCE = 0.3; // max length of pick-ray for close grabbing to be selected var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things var PICK_BACKOFF_DISTANCE = 0.2; // helps when hand is intersecting the grabble object +var NEAR_GRABBING_KINEMATIC = true; // force objects to be kinematic when near-grabbed ///////////////////////////////////////////////////////////////// // @@ -404,8 +405,9 @@ function MyController(hand, triggerAction) { var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); - var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation", - "gravity", "ignoreForCollisions"]); + var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation", "gravity", + "ignoreForCollisions", + "collisionsWillMove"]); var now = Date.now(); // add the action and initialize some variables @@ -549,8 +551,14 @@ function MyController(hand, triggerAction) { this.lineOff(); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, - ["position", "rotation", "gravity", "ignoreForCollisions"]); + ["position", "rotation", "gravity", + "ignoreForCollisions", "collisionsWillMove"]); this.activateEntity(this.grabbedEntity, grabbedProperties); + if (grabbedProperties.collisionsWillMove && NEAR_GRABBING_KINEMATIC) { + Entities.editEntity(this.grabbedEntity, { + collisionsWillMove: false + }); + } var handRotation = this.getHandRotation(); var handPosition = this.getHandPosition(); @@ -579,7 +587,8 @@ function MyController(hand, triggerAction) { timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, relativeRotation: this.offsetRotation, - ttl: ACTION_TTL + ttl: ACTION_TTL, + kinematic: NEAR_GRABBING_KINEMATIC }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; @@ -631,7 +640,8 @@ function MyController(hand, triggerAction) { timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, relativeRotation: this.offsetRotation, - ttl: ACTION_TTL + ttl: ACTION_TTL, + kinematic: NEAR_GRABBING_KINEMATIC }); this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); } @@ -828,6 +838,7 @@ function MyController(hand, triggerAction) { if (data["refCount"] == 1) { data["gravity"] = grabbedProperties.gravity; data["ignoreForCollisions"] = grabbedProperties.ignoreForCollisions; + data["collisionsWillMove"] = grabbedProperties.collisionsWillMove; var whileHeldProperties = {gravity: {x:0, y:0, z:0}}; if (invertSolidWhileHeld) { whileHeldProperties["ignoreForCollisions"] = ! grabbedProperties.ignoreForCollisions; @@ -845,7 +856,8 @@ function MyController(hand, triggerAction) { if (data["refCount"] < 1) { Entities.editEntity(entityID, { gravity: data["gravity"], - ignoreForCollisions: data["ignoreForCollisions"] + ignoreForCollisions: data["ignoreForCollisions"], + collisionsWillMove: data["collisionsWillMove"] }); data = null; } diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 238e48d2fd..59bfd88be6 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -119,6 +119,9 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) { worldTrans.setRotation(glmToBullet(_rotationalTarget)); rigidBody->setWorldTransform(worldTrans); + ownerEntity->setPosition(_positionalTarget); + ownerEntity->setRotation(_rotationalTarget); + _previousPositionalTarget = _positionalTarget; _previousRotationalTarget = _rotationalTarget; _previousSet = true; @@ -224,6 +227,8 @@ QVariantMap AvatarActionHold::getArguments() { arguments["relativeRotation"] = glmToQMap(_relativeRotation); arguments["timeScale"] = _linearTimeScale; arguments["hand"] = _hand; + arguments["kinematic"] = _kinematic; + arguments["kinematicSetVelocity"] = _kinematicSetVelocity; }); return arguments; } diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index ff8382a143..d44ebc30b1 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -35,7 +35,9 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta if (ownerEntityExpired) { qDebug() << "warning -- action with no entity removing self from btCollisionWorld."; btDynamicsWorld* dynamicsWorld = static_cast(collisionWorld); - dynamicsWorld->removeAction(this); + if (dynamicsWorld) { + dynamicsWorld->removeAction(this); + } return; } @@ -120,6 +122,17 @@ QVariantMap ObjectAction::getArguments() { arguments["ttl"] = (float)(_expires - now) / (float)USECS_PER_SECOND; } arguments["tag"] = _tag; + + EntityItemPointer entity = _ownerEntity.lock(); + if (entity) { + ObjectMotionState* motionState = static_cast(entity->getPhysicsInfo()); + if (motionState) { + arguments["::active"] = motionState->isActive(); + arguments["::motion-type"] = motionTypeToString(motionState->getMotionType()); + } else { + arguments["::no-motion-state"] = true; + } + } }); return arguments; } diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 450ac34a90..22f0e9dcb0 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -29,6 +29,15 @@ enum MotionType { MOTION_TYPE_KINEMATIC // keyframed motion }; +inline QString motionTypeToString(MotionType motionType) { + switch(motionType) { + case MOTION_TYPE_STATIC: return QString("static"); + case MOTION_TYPE_DYNAMIC: return QString("dynamic"); + case MOTION_TYPE_KINEMATIC: return QString("kinematic"); + } + return QString("unknown"); +} + enum MotionStateType { MOTIONSTATE_TYPE_INVALID, MOTIONSTATE_TYPE_ENTITY, From b102081f2f1dd0a0bc63c9f7d9c9972c7cb2eb38 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 30 Oct 2015 11:35:51 -0700 Subject: [PATCH 08/44] upon release, set velocity after returning entity to being dynamic --- examples/controllers/handControllerGrab.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 9ee9ed1e04..353e7b3daa 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -588,7 +588,8 @@ function MyController(hand, triggerAction) { relativePosition: this.offsetPosition, relativeRotation: this.offsetRotation, ttl: ACTION_TTL, - kinematic: NEAR_GRABBING_KINEMATIC + kinematic: NEAR_GRABBING_KINEMATIC, + kinematicSetVelocity: true }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; @@ -641,7 +642,8 @@ function MyController(hand, triggerAction) { relativePosition: this.offsetPosition, relativeRotation: this.offsetRotation, ttl: ACTION_TTL, - kinematic: NEAR_GRABBING_KINEMATIC + kinematic: NEAR_GRABBING_KINEMATIC, + kinematicSetVelocity: true }); this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); } @@ -810,12 +812,13 @@ function MyController(hand, triggerAction) { Entities.callEntityMethod(this.grabbedEntity, "releaseGrab"); } + this.deactivateEntity(this.grabbedEntity); + // the action will tend to quickly bring an object's velocity to zero. now that // the action is gone, set the objects velocity to something the holder might expect. Entities.editEntity(this.grabbedEntity, { velocity: this.grabbedVelocity }); - this.deactivateEntity(this.grabbedEntity); this.grabbedVelocity = ZERO_VEC; this.grabbedEntity = null; From f652e983a979daa9d4007f3e0ff2836563fa9779 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 30 Oct 2015 14:53:29 -0700 Subject: [PATCH 09/44] flag kinematic objs when changed in stepSimulation() --- interface/src/avatar/AvatarActionHold.cpp | 3 +- libraries/physics/src/ObjectAction.cpp | 1 - libraries/physics/src/ObjectAction.h | 10 ++--- libraries/physics/src/ObjectMotionState.cpp | 10 ++--- libraries/physics/src/ObjectMotionState.h | 16 ++++--- .../physics/src/ThreadSafeDynamicsWorld.cpp | 43 +++++++++++++++---- .../physics/src/ThreadSafeDynamicsWorld.h | 9 ++-- 7 files changed, 62 insertions(+), 30 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 59bfd88be6..e7d030e17a 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -119,8 +119,7 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) { worldTrans.setRotation(glmToBullet(_rotationalTarget)); rigidBody->setWorldTransform(worldTrans); - ownerEntity->setPosition(_positionalTarget); - ownerEntity->setRotation(_rotationalTarget); + motionState->dirtyInternalKinematicChanges(); _previousPositionalTarget = _positionalTarget; _previousRotationalTarget = _rotationalTarget; diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index d44ebc30b1..3188283f68 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -16,7 +16,6 @@ ObjectAction::ObjectAction(EntityActionType type, const QUuid& id, EntityItemPointer ownerEntity) : btActionInterface(), EntityActionInterface(type, id), - _active(false), _ownerEntity(ownerEntity) { } diff --git a/libraries/physics/src/ObjectAction.h b/libraries/physics/src/ObjectAction.h index fca446aec4..45b40a9fb3 100644 --- a/libraries/physics/src/ObjectAction.h +++ b/libraries/physics/src/ObjectAction.h @@ -50,6 +50,8 @@ public: virtual quint64 getExpires() { return _expires; } protected: + quint64 localTimeToServerTime(quint64 timeValue) const; + quint64 serverTimeToLocalTime(quint64 timeValue) const; virtual btRigidBody* getRigidBody(); virtual glm::vec3 getPosition(); @@ -62,14 +64,10 @@ protected: virtual void setAngularVelocity(glm::vec3 angularVelocity); virtual void activateBody(); - bool _active; EntityItemWeakPointer _ownerEntity; - - quint64 _expires; // in seconds since epoch QString _tag; - - quint64 localTimeToServerTime(quint64 timeValue) const; - quint64 serverTimeToLocalTime(quint64 timeValue) const; + quint64 _expires { 0 }; // in seconds since epoch + bool _active { false }; private: int getEntityServerClockSkew() const; diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 4f3d0396c6..be0edafff5 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -20,17 +20,17 @@ // origin of physics simulation in world-frame glm::vec3 _worldOffset(0.0f); -// static +// static void ObjectMotionState::setWorldOffset(const glm::vec3& offset) { _worldOffset = offset; } -// static +// static const glm::vec3& ObjectMotionState::getWorldOffset() { return _worldOffset; } -// static +// static uint32_t worldSimulationStep = 0; void ObjectMotionState::setWorldSimulationStep(uint32_t step) { assert(step > worldSimulationStep); @@ -41,7 +41,7 @@ uint32_t ObjectMotionState::getWorldSimulationStep() { return worldSimulationStep; } -// static +// static ShapeManager* shapeManager = nullptr; void ObjectMotionState::setShapeManager(ShapeManager* manager) { assert(manager); @@ -85,7 +85,7 @@ glm::vec3 ObjectMotionState::getBodyLinearVelocity() const { glm::vec3 ObjectMotionState::getBodyLinearVelocityGTSigma() const { // NOTE: the threshold to use here relates to the linear displacement threshold (dX) for sending updates - // to objects that are tracked server-side (e.g. entities which use dX = 2mm). Hence an object moving + // to objects that are tracked server-side (e.g. entities which use dX = 2mm). Hence an object moving // just under this velocity threshold would trigger an update about V/dX times per second. const float MIN_LINEAR_SPEED_SQUARED = 0.0036f; // 6 mm/sec diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 22f0e9dcb0..992bdd11d7 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -44,12 +44,12 @@ enum MotionStateType { MOTIONSTATE_TYPE_AVATAR }; -// The update flags trigger two varieties of updates: "hard" which require the body to be pulled +// The update flags trigger two varieties of updates: "hard" which require the body to be pulled // and re-added to the physics engine and "easy" which just updates the body properties. -const uint32_t HARD_DIRTY_PHYSICS_FLAGS = (uint32_t)(Simulation::DIRTY_MOTION_TYPE | Simulation::DIRTY_SHAPE | +const uint32_t HARD_DIRTY_PHYSICS_FLAGS = (uint32_t)(Simulation::DIRTY_MOTION_TYPE | Simulation::DIRTY_SHAPE | Simulation::DIRTY_COLLISION_GROUP); const uint32_t EASY_DIRTY_PHYSICS_FLAGS = (uint32_t)(Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES | - Simulation::DIRTY_MASS | Simulation::DIRTY_MATERIAL | + Simulation::DIRTY_MASS | Simulation::DIRTY_MATERIAL | Simulation::DIRTY_SIMULATOR_ID | Simulation::DIRTY_SIMULATOR_OWNERSHIP); // These are the set of incoming flags that the PhysicsEngine needs to hear about: @@ -66,7 +66,7 @@ class PhysicsEngine; class ObjectMotionState : public btMotionState { public: // These poroperties of the PhysicsEngine are "global" within the context of all ObjectMotionStates - // (assuming just one PhysicsEngine). They are cached as statics for fast calculations in the + // (assuming just one PhysicsEngine). They are cached as statics for fast calculations in the // ObjectMotionState context. static void setWorldOffset(const glm::vec3& offset); static const glm::vec3& getWorldOffset(); @@ -121,7 +121,7 @@ public: virtual float getObjectFriction() const = 0; virtual float getObjectLinearDamping() const = 0; virtual float getObjectAngularDamping() const = 0; - + virtual glm::vec3 getObjectPosition() const = 0; virtual glm::quat getObjectRotation() const = 0; virtual glm::vec3 getObjectLinearVelocity() const = 0; @@ -140,6 +140,11 @@ public: bool isActive() const { return _body ? _body->isActive() : false; } + bool hasInternalKinematicChanges() const { return _hasInternalKinematicChanges; } + + void dirtyInternalKinematicChanges() { _hasInternalKinematicChanges = true; } + void clearInternalKinematicChanges() { _hasInternalKinematicChanges = false; } + friend class PhysicsEngine; protected: @@ -160,6 +165,7 @@ protected: float _mass; uint32_t _lastKinematicStep; + bool _hasInternalKinematicChanges { false }; }; typedef QSet SetOfMotionStates; diff --git a/libraries/physics/src/ThreadSafeDynamicsWorld.cpp b/libraries/physics/src/ThreadSafeDynamicsWorld.cpp index 94d6315705..c7dddb95c4 100644 --- a/libraries/physics/src/ThreadSafeDynamicsWorld.cpp +++ b/libraries/physics/src/ThreadSafeDynamicsWorld.cpp @@ -4,8 +4,8 @@ * * 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 but is not required. @@ -75,7 +75,7 @@ int ThreadSafeDynamicsWorld::stepSimulationWithSubstepCallback(btScalar timeStep } } - // NOTE: We do NOT call synchronizeMotionState() after each substep (to avoid multiple locks on the + // NOTE: We do NOT call synchronizeMotionStates() after each substep (to avoid multiple locks on the // object data outside of the physics engine). A consequence of this is that the transforms of the // external objects only ever update at the end of the full step. @@ -87,6 +87,33 @@ int ThreadSafeDynamicsWorld::stepSimulationWithSubstepCallback(btScalar timeStep return subSteps; } +// call this instead of non-virtual btDiscreteDynamicsWorld::synchronizeSingleMotionState() +void ThreadSafeDynamicsWorld::synchronizeMotionState(btRigidBody* body) { + btAssert(body); + if (body->getMotionState() && !body->isStaticObject()) { + //we need to call the update at least once, even for sleeping objects + //otherwise the 'graphics' transform never updates properly + ///@todo: add 'dirty' flag + //if (body->getActivationState() != ISLAND_SLEEPING) + { + if (body->isKinematicObject()) { + ObjectMotionState* objectMotionState = static_cast(body->getMotionState()); + if (!objectMotionState->hasInternalKinematicChanges()) { + return; + } else { + objectMotionState->clearInternalKinematicChanges(); + } + } + btTransform interpolatedTransform; + btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(), + body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(), + (m_latencyMotionStateInterpolation && m_fixedTimeStep) ? m_localTime - m_fixedTimeStep : m_localTime*body->getHitFraction(), + interpolatedTransform); + body->getMotionState()->setWorldTransform(interpolatedTransform); + } + } +} + void ThreadSafeDynamicsWorld::synchronizeMotionStates() { _changedMotionStates.clear(); BT_PROFILE("synchronizeMotionStates"); @@ -97,22 +124,22 @@ void ThreadSafeDynamicsWorld::synchronizeMotionStates() { btRigidBody* body = btRigidBody::upcast(colObj); if (body) { if (body->getMotionState()) { - synchronizeSingleMotionState(body); + synchronizeMotionState(body); _changedMotionStates.push_back(static_cast(body->getMotionState())); } } } - } else { + } else { //iterate over all active rigid bodies for (int i=0;iisActive()) { if (body->getMotionState()) { - synchronizeSingleMotionState(body); + synchronizeMotionState(body); _changedMotionStates.push_back(static_cast(body->getMotionState())); } } } - } -} + } +} diff --git a/libraries/physics/src/ThreadSafeDynamicsWorld.h b/libraries/physics/src/ThreadSafeDynamicsWorld.h index 26954832cf..de37554f56 100644 --- a/libraries/physics/src/ThreadSafeDynamicsWorld.h +++ b/libraries/physics/src/ThreadSafeDynamicsWorld.h @@ -4,8 +4,8 @@ * * 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 but is not required. @@ -43,13 +43,16 @@ public: void synchronizeMotionStates(); // btDiscreteDynamicsWorld::m_localTime is the portion of real-time that has not yet been simulated - // but is used for MotionState::setWorldTransform() extrapolation (a feature that Bullet uses to provide + // but is used for MotionState::setWorldTransform() extrapolation (a feature that Bullet uses to provide // smoother rendering of objects when the physics simulation loop is ansynchronous to the render loop). float getLocalTimeAccumulation() const { return m_localTime; } VectorOfMotionStates& getChangedMotionStates() { return _changedMotionStates; } private: + // call this instead of non-virtual btDiscreteDynamicsWorld::synchronizeSingleMotionState() + void synchronizeMotionState(btRigidBody* body); + VectorOfMotionStates _changedMotionStates; }; From cf83ca22bbaa77a195268e49ff720096f61d5a15 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 30 Oct 2015 15:30:54 -0700 Subject: [PATCH 10/44] change how kinematic objects get data back to entity when an action is active --- examples/controllers/handControllerGrab.js | 64 ++++++++++++++----- libraries/physics/src/EntityMotionState.cpp | 3 +- .../physics/src/ThreadSafeDynamicsWorld.cpp | 2 + 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 353e7b3daa..10775a483f 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -80,6 +80,18 @@ var ACTION_TTL_REFRESH = 5; var PICKS_PER_SECOND_PER_HAND = 5; var MSECS_PER_SEC = 1000.0; + +var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with grab.js +var GRAB_USER_DATA_KEY = "grabKey"; // shared with grab.js + +var DEFAULT_GRABBABLE_DATA = { + grabbable: true, + invertSolidWhileHeld: false +}; + +var disabledHand ='none'; + + // states for the state machine var STATE_OFF = 0; var STATE_SEARCHING = 1; @@ -93,15 +105,35 @@ var STATE_FAR_GRABBING_NON_COLLIDING = 8; var STATE_CONTINUE_FAR_GRABBING_NON_COLLIDING = 9; var STATE_RELEASE = 10; -var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with grab.js -var GRAB_USER_DATA_KEY = "grabKey"; // shared with grab.js -var DEFAULT_GRABBABLE_DATA = { - grabbable: true, - invertSolidWhileHeld: false -}; +function stateToName(state) { + switch (state) { + case STATE_OFF: + return "off"; + case STATE_SEARCHING: + return "searching"; + case STATE_DISTANCE_HOLDING: + return "distance_holding"; + case STATE_CONTINUE_DISTANCE_HOLDING: + return "continue_distance_holding"; + case STATE_NEAR_GRABBING: + return "near_grabbing"; + case STATE_CONTINUE_NEAR_GRABBING: + return "continue_near_grabbing"; + case STATE_NEAR_GRABBING_NON_COLLIDING: + return "near_grabbing_non_colliding"; + case STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING: + return "continue_near_grabbing_non_colliding"; + case STATE_FAR_GRABBING_NON_COLLIDING: + return "far_grabbing_non_colliding"; + case STATE_CONTINUE_FAR_GRABBING_NON_COLLIDING: + return "continue_far_grabbing_non_colliding"; + case STATE_RELEASE: + return "release"; + } -var disabledHand ='none'; + return "unknown"; +} function getTag() { return "grab-" + MyAvatar.sessionUUID; @@ -196,7 +228,7 @@ function MyController(hand, triggerAction) { this.setState = function(newState) { if (WANT_DEBUG) { - print("STATE: " + this.state + " --> " + newState); + print("STATE: " + stateToName(this.state) + " --> " + newState + ", hand: " + this.hand); } this.state = newState; } @@ -348,10 +380,11 @@ function MyController(hand, triggerAction) { } if (intersectionDistance <= NEAR_PICK_MAX_DISTANCE) { // the hand is very close to the intersected object. go into close-grabbing mode. - if (intersection.properties.collisionsWillMove === 1) { - this.setState(STATE_NEAR_GRABBING); - } else { + var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA); + if (grabbableData.wantsTrigger) { this.setState(STATE_NEAR_GRABBING_NON_COLLIDING); + } else { + this.setState(STATE_NEAR_GRABBING); } } else { // don't allow two people to distance grab the same object @@ -392,11 +425,11 @@ function MyController(hand, triggerAction) { } if (this.grabbedEntity === null) { return; - } else if (props.locked === 0 && props.collisionsWillMove === 1) { - this.setState(STATE_NEAR_GRABBING); - } else if (props.collisionsWillMove === 0 && grabbableData.wantsTrigger) { - // We have grabbed a non-physical object, so we want to trigger a non-colliding event as opposed to a grab event + } + if (grabbableData.wantsTrigger) { this.setState(STATE_NEAR_GRABBING_NON_COLLIDING); + } else if (props.locked === 0) { + this.setState(STATE_NEAR_GRABBING); } } }; @@ -816,6 +849,7 @@ function MyController(hand, triggerAction) { // the action will tend to quickly bring an object's velocity to zero. now that // the action is gone, set the objects velocity to something the holder might expect. + print("release velocity is " + vec3toStr(this.grabbedVelocity)); Entities.editEntity(this.grabbedEntity, { velocity: this.grabbedVelocity }); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 6832b8daff..42aaea33c2 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -146,7 +146,7 @@ MotionType EntityMotionState::computeObjectMotionType() const { if (_entity->getCollisionsWillMove()) { return MOTION_TYPE_DYNAMIC; } - return _entity->isMoving() ? MOTION_TYPE_KINEMATIC : MOTION_TYPE_STATIC; + return (_entity->isMoving() || _entity->hasActions()) ? MOTION_TYPE_KINEMATIC : MOTION_TYPE_STATIC; } bool EntityMotionState::isMoving() const { @@ -184,6 +184,7 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { if (!_entity) { return; } + assert(entityTreeIsLocked()); measureBodyAcceleration(); _entity->setPosition(bulletToGLM(worldTrans.getOrigin()) + ObjectMotionState::getWorldOffset()); diff --git a/libraries/physics/src/ThreadSafeDynamicsWorld.cpp b/libraries/physics/src/ThreadSafeDynamicsWorld.cpp index c7dddb95c4..f725315330 100644 --- a/libraries/physics/src/ThreadSafeDynamicsWorld.cpp +++ b/libraries/physics/src/ThreadSafeDynamicsWorld.cpp @@ -102,6 +102,8 @@ void ThreadSafeDynamicsWorld::synchronizeMotionState(btRigidBody* body) { return; } else { objectMotionState->clearInternalKinematicChanges(); + body->getMotionState()->setWorldTransform(body->getWorldTransform()); + return; } } btTransform interpolatedTransform; From 77e0023b43ddcfe6db2fd7b9852cba2b0977cdd2 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 30 Oct 2015 16:31:15 -0700 Subject: [PATCH 11/44] Fix lifetime bug with first PolyLine in InfiniteLine --- examples/libraries/line.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/libraries/line.js b/examples/libraries/line.js index d31a34867b..c21bf2f3ad 100644 --- a/examples/libraries/line.js +++ b/examples/libraries/line.js @@ -102,7 +102,7 @@ InfiniteLine = function(position, color, lifetime) { this.position = position; this.color = color; this.lifetime = lifetime === undefined ? DEFAULT_LIFETIME : lifetime; - this.lines = [new PolyLine(position, color, 0.01)]; + this.lines = []; this.size = 0; }; From 944f0965c059a1d9af6a30d8c18523d59c836cff Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 30 Oct 2015 16:35:50 -0700 Subject: [PATCH 12/44] some refactoring and a bug fix -- grab script can throw things again --- examples/controllers/handControllerGrab.js | 8 +------- libraries/physics/src/PhysicsEngine.cpp | 9 ++++++--- libraries/physics/src/ThreadSafeDynamicsWorld.cpp | 6 ++---- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 10775a483f..815f903bfa 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -15,13 +15,11 @@ Script.include("../libraries/utils.js"); -//////////////////////////////////////////////////////////// // // add lines where the hand ray picking is happening // var WANT_DEBUG = false; -///////////////////////////////////////////////////////////////// // // these tune time-averaging and "on" value for analog trigger // @@ -30,7 +28,6 @@ var TRIGGER_SMOOTH_RATIO = 0.1; // 0.0 disables smoothing of trigger value var TRIGGER_ON_VALUE = 0.4; var TRIGGER_OFF_VALUE = 0.15; -///////////////////////////////////////////////////////////////// // // distant manipulation // @@ -44,7 +41,6 @@ var LINE_ENTITY_DIMENSIONS = { x: 1000, y: 1000,z: 1000}; var LINE_LENGTH = 500; var PICK_MAX_DISTANCE = 500; // max length of pick-ray -///////////////////////////////////////////////////////////////// // // near grabbing // @@ -57,7 +53,6 @@ var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things var PICK_BACKOFF_DISTANCE = 0.2; // helps when hand is intersecting the grabble object var NEAR_GRABBING_KINEMATIC = true; // force objects to be kinematic when near-grabbed -///////////////////////////////////////////////////////////////// // // other constants // @@ -228,7 +223,7 @@ function MyController(hand, triggerAction) { this.setState = function(newState) { if (WANT_DEBUG) { - print("STATE: " + stateToName(this.state) + " --> " + newState + ", hand: " + this.hand); + print("STATE: " + stateToName(this.state) + " --> " + stateToName(newState) + ", hand: " + this.hand); } this.state = newState; } @@ -849,7 +844,6 @@ function MyController(hand, triggerAction) { // the action will tend to quickly bring an object's velocity to zero. now that // the action is gone, set the objects velocity to something the holder might expect. - print("release velocity is " + vec3toStr(this.grabbedVelocity)); Entities.editEntity(this.grabbedEntity, { velocity: this.grabbedVelocity }); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 1e652b75c4..f3ef855e50 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -82,12 +82,12 @@ void PhysicsEngine::addObject(ObjectMotionState* motionState) { btCollisionShape* shape = motionState->getShape(); assert(shape); body = new btRigidBody(mass, motionState, shape, inertia); + motionState->setRigidBody(body); } else { body->setMassProps(mass, inertia); } body->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT); body->updateInertiaTensor(); - motionState->setRigidBody(body); motionState->updateBodyVelocities(); const float KINEMATIC_LINEAR_VELOCITY_THRESHOLD = 0.01f; // 1 cm/sec const float KINEMATIC_ANGULAR_VELOCITY_THRESHOLD = 0.01f; // ~1 deg/sec @@ -101,12 +101,15 @@ void PhysicsEngine::addObject(ObjectMotionState* motionState) { shape->calculateLocalInertia(mass, inertia); if (!body) { body = new btRigidBody(mass, motionState, shape, inertia); + motionState->setRigidBody(body); } else { body->setMassProps(mass, inertia); } + body->setCollisionFlags(body->getCollisionFlags() & ~(btCollisionObject::CF_KINEMATIC_OBJECT | + btCollisionObject::CF_STATIC_OBJECT)); body->updateInertiaTensor(); - motionState->setRigidBody(body); motionState->updateBodyVelocities(); + // NOTE: Bullet will deactivate any object whose velocity is below these thresholds for longer than 2 seconds. // (the 2 seconds is determined by: static btRigidBody::gDeactivationTime const float DYNAMIC_LINEAR_VELOCITY_THRESHOLD = 0.05f; // 5 cm/sec @@ -123,12 +126,12 @@ void PhysicsEngine::addObject(ObjectMotionState* motionState) { if (!body) { assert(motionState->getShape()); body = new btRigidBody(mass, motionState, motionState->getShape(), inertia); + motionState->setRigidBody(body); } else { body->setMassProps(mass, inertia); } body->setCollisionFlags(btCollisionObject::CF_STATIC_OBJECT); body->updateInertiaTensor(); - motionState->setRigidBody(body); break; } } diff --git a/libraries/physics/src/ThreadSafeDynamicsWorld.cpp b/libraries/physics/src/ThreadSafeDynamicsWorld.cpp index f725315330..d06a9b8e07 100644 --- a/libraries/physics/src/ThreadSafeDynamicsWorld.cpp +++ b/libraries/physics/src/ThreadSafeDynamicsWorld.cpp @@ -98,13 +98,11 @@ void ThreadSafeDynamicsWorld::synchronizeMotionState(btRigidBody* body) { { if (body->isKinematicObject()) { ObjectMotionState* objectMotionState = static_cast(body->getMotionState()); - if (!objectMotionState->hasInternalKinematicChanges()) { - return; - } else { + if (objectMotionState->hasInternalKinematicChanges()) { objectMotionState->clearInternalKinematicChanges(); body->getMotionState()->setWorldTransform(body->getWorldTransform()); - return; } + return; } btTransform interpolatedTransform; btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(), From f50e1a0977f92d28c5e117f80a2e7723e6acd8ae Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 30 Oct 2015 17:18:37 -0700 Subject: [PATCH 13/44] Fix for rare crash in LogHandler::flushRepeatedMessages() This can happen when LogHandler::flushRepetedMessages is called on the main thread, while the application is printing messages on a separate thread. The access to the _lastRepeatedMessage QHash was not guarded. I've added two mutexes to guard access to both the repeatedMessage hashes/regexes and the onlyOnceMessages/regexes. This will unfortunately incur a performance hit for frequent debug logging, but that's better then crashing. Also, I've added the ability to print threadIDs as well as Process ids. This is helpful when debugging multi-threaded access to shared variables. --- assignment-client/src/AssignmentClient.cpp | 2 +- .../src/AssignmentClientMonitor.cpp | 2 +- libraries/shared/src/LogHandler.cpp | 66 ++++++++++++------- libraries/shared/src/LogHandler.h | 26 ++++---- 4 files changed, 60 insertions(+), 36 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index f4f98114d0..bf5f9c3b7f 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -74,7 +74,7 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); // make sure we output process IDs for a child AC otherwise it's insane to parse - LogHandler::getInstance().setShouldOutputPID(true); + LogHandler::getInstance().setShouldOutputProcessID(true); // setup our _requestAssignment member variable from the passed arguments _requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, assignmentPool); diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 58cf3c49f3..7b3d5695e1 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -44,7 +44,7 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME); // make sure we output process IDs for a monitor otherwise it's insane to parse - LogHandler::getInstance().setShouldOutputPID(true); + LogHandler::getInstance().setShouldOutputProcessID(true); // create a NodeList so we can receive stats from children DependencyManager::registerInheritance(); diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index cc3519e43e..0e05df277b 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -12,9 +12,10 @@ #include -#include -#include -#include +#include +#include +#include +#include #include "LogHandler.h" @@ -24,13 +25,14 @@ LogHandler& LogHandler::getInstance() { } LogHandler::LogHandler() : - _shouldOutputPID(false) + _shouldOutputProcessID(false), + _shouldOutputThreadID(false) { // setup our timer to flush the verbose logs every 5 seconds QTimer* logFlushTimer = new QTimer(this); connect(logFlushTimer, &QTimer::timeout, this, &LogHandler::flushRepeatedMessages); logFlushTimer->start(VERBOSE_LOG_INTERVAL_SECONDS * 1000); - + // when the log handler is first setup we should print our timezone QString timezoneString = "Time zone: " + QDateTime::currentDateTime().toString("t"); printf("%s\n", qPrintable(timezoneString)); @@ -57,51 +59,55 @@ const char* stringForLogType(LogMsgType msgType) { const QString DATE_STRING_FORMAT = "MM/dd hh:mm:ss"; void LogHandler::flushRepeatedMessages() { + QMutexLocker locker(&_repeatedMessageLock); QHash::iterator message = _repeatMessageCountHash.begin(); while (message != _repeatMessageCountHash.end()) { - + if (message.value() > 0) { QString repeatMessage = QString("%1 repeated log entries matching \"%2\" - Last entry: \"%3\"") .arg(message.value()).arg(message.key()).arg(_lastRepeatedMessage.value(message.key())); - + QMessageLogContext emptyContext; printMessage(LogSuppressed, emptyContext, repeatMessage); } - + _lastRepeatedMessage.remove(message.key()); message = _repeatMessageCountHash.erase(message); } } QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& context, const QString& message) { - + if (message.isEmpty()) { return QString(); } - + if (type == LogDebug) { // for debug messages, check if this matches any of our regexes for repeated log messages + QMutexLocker locker(&_repeatedMessageLock); foreach(const QString& regexString, getInstance()._repeatedMessageRegexes) { QRegExp repeatRegex(regexString); if (repeatRegex.indexIn(message) != -1) { - + if (!_repeatMessageCountHash.contains(regexString)) { // we have a match but didn't have this yet - output the first one _repeatMessageCountHash[regexString] = 0; - + // break the foreach so we output the first match break; } else { // we have a match - add 1 to the count of repeats for this message and set this as the last repeated message _repeatMessageCountHash[regexString] += 1; _lastRepeatedMessage[regexString] = message; - + // return out, we're not printing this one return QString(); } } } - + } + if (type == LogDebug) { + QMutexLocker locker(&_onlyOnceMessageLock); // see if this message is one we should only print once foreach(const QString& regexString, getInstance()._onlyOnceMessageRegexes) { QRegExp onlyOnceRegex(regexString); @@ -118,23 +124,27 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont } } } - + // log prefix is in the following format - // [TIMESTAMP] [DEBUG] [PID] [TARGET] logged string - + // [TIMESTAMP] [DEBUG] [PID] [TID] [TARGET] logged string + QString prefixString = QString("[%1]").arg(QDateTime::currentDateTime().toString(DATE_STRING_FORMAT)); - + prefixString.append(QString(" [%1]").arg(stringForLogType(type))); - - if (_shouldOutputPID) { + + if (_shouldOutputProcessID) { prefixString.append(QString(" [%1]").arg(QCoreApplication::instance()->applicationPid())); - } - + + if (_shouldOutputThreadID) { + size_t threadID = (size_t)QThread::currentThreadId(); + prefixString.append(QString(" [%1]").arg(threadID)); + } + if (!_targetName.isEmpty()) { prefixString.append(QString(" [%1]").arg(_targetName)); } - + QString logMessage = QString("%1 %2").arg(prefixString, message.split("\n").join("\n" + prefixString + " ")); fprintf(stdout, "%s\n", qPrintable(logMessage)); return logMessage; @@ -143,3 +153,13 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont void LogHandler::verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { getInstance().printMessage((LogMsgType) type, context, message); } + +const QString& LogHandler::addRepeatedMessageRegex(const QString& regexString) { + QMutexLocker locker(&_repeatedMessageLock); + return *_repeatedMessageRegexes.insert(regexString); +} + +const QString& LogHandler::addOnlyOnceMessageRegex(const QString& regexString) { + QMutexLocker locker(&_onlyOnceMessageLock); + return *_onlyOnceMessageRegexes.insert(regexString); +} diff --git a/libraries/shared/src/LogHandler.h b/libraries/shared/src/LogHandler.h index 6af721f96c..fff6ca43d6 100644 --- a/libraries/shared/src/LogHandler.h +++ b/libraries/shared/src/LogHandler.h @@ -34,34 +34,38 @@ class LogHandler : public QObject { Q_OBJECT public: static LogHandler& getInstance(); - + /// sets the target name to output via the verboseMessageHandler, called once before logging begins /// \param targetName the desired target name to output in logs void setTargetName(const QString& targetName) { _targetName = targetName; } - - void setShouldOutputPID(bool shouldOutputPID) { _shouldOutputPID = shouldOutputPID; } - + + void setShouldOutputProcessID(bool shouldOutputProcessID) { _shouldOutputProcessID = shouldOutputProcessID; } + void setShouldOutputThreadID(bool shouldOutputThreadID) { _shouldOutputThreadID = shouldOutputThreadID; } + QString printMessage(LogMsgType type, const QMessageLogContext& context, const QString &message); - + /// a qtMessageHandler that can be hooked up to a target that links to Qt /// prints various process, message type, and time information static void verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message); - - const QString& addRepeatedMessageRegex(const QString& regexString) { return *_repeatedMessageRegexes.insert(regexString); } - const QString& addOnlyOnceMessageRegex(const QString& regexString) { return *_onlyOnceMessageRegexes.insert(regexString); } + + const QString& addRepeatedMessageRegex(const QString& regexString); + const QString& addOnlyOnceMessageRegex(const QString& regexString); private: LogHandler(); - + void flushRepeatedMessages(); - + QString _targetName; - bool _shouldOutputPID; + bool _shouldOutputProcessID; + bool _shouldOutputThreadID; QSet _repeatedMessageRegexes; QHash _repeatMessageCountHash; QHash _lastRepeatedMessage; + QMutex _repeatedMessageLock; QSet _onlyOnceMessageRegexes; QHash _onlyOnceMessageCountHash; + QMutex _onlyOnceMessageLock; }; #endif // hifi_LogHandler_h From 2eb62f2fd89fb9c49107a72bdab9106dc00a8efa Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 30 Oct 2015 17:44:06 -0700 Subject: [PATCH 14/44] LogHandler: fix for linux build --- libraries/shared/src/LogHandler.cpp | 2 ++ libraries/shared/src/LogHandler.h | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index 0e05df277b..7dd1aceb3d 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include "LogHandler.h" diff --git a/libraries/shared/src/LogHandler.h b/libraries/shared/src/LogHandler.h index fff6ca43d6..a74a6287d7 100644 --- a/libraries/shared/src/LogHandler.h +++ b/libraries/shared/src/LogHandler.h @@ -13,11 +13,11 @@ #ifndef hifi_LogHandler_h #define hifi_LogHandler_h -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include const int VERBOSE_LOG_INTERVAL_SECONDS = 5; From 46d87dda5a8d4f77e74718da6e43cd635a153903 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Fri, 30 Oct 2015 19:00:01 -0700 Subject: [PATCH 15/44] Fixing paths for SDL2 and Sixense libs --- cmake/externals/sdl2/CMakeLists.txt | 42 ++++++++++++++++++-------- cmake/externals/sixense/CMakeLists.txt | 12 ++++++++ libraries/entities/CMakeLists.txt | 2 +- libraries/procedural/CMakeLists.txt | 2 +- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/cmake/externals/sdl2/CMakeLists.txt b/cmake/externals/sdl2/CMakeLists.txt index 0f44f28610..abd436d571 100644 --- a/cmake/externals/sdl2/CMakeLists.txt +++ b/cmake/externals/sdl2/CMakeLists.txt @@ -2,6 +2,8 @@ set(EXTERNAL_NAME sdl2) include(ExternalProject) +string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) + if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} @@ -13,15 +15,33 @@ if (WIN32) LOG_DOWNLOAD 1 ) elseif (APPLE) - ExternalProject_Add( - ${EXTERNAL_NAME} - URL http://hifi-public.s3.amazonaws.com/dependencies/SDL2-2.0.3-OSX.tar.gz - URL_MD5 64f888886268bdf1656ef1b4b7d7756d - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - LOG_DOWNLOAD 1 - ) + + ExternalProject_Add( + ${EXTERNAL_NAME} + URL https://hifi-public.s3.amazonaws.com/dependencies/SDL2-2.0.3.zip + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= -DVIDEO_OPENGL=OFF + BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 + ) + + ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) + set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIR ${INSTALL_DIR}/include/SDL2 CACHE PATH "Location of SDL2 include directory") + set(${EXTERNAL_NAME_UPPER}_LIBRARY "${INSTALL_DIR}/lib/libSDL2-2.0.dylib" CACHE STRING "Path to SDL2 library") + + set(_SDL2_LIB_DIR "${INSTALL_DIR}/lib") + + ExternalProject_Add_Step( + ${EXTERNAL_NAME} + change-install-name + COMMENT "Calling install_name_tool on SDL2 libraries to fix install name for dylib linking" + COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${_SDL2_LIB_DIR} -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake + DEPENDEES install + WORKING_DIRECTORY + LOG 1 + ) + else () if (ANDROID) set(ANDROID_CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DANDROID_NATIVE_API_LEVEL=19") @@ -41,12 +61,8 @@ endif () # Hide this external target (for ide users) set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") -string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) if (APPLE) - ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) - set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIR ${SOURCE_DIR}/SDL2.framework/Headers CACHE PATH "Location of SDL2 include directory") - set(${EXTERNAL_NAME_UPPER}_LIBRARY_TEMP ${SOURCE_DIR}/SDL2.framework/SDL2 CACHE STRING "Path to SDL2 library") elseif (WIN32) ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIR ${SOURCE_DIR}/include CACHE PATH "Location of SDL2 include directory") diff --git a/cmake/externals/sixense/CMakeLists.txt b/cmake/externals/sixense/CMakeLists.txt index 72de4a7e15..dea15485dc 100644 --- a/cmake/externals/sixense/CMakeLists.txt +++ b/cmake/externals/sixense/CMakeLists.txt @@ -37,6 +37,18 @@ elseif(APPLE) set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/osx_x64/release_dll/libsixense_x64.dylib CACHE TYPE INTERNAL) + set(_SIXENSE_LIB_DIR "${SOURCE_DIR}/lib/osx_x64/release_dll") + + ExternalProject_Add_Step( + ${EXTERNAL_NAME} + change-install-name-release + COMMENT "Calling install_name_tool on libraries to fix install name for dylib linking" + COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${_SIXENSE_LIB_DIR} -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake + DEPENDEES install + WORKING_DIRECTORY + LOG 1 + ) + elseif(NOT ANDROID) # FIXME need to account for different architectures diff --git a/libraries/entities/CMakeLists.txt b/libraries/entities/CMakeLists.txt index f6b2e0e280..26e90f5d41 100644 --- a/libraries/entities/CMakeLists.txt +++ b/libraries/entities/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME entities) setup_hifi_library(Network Script) -link_hifi_libraries(avatars shared octree gpu model fbx networking animation environment) +link_hifi_libraries(avatars shared audio octree gpu model fbx networking animation environment) target_bullet() diff --git a/libraries/procedural/CMakeLists.txt b/libraries/procedural/CMakeLists.txt index 0483b8d3a8..37c4fbfbe8 100644 --- a/libraries/procedural/CMakeLists.txt +++ b/libraries/procedural/CMakeLists.txt @@ -1,5 +1,5 @@ set(TARGET_NAME procedural) AUTOSCRIBE_SHADER_LIB(gpu model) setup_hifi_library() -link_hifi_libraries(shared gpu model model-networking) +link_hifi_libraries(shared gpu networking model model-networking) From 9b9e35d3963e556842c243da6bd8a33f2f9a4a26 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Fri, 30 Oct 2015 22:01:43 -0700 Subject: [PATCH 16/44] Limit sixense to mavericks and below --- cmake/externals/sixense/CMakeLists.txt | 21 ++++++++++++++----- cmake/modules/FindSixense.cmake | 4 ++++ .../src/input-plugins/SixenseManager.cpp | 8 +++++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/cmake/externals/sixense/CMakeLists.txt b/cmake/externals/sixense/CMakeLists.txt index dea15485dc..5edccb2c88 100644 --- a/cmake/externals/sixense/CMakeLists.txt +++ b/cmake/externals/sixense/CMakeLists.txt @@ -35,20 +35,31 @@ if (WIN32) elseif(APPLE) - set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/osx_x64/release_dll/libsixense_x64.dylib CACHE TYPE INTERNAL) - - set(_SIXENSE_LIB_DIR "${SOURCE_DIR}/lib/osx_x64/release_dll") - + set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/lib/osx_x64/release_dll/libsixense_x64.dylib CACHE TYPE INTERNAL) + set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${SOURCE_DIR}/lib/osx_x64/debug_dll/libsixensed_x64.dylib CACHE TYPE INTERNAL) + + set(_SIXENSE_LIB_DIR "${SOURCE_DIR}/lib/osx_x64") ExternalProject_Add_Step( ${EXTERNAL_NAME} change-install-name-release COMMENT "Calling install_name_tool on libraries to fix install name for dylib linking" - COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${_SIXENSE_LIB_DIR} -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake + COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${_SIXENSE_LIB_DIR}/release_dll -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake DEPENDEES install WORKING_DIRECTORY LOG 1 ) + set(_SIXENSE_LIB_DIR "${SOURCE_DIR}/lib/osx_x64") + ExternalProject_Add_Step( + ${EXTERNAL_NAME} + change-install-name-debug + COMMENT "Calling install_name_tool on libraries to fix install name for dylib linking" + COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${_SIXENSE_LIB_DIR}/debug_dll -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake + DEPENDEES install + WORKING_DIRECTORY + LOG 1 + ) + elseif(NOT ANDROID) # FIXME need to account for different architectures diff --git a/cmake/modules/FindSixense.cmake b/cmake/modules/FindSixense.cmake index 9abacac136..5a94d592d4 100644 --- a/cmake/modules/FindSixense.cmake +++ b/cmake/modules/FindSixense.cmake @@ -18,6 +18,10 @@ # See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html # +include(SelectLibraryConfigurations) +select_library_configurations(SIXENSE) + +set(SIXENSE_REQUIREMENTS SIXENSE_INCLUDE_DIRS SIXENSE_LIBRARIES) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Sixense DEFAULT_MSG SIXENSE_INCLUDE_DIRS SIXENSE_LIBRARIES) mark_as_advanced(SIXENSE_LIBRARIES SIXENSE_INCLUDE_DIRS SIXENSE_SEARCH_DIRS) diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp index 2527da9e03..6cb58ced82 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp +++ b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp @@ -12,6 +12,8 @@ #include #include +#include +#include #include #include @@ -74,7 +76,13 @@ SixenseManager::SixenseManager() : bool SixenseManager::isSupported() const { #ifdef HAVE_SIXENSE + +#if defined(Q_OS_OSX) + return QSysInfo::macVersion() <= QSysInfo::MV_MAVERICKS; +#else return true; +#endif + #else return false; #endif From 0355a37fb147d8bc7b4dcc3a28129d4343edd3d8 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Fri, 30 Oct 2015 22:19:44 -0700 Subject: [PATCH 17/44] Fixing SDL2 active/inactive value --- libraries/input-plugins/src/input-plugins/SDL2Manager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/input-plugins/src/input-plugins/SDL2Manager.cpp b/libraries/input-plugins/src/input-plugins/SDL2Manager.cpp index 600dc5c56f..48864beedc 100644 --- a/libraries/input-plugins/src/input-plugins/SDL2Manager.cpp +++ b/libraries/input-plugins/src/input-plugins/SDL2Manager.cpp @@ -82,6 +82,7 @@ void SDL2Manager::activate() { emit joystickAdded(joystick.get()); } #endif + InputPlugin::activate(); } void SDL2Manager::deactivate() { @@ -92,6 +93,7 @@ void SDL2Manager::deactivate() { emit joystickRemoved(joystick.get()); } #endif + InputPlugin::deactivate(); } From aee03e79f390a6b60a474eedb9bcf4ecfd3a5e50 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 30 Oct 2015 22:37:00 -0700 Subject: [PATCH 18/44] Fix win32 and linux Sixense config --- cmake/externals/sixense/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/sixense/CMakeLists.txt b/cmake/externals/sixense/CMakeLists.txt index 5edccb2c88..07cf1c1163 100644 --- a/cmake/externals/sixense/CMakeLists.txt +++ b/cmake/externals/sixense/CMakeLists.txt @@ -30,7 +30,7 @@ if (WIN32) set(ARCH_SUFFIX "") endif() - set(${EXTERNAL_NAME_UPPER}_LIBRARIES "${SOURCE_DIR}/lib/${ARCH_DIR}/VS2013/release_dll/sixense${ARCH_SUFFIX}.lib" CACHE TYPE INTERNAL) + set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE "${SOURCE_DIR}/lib/${ARCH_DIR}/VS2013/release_dll/sixense${ARCH_SUFFIX}.lib" CACHE TYPE INTERNAL) add_paths_to_fixup_libs("${SOURCE_DIR}/bin/${ARCH_DIR}/VS2013/release_dll") elseif(APPLE) @@ -63,7 +63,7 @@ elseif(APPLE) elseif(NOT ANDROID) # FIXME need to account for different architectures - set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/linux_x64/release/libsixense_x64.so CACHE TYPE INTERNAL) + set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/lib/linux_x64/release/libsixense_x64.so CACHE TYPE INTERNAL) endif() From 224aeea04406d56ae901e14d7d1216c34ff592b6 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 31 Oct 2015 08:11:43 -0700 Subject: [PATCH 19/44] quiet compiler --- libraries/animation/src/AnimVariant.cpp | 2 +- libraries/controllers/src/controllers/UserInputMapper.cpp | 4 ++-- libraries/controllers/src/controllers/impl/Endpoint.h | 3 ++- .../src/controllers/impl/conditionals/EndpointConditional.h | 2 +- .../controllers/src/controllers/impl/endpoints/AnyEndpoint.h | 1 + .../src/controllers/impl/endpoints/ArrayEndpoint.h | 1 + .../src/controllers/impl/endpoints/CompositeEndpoint.h | 1 + .../controllers/src/controllers/impl/endpoints/JSEndpoint.h | 1 + .../src/controllers/impl/endpoints/ScriptEndpoint.h | 1 + .../src/controllers/impl/endpoints/StandardEndpoint.h | 2 +- 10 files changed, 12 insertions(+), 6 deletions(-) diff --git a/libraries/animation/src/AnimVariant.cpp b/libraries/animation/src/AnimVariant.cpp index 8d320195dd..234e9cef09 100644 --- a/libraries/animation/src/AnimVariant.cpp +++ b/libraries/animation/src/AnimVariant.cpp @@ -44,7 +44,7 @@ QScriptValue AnimVariantMap::animVariantMapToScriptValue(QScriptEngine* engine, break; default: // Note that we don't do mat4 in Javascript currently, and there's not yet a reason to start now. - assert("AnimVariant::Type" == "valid"); + assert(QString("AnimVariant::Type") == QString("valid")); } }; if (useNames) { // copy only the requested names diff --git a/libraries/controllers/src/controllers/UserInputMapper.cpp b/libraries/controllers/src/controllers/UserInputMapper.cpp index d33e215797..8e121de7fb 100755 --- a/libraries/controllers/src/controllers/UserInputMapper.cpp +++ b/libraries/controllers/src/controllers/UserInputMapper.cpp @@ -74,7 +74,7 @@ void UserInputMapper::registerDevice(InputDevice::Pointer device) { } const auto& deviceID = device->_deviceID; - int numberOfType = recordDeviceOfType(device->getName()); + recordDeviceOfType(device->getName()); qCDebug(controllers) << "Registered input device <" << device->getName() << "> deviceID = " << deviceID; for (const auto& inputMapping : device->getAvailableInputs()) { @@ -266,7 +266,7 @@ void UserInputMapper::update(float deltaTime) { } auto standardInputs = getStandardInputs(); - if (_lastStandardStates.size() != standardInputs.size()) { + if ((int)_lastStandardStates.size() != standardInputs.size()) { _lastStandardStates.resize(standardInputs.size()); for (auto& lastValue : _lastStandardStates) { lastValue = 0; diff --git a/libraries/controllers/src/controllers/impl/Endpoint.h b/libraries/controllers/src/controllers/impl/Endpoint.h index 5dd3f6adb4..bc604da2c5 100644 --- a/libraries/controllers/src/controllers/impl/Endpoint.h +++ b/libraries/controllers/src/controllers/impl/Endpoint.h @@ -40,7 +40,7 @@ namespace controller { virtual void apply(float value, const Pointer& source) = 0; virtual Pose pose() { return Pose(); } virtual void apply(const Pose& value, const Pointer& source) {} - virtual const bool isPose() { return _input.isPose(); } + virtual bool isPose() { return _input.isPose(); } virtual bool writeable() const { return true; } virtual bool readable() const { return true; } @@ -54,6 +54,7 @@ namespace controller { class LambdaEndpoint : public Endpoint { public: + using Endpoint::apply; LambdaEndpoint(ReadLambda readLambda, WriteLambda writeLambda = [](float) {}) : Endpoint(Input::INVALID_INPUT), _readLambda(readLambda), _writeLambda(writeLambda) { } diff --git a/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h b/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h index 1e4205afc7..54ed57e871 100644 --- a/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h +++ b/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h @@ -18,7 +18,7 @@ namespace controller { class EndpointConditional : public Conditional { public: EndpointConditional(Endpoint::Pointer endpoint) : _endpoint(endpoint) {} - virtual bool satisfied() override { return _endpoint && _endpoint->value() != 0.0; } + virtual bool satisfied() override { return _endpoint && _endpoint->value() != 0.0f; } private: Endpoint::Pointer _endpoint; }; diff --git a/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h index 86dd057414..24834ce223 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h @@ -17,6 +17,7 @@ namespace controller { class AnyEndpoint : public Endpoint { friend class UserInputMapper; public: + using Endpoint::apply; AnyEndpoint(Endpoint::List children); virtual float value() override; virtual void apply(float newValue, const Endpoint::Pointer& source) override; diff --git a/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h index 79bb604ec0..899fa46de0 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h @@ -17,6 +17,7 @@ namespace controller { class ArrayEndpoint : public Endpoint { friend class UserInputMapper; public: + using Endpoint::apply; using Pointer = std::shared_ptr; ArrayEndpoint() : Endpoint(Input::INVALID_INPUT) { } diff --git a/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h index c6ec90b7c8..b29266464c 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h @@ -15,6 +15,7 @@ namespace controller { class CompositeEndpoint : public Endpoint, Endpoint::Pair { public: + using Endpoint::apply; CompositeEndpoint(Endpoint::Pointer first, Endpoint::Pointer second); virtual float value() override; diff --git a/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h index 27f17b5cd3..5113fef657 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h @@ -19,6 +19,7 @@ namespace controller { class JSEndpoint : public Endpoint { public: + using Endpoint::apply; JSEndpoint(const QJSValue& callable) : Endpoint(Input::INVALID_INPUT), _callable(callable) { } diff --git a/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h index 23f77892c6..37160fcb48 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h @@ -19,6 +19,7 @@ namespace controller { class ScriptEndpoint : public Endpoint { Q_OBJECT; public: + using Endpoint::apply; ScriptEndpoint(const QScriptValue& callable) : Endpoint(Input::INVALID_INPUT), _callable(callable) { } diff --git a/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.h index 74adaf825d..7fe1a5467e 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.h @@ -32,7 +32,7 @@ public: virtual void apply(float value, const Pointer& source) override { // For standard endpoints, the first NON-ZERO write counts. - if (value != 0.0) { + if (value != 0.0f) { _written = true; } VirtualEndpoint::apply(value, source); From 5916875345dcd51d16cfc484c5762295f40feac2 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 31 Oct 2015 08:20:24 -0700 Subject: [PATCH 20/44] one more --- .../controllers/src/controllers/impl/filters/InvertFilter.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/controllers/src/controllers/impl/filters/InvertFilter.h b/libraries/controllers/src/controllers/impl/filters/InvertFilter.h index 889cd0140c..8acc9d56d6 100644 --- a/libraries/controllers/src/controllers/impl/filters/InvertFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/InvertFilter.h @@ -17,6 +17,7 @@ namespace controller { class InvertFilter : public ScaleFilter { REGISTER_FILTER_CLASS(InvertFilter); public: + using ScaleFilter::parseParameters; InvertFilter() : ScaleFilter(-1.0f) {} virtual bool parseParameters(const QJsonArray& parameters) { return true; } From b877f832a9d7175826ad581c0ca50abe044a5936 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sat, 31 Oct 2015 13:02:17 -0700 Subject: [PATCH 21/44] fix SDL joysticks --- .../src/controllers/StandardControls.h | 6 ++--- .../src/input-plugins/SDL2Manager.cpp | 27 +++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/libraries/controllers/src/controllers/StandardControls.h b/libraries/controllers/src/controllers/StandardControls.h index 9c6defb865..d5063f6034 100644 --- a/libraries/controllers/src/controllers/StandardControls.h +++ b/libraries/controllers/src/controllers/StandardControls.h @@ -58,15 +58,15 @@ namespace controller { // Left Analog stick LX = 0, LY, - LZ, // Right Analog stick RX, RY, - RZ, // Triggers LT, RT, - NUM_STANDARD_AXES + NUM_STANDARD_AXES, + LZ = LT, + RZ = RT }; // No correlation to SDL diff --git a/libraries/input-plugins/src/input-plugins/SDL2Manager.cpp b/libraries/input-plugins/src/input-plugins/SDL2Manager.cpp index 48864beedc..ec2fa2ed07 100644 --- a/libraries/input-plugins/src/input-plugins/SDL2Manager.cpp +++ b/libraries/input-plugins/src/input-plugins/SDL2Manager.cpp @@ -18,6 +18,33 @@ #include "SDL2Manager.h" +#ifdef HAVE_SDL2 +static_assert( + controller::A == SDL_CONTROLLER_BUTTON_A && + controller::B == SDL_CONTROLLER_BUTTON_B && + controller::X == SDL_CONTROLLER_BUTTON_X && + controller::Y == SDL_CONTROLLER_BUTTON_Y && + controller::BACK == SDL_CONTROLLER_BUTTON_BACK && + controller::GUIDE == SDL_CONTROLLER_BUTTON_GUIDE && + controller::START == SDL_CONTROLLER_BUTTON_START && + controller::LS == SDL_CONTROLLER_BUTTON_LEFTSTICK && + controller::RS == SDL_CONTROLLER_BUTTON_RIGHTSTICK && + controller::LB == SDL_CONTROLLER_BUTTON_LEFTSHOULDER && + controller::RB == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER && + controller::DU == SDL_CONTROLLER_BUTTON_DPAD_UP && + controller::DD == SDL_CONTROLLER_BUTTON_DPAD_DOWN && + controller::DL == SDL_CONTROLLER_BUTTON_DPAD_LEFT && + controller::DR == SDL_CONTROLLER_BUTTON_DPAD_RIGHT && + controller::LX == SDL_CONTROLLER_AXIS_LEFTX && + controller::LY == SDL_CONTROLLER_AXIS_LEFTY && + controller::RX == SDL_CONTROLLER_AXIS_RIGHTX && + controller::RY == SDL_CONTROLLER_AXIS_RIGHTY && + controller::LT == SDL_CONTROLLER_AXIS_TRIGGERLEFT && + controller::RT == SDL_CONTROLLER_AXIS_TRIGGERRIGHT, + "SDL2 equvalence: Enums and values from StandardControls.h are assumed to match enums from SDL_gamecontroller.h"); +#endif + + const QString SDL2Manager::NAME = "SDL2"; #ifdef HAVE_SDL2 From 46f9a432aba2778a0060ae2ba0935effc8e83bf2 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sat, 31 Oct 2015 14:21:50 -0700 Subject: [PATCH 22/44] fix handControllerGrab.js --- examples/controllers/handControllerGrab.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 60e5286ad8..727e42cdc1 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -154,7 +154,7 @@ function entityIsGrabbedByOther(entityID) { } -function MyController(hand, triggerAction) { +function MyController(hand) { this.hand = hand; if (this.hand === RIGHT_HAND) { this.getHandPosition = MyAvatar.getRightPalmPosition; @@ -166,7 +166,6 @@ function MyController(hand, triggerAction) { var SPATIAL_CONTROLLERS_PER_PALM = 2; var TIP_CONTROLLER_OFFSET = 1; - this.triggerAction = triggerAction; this.palm = SPATIAL_CONTROLLERS_PER_PALM * hand; this.tip = SPATIAL_CONTROLLERS_PER_PALM * hand + TIP_CONTROLLER_OFFSET; @@ -282,7 +281,6 @@ function MyController(hand, triggerAction) { // smooth out trigger value this.triggerValue = (this.triggerValue * TRIGGER_SMOOTH_RATIO) + (triggerValue * (1.0 - TRIGGER_SMOOTH_RATIO)); - }; this.triggerSmoothedSqueezed = function() { @@ -439,8 +437,7 @@ function MyController(hand, triggerAction) { var handControllerPosition = (this.hand === RIGHT_HAND) ? MyAvatar.rightHandPosition : MyAvatar.leftHandPosition; var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getPoseValue(controllerHandInput).rotation); - var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation", - "gravity", "ignoreForCollisions", + var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); var now = Date.now(); @@ -906,8 +903,8 @@ function MyController(hand, triggerAction) { }; } -var rightController = new MyController(RIGHT_HAND, Controller.Standard.RT); -var leftController = new MyController(LEFT_HAND, Controller.Standard.LT); +var rightController = new MyController(RIGHT_HAND); +var leftController = new MyController(LEFT_HAND); var MAPPING_NAME = "com.highfidelity.handControllerGrab"; From abbfe153959cbe51db4b18b409903da7cfadc2f7 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 30 Oct 2015 14:34:18 -0700 Subject: [PATCH 23/44] Adding peek support for endpoints --- examples/controllers/handControllerGrab.js | 4 ++-- .../src/controllers/UserInputMapper.cpp | 16 +++++++++------- .../src/controllers/UserInputMapper.h | 8 ++++---- .../controllers/src/controllers/impl/Endpoint.h | 15 ++++++++------- .../controllers/src/controllers/impl/Route.h | 1 + .../src/controllers/impl/RouteBuilderProxy.cpp | 5 +++++ .../src/controllers/impl/RouteBuilderProxy.h | 3 ++- .../impl/conditionals/EndpointConditional.h | 2 +- .../controllers/impl/endpoints/ActionEndpoint.h | 4 ++-- .../controllers/impl/endpoints/AnyEndpoint.cpp | 11 +++++++++++ .../controllers/impl/endpoints/AnyEndpoint.h | 1 + .../controllers/impl/endpoints/ArrayEndpoint.h | 4 +--- .../impl/endpoints/CompositeEndpoint.cpp | 6 ++++++ .../impl/endpoints/CompositeEndpoint.h | 1 + .../impl/endpoints/InputEndpoint.cpp | 17 +++++++++++++---- .../controllers/impl/endpoints/InputEndpoint.h | 2 ++ .../src/controllers/impl/endpoints/JSEndpoint.h | 5 ++--- .../impl/endpoints/ScriptEndpoint.cpp | 4 ++-- .../controllers/impl/endpoints/ScriptEndpoint.h | 4 ++-- 19 files changed, 75 insertions(+), 38 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 727e42cdc1..a866983194 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -909,8 +909,8 @@ var leftController = new MyController(LEFT_HAND); var MAPPING_NAME = "com.highfidelity.handControllerGrab"; var mapping = Controller.newMapping(MAPPING_NAME); -mapping.from([Controller.Standard.RB, Controller.Standard.RT]).to(rightController.eitherTrigger); -mapping.from([Controller.Standard.LB, Controller.Standard.LT]).to(leftController.eitherTrigger); +mapping.from([Controller.Standard.RB, Controller.Standard.RT]).peek().to(rightController.eitherTrigger); +mapping.from([Controller.Standard.LB, Controller.Standard.LT]).peek().to(leftController.eitherTrigger); Controller.enableMapping(MAPPING_NAME); diff --git a/libraries/controllers/src/controllers/UserInputMapper.cpp b/libraries/controllers/src/controllers/UserInputMapper.cpp index 8e121de7fb..1a0fae8158 100755 --- a/libraries/controllers/src/controllers/UserInputMapper.cpp +++ b/libraries/controllers/src/controllers/UserInputMapper.cpp @@ -513,7 +513,7 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) { // and someone else wires it to CONTEXT_MENU, I don't want both to occur when // I press the button. The exception is if I'm wiring a control back to itself // in order to adjust my interface, like inverting the Y axis on an analog stick - if (!source->readable()) { + if (!route->peek && !source->readable()) { if (debugRoutes && route->debug) { qCDebug(controllers) << "Source unreadable"; } @@ -539,7 +539,7 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) { // Fetch the value, may have been overriden by previous loopback routes if (source->isPose()) { - Pose value = getPose(source); + Pose value = getPose(source, route->peek); static const Pose IDENTITY_POSE { vec3(), quat() }; if (debugRoutes && route->debug) { if (!value.valid) { @@ -554,7 +554,7 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) { destination->apply(value, source); } else { // Fetch the value, may have been overriden by previous loopback routes - float value = getValue(source); + float value = getValue(source, route->peek); if (debugRoutes && route->debug) { qCDebug(controllers) << "Value was " << value; @@ -691,8 +691,8 @@ void UserInputMapper::enableMapping(const QString& mappingName, bool enable) { } } -float UserInputMapper::getValue(const Endpoint::Pointer& endpoint) { - return endpoint->value(); +float UserInputMapper::getValue(const Endpoint::Pointer& endpoint, bool peek) { + return peek ? endpoint->peek() : endpoint->value(); } float UserInputMapper::getValue(const Input& input) const { @@ -704,11 +704,11 @@ float UserInputMapper::getValue(const Input& input) const { return endpoint->value(); } -Pose UserInputMapper::getPose(const Endpoint::Pointer& endpoint) { +Pose UserInputMapper::getPose(const Endpoint::Pointer& endpoint, bool peek) { if (!endpoint->isPose()) { return Pose(); } - return endpoint->pose(); + return peek ? endpoint->peekPose() : endpoint->pose(); } Pose UserInputMapper::getPose(const Input& input) const { @@ -742,6 +742,7 @@ static const QString JSON_NAME = QStringLiteral("name"); static const QString JSON_CHANNELS = QStringLiteral("channels"); static const QString JSON_CHANNEL_FROM = QStringLiteral("from"); static const QString JSON_CHANNEL_DEBUG = QStringLiteral("debug"); +static const QString JSON_CHANNEL_PEEK = QStringLiteral("peek"); static const QString JSON_CHANNEL_WHEN = QStringLiteral("when"); static const QString JSON_CHANNEL_TO = QStringLiteral("to"); static const QString JSON_CHANNEL_FILTERS = QStringLiteral("filters"); @@ -953,6 +954,7 @@ Route::Pointer UserInputMapper::parseRoute(const QJsonValue& value) { result->json = QString(QJsonDocument(obj).toJson()); result->source = parseSource(obj[JSON_CHANNEL_FROM]); result->debug = obj[JSON_CHANNEL_DEBUG].toBool(); + result->debug = obj[JSON_CHANNEL_PEEK].toBool(); if (!result->source) { qWarning() << "Invalid route source " << obj[JSON_CHANNEL_FROM]; return Route::Pointer(); diff --git a/libraries/controllers/src/controllers/UserInputMapper.h b/libraries/controllers/src/controllers/UserInputMapper.h index 7684ecb7c5..c1dfcf5d33 100644 --- a/libraries/controllers/src/controllers/UserInputMapper.h +++ b/libraries/controllers/src/controllers/UserInputMapper.h @@ -38,8 +38,8 @@ namespace controller { class UserInputMapper : public QObject, public Dependency { Q_OBJECT - SINGLETON_DEPENDENCY - Q_ENUMS(Action) + SINGLETON_DEPENDENCY + Q_ENUMS(Action) public: // FIXME move to unordered set / map @@ -135,8 +135,8 @@ namespace controller { int recordDeviceOfType(const QString& deviceName); QHash _deviceCounts; - static float getValue(const EndpointPointer& endpoint); - static Pose getPose(const EndpointPointer& endpoint); + static float getValue(const EndpointPointer& endpoint, bool peek = false); + static Pose getPose(const EndpointPointer& endpoint, bool peek = false); friend class RouteBuilderProxy; friend class MappingBuilderProxy; diff --git a/libraries/controllers/src/controllers/impl/Endpoint.h b/libraries/controllers/src/controllers/impl/Endpoint.h index bc604da2c5..475dc035bb 100644 --- a/libraries/controllers/src/controllers/impl/Endpoint.h +++ b/libraries/controllers/src/controllers/impl/Endpoint.h @@ -36,12 +36,13 @@ namespace controller { using WriteLambda = std::function; Endpoint(const Input& input) : _input(input) {} - virtual float value() = 0; + virtual float value() { return peek(); } + virtual float peek() const = 0; virtual void apply(float value, const Pointer& source) = 0; - virtual Pose pose() { return Pose(); } + virtual Pose peekPose() const { return Pose(); }; + virtual Pose pose() { return peekPose(); } virtual void apply(const Pose& value, const Pointer& source) {} - virtual bool isPose() { return _input.isPose(); } - + virtual bool isPose() const { return _input.isPose(); } virtual bool writeable() const { return true; } virtual bool readable() const { return true; } virtual void reset() { } @@ -58,7 +59,7 @@ namespace controller { LambdaEndpoint(ReadLambda readLambda, WriteLambda writeLambda = [](float) {}) : Endpoint(Input::INVALID_INPUT), _readLambda(readLambda), _writeLambda(writeLambda) { } - virtual float value() override { return _readLambda(); } + virtual float peek() const override { return _readLambda(); } virtual void apply(float value, const Pointer& source) override { _writeLambda(value); } private: @@ -73,10 +74,10 @@ namespace controller { : Endpoint(id) { } - virtual float value() override { return _currentValue; } + virtual float peek() const override { return _currentValue; } virtual void apply(float value, const Pointer& source) override { _currentValue = value; } - virtual Pose pose() override { return _currentPose; } + virtual Pose peekPose() const override { return _currentPose; } virtual void apply(const Pose& value, const Pointer& source) override { _currentPose = value; } diff --git a/libraries/controllers/src/controllers/impl/Route.h b/libraries/controllers/src/controllers/impl/Route.h index 5ad3d36628..554dd82d5a 100644 --- a/libraries/controllers/src/controllers/impl/Route.h +++ b/libraries/controllers/src/controllers/impl/Route.h @@ -26,6 +26,7 @@ namespace controller { Filter::List filters; QString json; bool debug { false }; + bool peek { false }; using Pointer = std::shared_ptr; using List = std::list; diff --git a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp index 49e615439d..5ae52893e0 100644 --- a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp +++ b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp @@ -52,6 +52,11 @@ QObject* RouteBuilderProxy::debug(bool enable) { return this; } +QObject* RouteBuilderProxy::peek(bool enable) { + _route->peek = enable; + return this; +} + QObject* RouteBuilderProxy::when(const QScriptValue& expression) { _route->conditional = _parent.conditionalFor(expression); return this; diff --git a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h index d55aa80f6b..1c0ed6931d 100644 --- a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h +++ b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h @@ -38,6 +38,7 @@ class RouteBuilderProxy : public QObject { Q_INVOKABLE void to(const QScriptValue& destination); Q_INVOKABLE QObject* debug(bool enable = true); + Q_INVOKABLE QObject* peek(bool enable = true); Q_INVOKABLE QObject* when(const QScriptValue& expression); Q_INVOKABLE QObject* clamp(float min, float max); Q_INVOKABLE QObject* hysteresis(float min, float max); @@ -48,7 +49,7 @@ class RouteBuilderProxy : public QObject { Q_INVOKABLE QObject* constrainToInteger(); Q_INVOKABLE QObject* constrainToPositiveInteger(); -private: + private: void to(const Endpoint::Pointer& destination); void conditional(const Conditional::Pointer& conditional); void addFilter(Filter::Pointer filter); diff --git a/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h b/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h index 54ed57e871..0ba1347087 100644 --- a/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h +++ b/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h @@ -18,7 +18,7 @@ namespace controller { class EndpointConditional : public Conditional { public: EndpointConditional(Endpoint::Pointer endpoint) : _endpoint(endpoint) {} - virtual bool satisfied() override { return _endpoint && _endpoint->value() != 0.0f; } + virtual bool satisfied() override { return _endpoint && _endpoint->peek() != 0.0f; } private: Endpoint::Pointer _endpoint; }; diff --git a/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.h index 574fdcedb5..e07dc9e4c8 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.h @@ -23,10 +23,10 @@ class ActionEndpoint : public Endpoint { public: ActionEndpoint(const Input& id = Input::INVALID_INPUT) : Endpoint(id) { } - virtual float value() override { return _currentValue; } + virtual float peek() const { return _currentValue; } virtual void apply(float newValue, const Pointer& source) override; - virtual Pose pose() override { return _currentPose; } + virtual Pose peekPose() const { return _currentPose; } virtual void apply(const Pose& value, const Pointer& source) override; virtual void reset() override; diff --git a/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp index 24f3479ea8..0dd53fe78f 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp +++ b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp @@ -27,6 +27,17 @@ AnyEndpoint::AnyEndpoint(Endpoint::List children) : Endpoint(Input::INVALID_INPU } } +float AnyEndpoint::peek() const { + for (auto& child : _children) { + float childResult = child->peek(); + if (childResult != 0.0f) { + return childResult; + } + } + return 0.0f; +} + +// Fetching the value must trigger any necessary side effects of value() on ALL the children. float AnyEndpoint::value() { float result = 0; for (auto& child : _children) { diff --git a/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h index 24834ce223..8947eb675f 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h @@ -19,6 +19,7 @@ class AnyEndpoint : public Endpoint { public: using Endpoint::apply; AnyEndpoint(Endpoint::List children); + virtual float peek() const override; virtual float value() override; virtual void apply(float newValue, const Endpoint::Pointer& source) override; virtual bool writeable() const override; diff --git a/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h index 899fa46de0..34d30a2e97 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h @@ -21,9 +21,7 @@ public: using Pointer = std::shared_ptr; ArrayEndpoint() : Endpoint(Input::INVALID_INPUT) { } - virtual float value() override { - return 0.0; - } + virtual float peek() const override { return 0.0f; } virtual void apply(float value, const Endpoint::Pointer& source) override { for (auto& child : _children) { diff --git a/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.cpp index 913bf0136b..1bd27489f8 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.cpp +++ b/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.cpp @@ -24,6 +24,12 @@ bool CompositeEndpoint::readable() const { return first->readable() && second->readable(); } +float CompositeEndpoint::peek() const { + float result = first->peek() * -1.0f + second->peek(); + return result; +} + +// Fetching via value() must trigger any side effects of value() on the children float CompositeEndpoint::value() { float result = first->value() * -1.0f + second->value(); return result; diff --git a/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h index b29266464c..3249aa1d37 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h @@ -18,6 +18,7 @@ namespace controller { using Endpoint::apply; CompositeEndpoint(Endpoint::Pointer first, Endpoint::Pointer second); + virtual float peek() const override; virtual float value() override; virtual void apply(float newValue, const Pointer& source) override; virtual bool readable() const override; diff --git a/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.cpp index bb1f6df191..ce58c948d1 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.cpp +++ b/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.cpp @@ -13,10 +13,10 @@ #include "../../UserInputMapper.h" using namespace controller; -float InputEndpoint::value(){ - _read = true; + +float InputEndpoint::peek() const { if (isPose()) { - return pose().valid ? 1.0f : 0.0f; + return peekPose().valid ? 1.0f : 0.0f; } auto userInputMapper = DependencyManager::get(); auto deviceProxy = userInputMapper->getDevice(_input); @@ -26,8 +26,12 @@ float InputEndpoint::value(){ return deviceProxy->getValue(_input); } -Pose InputEndpoint::pose() { +float InputEndpoint::value(){ _read = true; + return peek(); +} + +Pose InputEndpoint::peekPose() const { if (!isPose()) { return Pose(); } @@ -39,3 +43,8 @@ Pose InputEndpoint::pose() { return deviceProxy->getPose(_input.channel); } +Pose InputEndpoint::pose() { + _read = true; + return peekPose(); +} + diff --git a/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.h index d58f0c2e73..663168bedc 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.h @@ -20,9 +20,11 @@ public: : Endpoint(id) { } + virtual float peek() const override; virtual float value() override; // FIXME need support for writing back to vibration / force feedback effects virtual void apply(float newValue, const Pointer& source) override {} + virtual Pose peekPose() const override; virtual Pose pose() override; virtual void apply(const Pose& value, const Pointer& source) override { } diff --git a/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h index 5113fef657..958914264e 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h @@ -24,9 +24,8 @@ public: : Endpoint(Input::INVALID_INPUT), _callable(callable) { } - virtual float value() { - float result = (float)_callable.call().toNumber(); - return result; + virtual float peek() const { + return (float)const_cast(this)->_callable.call().toNumber(); } virtual void apply(float newValue, const Pointer& source) { diff --git a/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.cpp index d9b4a5fc59..bb9517b136 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.cpp +++ b/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.cpp @@ -12,8 +12,8 @@ using namespace controller; -float ScriptEndpoint::value() { - updateValue(); +float ScriptEndpoint::peek() const { + const_cast(this)->updateValue(); return _lastValueRead; } diff --git a/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h index 37160fcb48..836af721f6 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h @@ -24,8 +24,8 @@ public: : Endpoint(Input::INVALID_INPUT), _callable(callable) { } - virtual float value(); - virtual void apply(float newValue, const Pointer& source); + virtual float peek() const override; + virtual void apply(float newValue, const Pointer& source) override; protected: Q_INVOKABLE void updateValue(); From 0e13348b5a3f4874552097cff8f58a122be72676 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sat, 31 Oct 2015 13:24:26 -0700 Subject: [PATCH 24/44] PR feedback --- .../src/controllers/impl/endpoints/AnyEndpoint.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp index 0dd53fe78f..a3b719b2c1 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp +++ b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp @@ -28,23 +28,18 @@ AnyEndpoint::AnyEndpoint(Endpoint::List children) : Endpoint(Input::INVALID_INPU } float AnyEndpoint::peek() const { + float result = 0; for (auto& child : _children) { - float childResult = child->peek(); - if (childResult != 0.0f) { - return childResult; - } + result = std::max(result, child->peek()); } - return 0.0f; + return result; } // Fetching the value must trigger any necessary side effects of value() on ALL the children. float AnyEndpoint::value() { float result = 0; for (auto& child : _children) { - float childResult = child->value(); - if (childResult != 0.0f) { - result = childResult; - } + result = std::max(result, child->value()); } return result; } From 9346366fc51e79cc1515ec63166ec0dc9f912824 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 31 Oct 2015 14:28:54 -0700 Subject: [PATCH 25/44] fix grab script --- examples/controllers/handControllerGrab.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 727e42cdc1..339c1ad002 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -437,8 +437,9 @@ function MyController(hand) { var handControllerPosition = (this.hand === RIGHT_HAND) ? MyAvatar.rightHandPosition : MyAvatar.leftHandPosition; var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getPoseValue(controllerHandInput).rotation); - var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); - + var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation", + "gravity", "ignoreForCollisions", + "collisionsWillMove"]); var now = Date.now(); // add the action and initialize some variables From 05dea847be1e2029157e6355fccf9df8794f0f7a Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sat, 31 Oct 2015 15:47:40 -0700 Subject: [PATCH 26/44] add Actions.CycleCamera and wire up secondary thumb buttons to Actions.CycleCamera and Actions.ContextMenu --- interface/resources/controllers/standard.json | 3 + interface/src/Application.cpp | 32 ++++++++- interface/src/Application.h | 3 +- .../controllers/src/controllers/Actions.cpp | 1 + .../controllers/src/controllers/Actions.h | 1 + .../src/controllers/StandardController.cpp | 36 ---------- .../src/input-plugins/KeyboardMouseDevice.cpp | 69 ------------------- .../src/input-plugins/SixenseManager.cpp | 43 ------------ 8 files changed, 37 insertions(+), 151 deletions(-) diff --git a/interface/resources/controllers/standard.json b/interface/resources/controllers/standard.json index 871374b85b..dff0ab95b0 100644 --- a/interface/resources/controllers/standard.json +++ b/interface/resources/controllers/standard.json @@ -25,6 +25,9 @@ { "from": [ "Standard.A", "Standard.B", "Standard.X", "Standard.Y" ], "to": "Standard.RightPrimaryThumb" }, { "from": "Standard.Start", "to": "Standard.RightSecondaryThumb" }, + { "from": "Standard.LeftSecondaryThumb", "to": "Actions.CycleCamera" }, + { "from": "Standard.RightSecondaryThumb", "to": "Actions.ContextMenu" }, + { "from": "Standard.LT", "to": "Actions.LeftHandClick" }, { "from": "Standard.RT", "to": "Actions.RightHandClick" }, diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7f4b5a3c3d..dc2eee000d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -630,8 +630,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : // Setup the userInputMapper with the actions auto userInputMapper = DependencyManager::get(); connect(userInputMapper.data(), &UserInputMapper::actionEvent, [this](int action, float state) { - if (state && action == toInt(controller::Action::TOGGLE_MUTE)) { - DependencyManager::get()->toggleMute(); + if (state) { + if (action == controller::toInt(controller::Action::TOGGLE_MUTE)) { + DependencyManager::get()->toggleMute(); + } else if (action == controller::toInt(controller::Action::CYCLE_CAMERA)) { + cycleCamera(); + } } }); @@ -2620,6 +2624,30 @@ void Application::updateThreads(float deltaTime) { } } +void Application::cycleCamera() { + auto menu = Menu::getInstance(); + if (menu->isOptionChecked(MenuOption::FullscreenMirror)) { + + menu->setIsOptionChecked(MenuOption::FullscreenMirror, false); + menu->setIsOptionChecked(MenuOption::FirstPerson, true); + + } else if (menu->isOptionChecked(MenuOption::FirstPerson)) { + + menu->setIsOptionChecked(MenuOption::FirstPerson, false); + menu->setIsOptionChecked(MenuOption::ThirdPerson, true); + + } else if (menu->isOptionChecked(MenuOption::ThirdPerson)) { + + menu->setIsOptionChecked(MenuOption::ThirdPerson, false); + menu->setIsOptionChecked(MenuOption::FullscreenMirror, true); + + } else if (menu->isOptionChecked(MenuOption::IndependentMode)) { + // do nothing if in independe mode + return; + } + cameraMenuChanged(); // handle the menu change +} + void Application::cameraMenuChanged() { if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { if (_myCamera.getMode() != CAMERA_MODE_MIRROR) { diff --git a/interface/src/Application.h b/interface/src/Application.h index bf45a0c6ec..dfc904e0ef 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -293,8 +293,9 @@ public slots: void aboutApp(); void showEditEntitiesHelp(); + void cycleCamera(); void cameraMenuChanged(); - + void reloadResourceCaches(); void crashApplication(); diff --git a/libraries/controllers/src/controllers/Actions.cpp b/libraries/controllers/src/controllers/Actions.cpp index a4a8656fb7..701aea79c5 100644 --- a/libraries/controllers/src/controllers/Actions.cpp +++ b/libraries/controllers/src/controllers/Actions.cpp @@ -60,6 +60,7 @@ namespace controller { makeButtonPair(Action::ACTION2, "SecondaryAction"), makeButtonPair(Action::CONTEXT_MENU, "ContextMenu"), makeButtonPair(Action::TOGGLE_MUTE, "ToggleMute"), + makeButtonPair(Action::CYCLE_CAMERA, "CycleCamera"), // Aliases and bisected versions makeAxisPair(Action::LONGITUDINAL_BACKWARD, "Backward"), diff --git a/libraries/controllers/src/controllers/Actions.h b/libraries/controllers/src/controllers/Actions.h index 36df695032..d5ad44c720 100644 --- a/libraries/controllers/src/controllers/Actions.h +++ b/libraries/controllers/src/controllers/Actions.h @@ -51,6 +51,7 @@ enum class Action { CONTEXT_MENU, TOGGLE_MUTE, + CYCLE_CAMERA, SHIFT, diff --git a/libraries/controllers/src/controllers/StandardController.cpp b/libraries/controllers/src/controllers/StandardController.cpp index 44f1bff1ae..31c023b1ea 100644 --- a/libraries/controllers/src/controllers/StandardController.cpp +++ b/libraries/controllers/src/controllers/StandardController.cpp @@ -118,41 +118,5 @@ QString StandardController::getDefaultMappingConfig() const { return DEFAULT_MAPPING_JSON; } -// FIXME figure out how to move the shifted version to JSON -//void StandardController::assignDefaultInputMapping(UserInputMapper& mapper) { -// const float JOYSTICK_MOVE_SPEED = 1.0f; -// const float DPAD_MOVE_SPEED = 0.5f; -// const float JOYSTICK_YAW_SPEED = 0.5f; -// const float JOYSTICK_PITCH_SPEED = 0.25f; -// const float BOOM_SPEED = 0.1f; -// -// // Hold front right shoulder button for precision controls -// // Left Joystick: Movement, strafing -// mapper.addInputChannel(UserInputMapper::TRANSLATE_Z, makeInput(controller::LY), makeInput(controller::RB), JOYSTICK_MOVE_SPEED / 2.0f); -// mapper.addInputChannel(UserInputMapper::TRANSLATE_X, makeInput(controller::LY), makeInput(controller::RB), JOYSTICK_MOVE_SPEED / 2.0f); -// -// // Right Joystick: Camera orientation -// mapper.addInputChannel(UserInputMapper::YAW, makeInput(controller::RX), makeInput(controller::RB), JOYSTICK_YAW_SPEED / 2.0f); -// mapper.addInputChannel(UserInputMapper::PITCH, makeInput(controller::RY), makeInput(controller::RB), JOYSTICK_PITCH_SPEED / 2.0f); -// -// // Dpad movement -// mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(controller::DU), makeInput(controller::RB), DPAD_MOVE_SPEED / 2.0f); -// mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(controller::DD), makeInput(controller::RB), DPAD_MOVE_SPEED / 2.0f); -// mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(controller::DR), makeInput(controller::RB), DPAD_MOVE_SPEED / 2.0f); -// mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(controller::DL), makeInput(controller::RB), DPAD_MOVE_SPEED / 2.0f); -// -// // Button controls -// mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(controller::Y), makeInput(controller::RB), DPAD_MOVE_SPEED / 2.0f); -// mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(controller::X), makeInput(controller::RB), DPAD_MOVE_SPEED / 2.0f); -// -// // Zoom -// mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(controller::RT), makeInput(controller::RB), BOOM_SPEED / 2.0f); -// mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(controller::LT), makeInput(controller::RB), BOOM_SPEED / 2.0f); -// -// mapper.addInputChannel(UserInputMapper::SHIFT, makeInput(controller::RB)); -// -// mapper.addInputChannel(UserInputMapper::ACTION1, makeInput(controller::B)); -// mapper.addInputChannel(UserInputMapper::ACTION2, makeInput(controller::A)); -//} } diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index a0481dfaa0..9cd510c521 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -209,72 +209,3 @@ QString KeyboardMouseDevice::getDefaultMappingConfig() const { return MAPPING_JSON; } -//void KeyboardMouseDevice::assignDefaultInputMapping(UserInputMapper& mapper) { -// const float BUTTON_MOVE_SPEED = 1.0f; -// const float BUTTON_YAW_SPEED = 0.75f; -// const float BUTTON_PITCH_SPEED = 0.5f; -// const float MOUSE_YAW_SPEED = 0.5f; -// const float MOUSE_PITCH_SPEED = 0.25f; -// const float TOUCH_YAW_SPEED = 0.5f; -// const float TOUCH_PITCH_SPEED = 0.25f; -// const float BUTTON_BOOM_SPEED = 0.1f; -// -// // AWSD keys mapping -// -// mapper.addInputChannel(controller::BOOM_IN, makeInput(Qt::Key_E), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); -// mapper.addInputChannel(controller::BOOM_OUT, makeInput(Qt::Key_C), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); -// mapper.addInputChannel(controller::LATERAL_LEFT, makeInput(Qt::Key_A), makeInput(Qt::RightButton), BUTTON_YAW_SPEED); -// mapper.addInputChannel(controller::LATERAL_RIGHT, makeInput(Qt::Key_D), makeInput(Qt::RightButton), BUTTON_YAW_SPEED); -// mapper.addInputChannel(controller::LATERAL_LEFT, makeInput(Qt::Key_A), makeInput(Qt::Key_Shift), BUTTON_YAW_SPEED); -// mapper.addInputChannel(controller::LATERAL_RIGHT, makeInput(Qt::Key_D), makeInput(Qt::Key_Shift), BUTTON_YAW_SPEED); -// mapper.addInputChannel(controller::PITCH_DOWN, makeInput(Qt::Key_S), makeInput(Qt::Key_Shift), BUTTON_PITCH_SPEED); -// mapper.addInputChannel(controller::PITCH_UP, makeInput(Qt::Key_W), makeInput(Qt::Key_Shift), BUTTON_PITCH_SPEED); -// -// // Arrow keys mapping -// mapper.addInputChannel(controller::LONGITUDINAL_BACKWARD, makeInput(Qt::Key_Down), BUTTON_MOVE_SPEED); -// mapper.addInputChannel(controller::LONGITUDINAL_FORWARD, makeInput(Qt::Key_Up), BUTTON_MOVE_SPEED); -// mapper.addInputChannel(controller::YAW_LEFT, makeInput(Qt::Key_Left), BUTTON_MOVE_SPEED); -// mapper.addInputChannel(controller::YAW_RIGHT, makeInput(Qt::Key_Right), BUTTON_MOVE_SPEED); -// mapper.addInputChannel(controller::VERTICAL_DOWN, makeInput(Qt::Key_PageDown), BUTTON_MOVE_SPEED); -// mapper.addInputChannel(controller::VERTICAL_UP, makeInput(Qt::Key_PageUp), BUTTON_MOVE_SPEED); -// -// mapper.addInputChannel(controller::LATERAL_LEFT, makeInput(Qt::Key_Left), makeInput(Qt::RightButton), BUTTON_YAW_SPEED); -// mapper.addInputChannel(controller::LATERAL_RIGHT, makeInput(Qt::Key_Right), makeInput(Qt::RightButton), BUTTON_YAW_SPEED); -// mapper.addInputChannel(controller::LATERAL_LEFT, makeInput(Qt::Key_Left), makeInput(Qt::Key_Shift), BUTTON_YAW_SPEED); -// mapper.addInputChannel(controller::LATERAL_RIGHT, makeInput(Qt::Key_Right), makeInput(Qt::Key_Shift), BUTTON_YAW_SPEED); -// mapper.addInputChannel(controller::PITCH_DOWN, makeInput(Qt::Key_Down), makeInput(Qt::Key_Shift), BUTTON_PITCH_SPEED); -// mapper.addInputChannel(controller::PITCH_UP, makeInput(Qt::Key_Up), makeInput(Qt::Key_Shift), BUTTON_PITCH_SPEED); -// -// // Mouse move -// mapper.addInputChannel(controller::PITCH_DOWN, makeInput(MOUSE_AXIS_Y_NEG), makeInput(Qt::RightButton), MOUSE_PITCH_SPEED); -// mapper.addInputChannel(controller::PITCH_UP, makeInput(MOUSE_AXIS_Y_POS), makeInput(Qt::RightButton), MOUSE_PITCH_SPEED); -// mapper.addInputChannel(controller::YAW_LEFT, makeInput(MOUSE_AXIS_X_NEG), makeInput(Qt::RightButton), MOUSE_YAW_SPEED); -// mapper.addInputChannel(controller::YAW_RIGHT, makeInput(MOUSE_AXIS_X_POS), makeInput(Qt::RightButton), MOUSE_YAW_SPEED); -// -// -//#ifdef Q_OS_MAC -// // wheel event modifier on Mac collide with the touchpad scroll event -// mapper.addInputChannel(controller::PITCH_DOWN, makeInput(TOUCH_AXIS_Y_NEG), TOUCH_PITCH_SPEED); -// mapper.addInputChannel(controller::PITCH_UP, makeInput(TOUCH_AXIS_Y_POS), TOUCH_PITCH_SPEED); -// mapper.addInputChannel(controller::YAW_LEFT, makeInput(TOUCH_AXIS_X_NEG), TOUCH_YAW_SPEED); -// mapper.addInputChannel(controller::YAW_RIGHT, makeInput(TOUCH_AXIS_X_POS), TOUCH_YAW_SPEED); -//#else -// // Touch pad yaw pitch -// mapper.addInputChannel(controller::PITCH_DOWN, makeInput(TOUCH_AXIS_Y_NEG), TOUCH_PITCH_SPEED); -// mapper.addInputChannel(controller::PITCH_UP, makeInput(TOUCH_AXIS_Y_POS), TOUCH_PITCH_SPEED); -// mapper.addInputChannel(controller::YAW_LEFT, makeInput(TOUCH_AXIS_X_NEG), TOUCH_YAW_SPEED); -// mapper.addInputChannel(controller::YAW_RIGHT, makeInput(TOUCH_AXIS_X_POS), TOUCH_YAW_SPEED); -// -// // Wheel move -// mapper.addInputChannel(controller::BOOM_IN, makeInput(MOUSE_AXIS_WHEEL_Y_POS), BUTTON_BOOM_SPEED); -// mapper.addInputChannel(controller::BOOM_OUT, makeInput(MOUSE_AXIS_WHEEL_Y_NEG), BUTTON_BOOM_SPEED); -// mapper.addInputChannel(controller::LATERAL_LEFT, makeInput(MOUSE_AXIS_WHEEL_X_NEG), BUTTON_YAW_SPEED); -// mapper.addInputChannel(controller::LATERAL_RIGHT, makeInput(MOUSE_AXIS_WHEEL_X_POS), BUTTON_YAW_SPEED); -// -//#endif -// -// mapper.addInputChannel(controller::SHIFT, makeInput(Qt::Key_Space)); -// mapper.addInputChannel(controller::ACTION1, makeInput(Qt::Key_R)); -// mapper.addInputChannel(controller::ACTION2, makeInput(Qt::Key_T)); -//} - diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp index 6cb58ced82..5e0f3277b1 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp +++ b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp @@ -556,49 +556,6 @@ QString SixenseManager::getDefaultMappingConfig() const { return MAPPING_JSON; } -// -//void SixenseManager::assignDefaultInputMapping(UserInputMapper& mapper) { -// const float JOYSTICK_MOVE_SPEED = 1.0f; -// const float JOYSTICK_YAW_SPEED = 0.5f; -// const float JOYSTICK_PITCH_SPEED = 0.25f; -// const float BUTTON_MOVE_SPEED = 1.0f; -// const float BOOM_SPEED = 0.1f; -// using namespace controller; -// -// // Left Joystick: Movement, strafing -// mapper.addInputChannel(UserInputMapper::TRANSLATE_Z, makeInput(LY), JOYSTICK_MOVE_SPEED); -// mapper.addInputChannel(UserInputMapper::TRANSLATE_X, makeInput(LX), JOYSTICK_MOVE_SPEED); -// -// // Right Joystick: Camera orientation -// mapper.addInputChannel(UserInputMapper::YAW, makeInput(RX), JOYSTICK_YAW_SPEED); -// mapper.addInputChannel(UserInputMapper::PITCH, makeInput(RY), JOYSTICK_PITCH_SPEED); -// -// // Buttons -// mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(L3), BOOM_SPEED); -// mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(L1), BOOM_SPEED); -// -// mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(R3), BUTTON_MOVE_SPEED); -// mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(R1), BUTTON_MOVE_SPEED); -// -// mapper.addInputChannel(UserInputMapper::SHIFT, makeInput(L2)); -// mapper.addInputChannel(UserInputMapper::SHIFT, makeInput(R2)); -// -// mapper.addInputChannel(UserInputMapper::ACTION1, makeInput(L4)); -// mapper.addInputChannel(UserInputMapper::ACTION2, makeInput(R4)); -// -// // FIXME -//// mapper.addInputChannel(UserInputMapper::LEFT_HAND, makeInput(LEFT_HAND)); -//// mapper.addInputChannel(UserInputMapper::RIGHT_HAND, makeInput(RIGHT_HAND)); -// -// mapper.addInputChannel(UserInputMapper::LEFT_HAND_CLICK, makeInput(LT)); -// mapper.addInputChannel(UserInputMapper::RIGHT_HAND_CLICK, makeInput(RT)); -// -// // TODO find a mechanism to allow users to navigate the context menu via -// mapper.addInputChannel(UserInputMapper::CONTEXT_MENU, makeInput(L0)); -// mapper.addInputChannel(UserInputMapper::TOGGLE_MUTE, makeInput(R0)); -// -//} - // virtual void SixenseManager::saveSettings() const { Settings settings; From 77816d818a096b3d331b857b602a3074e22cd453 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sat, 31 Oct 2015 16:00:22 -0700 Subject: [PATCH 27/44] make RY map to jump --- interface/resources/controllers/standard.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/controllers/standard.json b/interface/resources/controllers/standard.json index dff0ab95b0..b08abcbaad 100644 --- a/interface/resources/controllers/standard.json +++ b/interface/resources/controllers/standard.json @@ -16,7 +16,7 @@ { "from": "Standard.RX", "to": "Actions.Yaw" }, - { "from": "Standard.RY", "to": "Actions.Pitch" }, + { "from": "Standard.RY", "filters": "invert", "to": "Actions.TranslateY" }, { "from": [ "Standard.DU", "Standard.DL", "Standard.DR", "Standard.DD" ], "to": "Standard.LeftPrimaryThumb" }, From 7fa6fb13085793560eca7b153aacf63e4b4e0f68 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sun, 1 Nov 2015 01:36:12 -0700 Subject: [PATCH 28/44] Remove GLEW spam in cmake --- cmake/modules/FindGLEW.cmake | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cmake/modules/FindGLEW.cmake b/cmake/modules/FindGLEW.cmake index 4f22271e3e..f4eca0eddf 100644 --- a/cmake/modules/FindGLEW.cmake +++ b/cmake/modules/FindGLEW.cmake @@ -30,6 +30,4 @@ include(SelectLibraryConfigurations) select_library_configurations(GLEW) include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_INCLUDE_DIRS GLEW_LIBRARIES) - -message(STATUS "Found GLEW - Assuming that GLEW is static and defining GLEW_STATIC") \ No newline at end of file +find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_INCLUDE_DIRS GLEW_LIBRARIES) \ No newline at end of file From 99d8554cc8050fa29ba73205155e7d455f0d2458 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sun, 1 Nov 2015 01:36:54 -0700 Subject: [PATCH 29/44] Make zlib a true external on windows (linux and OSX should rely on system libraries) --- cmake/externals/zlib/CMakeLists.txt | 49 +++++++++++++++-------------- cmake/macros/TargetZlib.cmake | 17 ++++++++++ libraries/shared/CMakeLists.txt | 12 +------ 3 files changed, 44 insertions(+), 34 deletions(-) create mode 100644 cmake/macros/TargetZlib.cmake diff --git a/cmake/externals/zlib/CMakeLists.txt b/cmake/externals/zlib/CMakeLists.txt index 69dbca714d..0d279cc469 100644 --- a/cmake/externals/zlib/CMakeLists.txt +++ b/cmake/externals/zlib/CMakeLists.txt @@ -1,28 +1,31 @@ +set(EXTERNAL_NAME zlib) +string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) -if (WIN32) - set(EXTERNAL_NAME zlib) - string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) +include(ExternalProject) - include(ExternalProject) - ExternalProject_Add( - ${EXTERNAL_NAME} - URL http://zlib.net/zlib128.zip - URL_MD5 126f8676442ffbd97884eb4d6f32afb4 - INSTALL_COMMAND "" - LOG_DOWNLOAD 1 - ) +ExternalProject_Add( +${EXTERNAL_NAME} +URL http://zlib.net/zlib128.zip +CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= +BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build +LOG_DOWNLOAD 1 +LOG_CONFIGURE 1 +LOG_BUILD 1 +) + +# Hide this external target (for ide users) +set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") - # Hide this external target (for ide users) - set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") +ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) +set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIR ${INSTALL_DIR}/include CACHE PATH "List of zlib include directories") +set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${${EXTERNAL_NAME_UPPER}_INCLUDE_DIR} CACHE PATH "List of zlib include directories") +set(${EXTERNAL_NAME_UPPER}_DLL_PATH ${INSTALL_DIR}/bin CACHE FILEPATH "Location of ZLib DLL") +set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/zlib.lib CACHE FILEPATH "Location of zlib release library") +set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/zlibd.lib CACHE FILEPATH "Location of zlib debug library") - ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) +include(SelectLibraryConfigurations) +select_library_configurations(${EXTERNAL_NAME_UPPER}) - set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE PATH "List of zlib include directories") - - ExternalProject_Get_Property(${EXTERNAL_NAME} BINARY_DIR) - - set(${EXTERNAL_NAME_UPPER}_DLL_PATH ${BINARY_DIR}/Release CACHE FILEPATH "Location of GLEW DLL") - set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${BINARY_DIR}/Release/zlib.lib CACHE FILEPATH "Location of ZLib release library") - set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG "" CACHE FILEPATH "Location of ZLib debug library") - -endif () \ No newline at end of file +# Force selected libraries into the cache +set(${EXTERNAL_NAME_UPPER}_LIBRARY ${${EXTERNAL_NAME_UPPER}_LIBRARY} CACHE FILEPATH "Location of zlib libraries") +set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE FILEPATH "Location of zlib libraries") diff --git a/cmake/macros/TargetZlib.cmake b/cmake/macros/TargetZlib.cmake new file mode 100644 index 0000000000..11eb8c132e --- /dev/null +++ b/cmake/macros/TargetZlib.cmake @@ -0,0 +1,17 @@ +# +# Copyright 2015 High Fidelity, Inc. +# Created by Bradley Austin Davis on 2015/10/10 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# +macro(TARGET_ZLIB) + if (WIN32) + add_dependency_external_projects(zlib) + add_paths_to_fixup_libs(${ZLIB_DLL_PATH}) + else() + find_package(ZLIB REQUIRED) + endif() + target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${ZLIB_INCLUDE_DIRS}) + target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES}) +endmacro() diff --git a/libraries/shared/CMakeLists.txt b/libraries/shared/CMakeLists.txt index d9df5eba7f..2691c51128 100644 --- a/libraries/shared/CMakeLists.txt +++ b/libraries/shared/CMakeLists.txt @@ -3,14 +3,4 @@ set(TARGET_NAME shared) # TODO: there isn't really a good reason to have Script linked here - let's get what is requiring it out (RegisteredMetaTypes.cpp) setup_hifi_library(Gui Network Script Widgets) -find_package(ZLIB REQUIRED) -target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES}) -target_include_directories(${TARGET_NAME} PUBLIC ${ZLIB_INCLUDE_DIRS}) - -if (WIN32) - # Birarda will fix this when he finds it. - get_filename_component(ZLIB_LIB_DIR "${ZLIB_LIBRARIES}" DIRECTORY) - get_filename_component(ZLIB_DIR "${ZLIB_LIB_DIR}" DIRECTORY) - set(ZLIB_BIN_DIR "${ZLIB_DIR}/bin") - add_paths_to_fixup_libs(${ZLIB_BIN_DIR}) -endif () +target_zlib() From cad1d28b7bee0af3474c06cea1ae1fed4e750af7 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sun, 1 Nov 2015 01:49:33 -0700 Subject: [PATCH 30/44] Updating build notes --- BUILD.md | 6 +----- BUILD_WIN.md | 10 ---------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/BUILD.md b/BUILD.md index e2f310bb1f..7ad2ddeee0 100644 --- a/BUILD.md +++ b/BUILD.md @@ -13,17 +13,13 @@ * [Intel Threading Building Blocks](https://www.threadingbuildingblocks.org/) ~> 4.3 * [glm](http://glm.g-truc.net/0.9.5/index.html) ~> 0.9.5.4 * [gverb](https://github.com/highfidelity/gverb) - -The following external projects are optional dependencies. You can indicate to CMake that you would like to include them by passing -DGET_$NAME=1 when running a clean CMake build. For example, to get CMake to download and compile SDL2 you would pass -DGET_SDL2=1. - * [SDL2](https://www.libsdl.org/download-2.0.php) ~> 2.0.3 - * Enables game controller support in Interface The above dependencies will be downloaded, built, linked and included automatically by CMake where we require them. The CMakeLists files that handle grabbing each of the following external dependencies can be found in the [cmake/externals folder](cmake/externals). The resulting downloads, source files and binaries will be placed in the `build/ext` folder in each of the subfolders for each external project. These are not placed in your normal build tree when doing an out of source build so that they do not need to be re-downloaded and re-compiled every time the CMake build folder is cleared. Should you want to force a re-download and re-compile of a specific external, you can simply remove that directory from the appropriate subfolder in `build/ext`. Should you want to force a re-download and re-compile of all externals, just remove the `build/ext` folder. -If you would like to use a specific install of a dependency instead of the version that would be grabbed as a CMake ExternalProject, you can pass -DGET_$NAME=0 (where $NAME is the name of the subfolder in [cmake/externals](cmake/externals)) when you run CMake to tell it not to get that dependency as an external project. +If you would like to use a specific install of a dependency instead of the version that would be grabbed as a CMake ExternalProject, you can pass -DUSE_LOCAL_$NAME=0 (where $NAME is the name of the subfolder in [cmake/externals](cmake/externals)) when you run CMake to tell it not to get that dependency as an external project. ###OS Specific Build Guides * [BUILD_OSX.md](BUILD_OSX.md) - additional instructions for OS X. diff --git a/BUILD_WIN.md b/BUILD_WIN.md index d291cef4f2..89646e99ff 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -75,16 +75,6 @@ To prevent these problems, install OpenSSL yourself. Download the following bina Install OpenSSL into the Windows system directory, to make sure that Qt uses the version that you've just installed, and not some other version. -####zlib - -Install zlib from - - [Zlib for Windows](http://gnuwin32.sourceforge.net/packages/zlib.htm) - -and fix a header file, as described here: - - [zlib zconf.h bug](http://sourceforge.net/p/gnuwin32/bugs/169/) - ###Build High Fidelity using Visual Studio Follow the same build steps from the CMake section of [BUILD.md](BUILD.md), but pass a different generator to CMake. From e899229cdeb0f78d274ad4b83c91585b778d37c1 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 1 Nov 2015 09:55:30 -0800 Subject: [PATCH 31/44] tweaks to how VrMenu is shown --- interface/resources/controllers/keyboardMouse.json | 3 ++- interface/src/Application.cpp | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/interface/resources/controllers/keyboardMouse.json b/interface/resources/controllers/keyboardMouse.json index 8af6b1dc98..9c3ba79d76 100644 --- a/interface/resources/controllers/keyboardMouse.json +++ b/interface/resources/controllers/keyboardMouse.json @@ -81,6 +81,7 @@ { "from": "Keyboard.Space", "to": "Actions.SHIFT" }, { "from": "Keyboard.R", "to": "Actions.ACTION1" }, - { "from": "Keyboard.T", "to": "Actions.ACTION2" } + { "from": "Keyboard.T", "to": "Actions.ACTION2" }, + { "from": "Keyboard.RightMouseClick", "to": "Actions.ContextMenu" } ] } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dc2eee000d..22f61a12e0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -635,6 +635,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : DependencyManager::get()->toggleMute(); } else if (action == controller::toInt(controller::Action::CYCLE_CAMERA)) { cycleCamera(); + } else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) { + VrMenu::toggle(); // show context menu even on non-stereo displays } } }); @@ -1789,9 +1791,7 @@ void Application::keyPressEvent(QKeyEvent* event) { void Application::keyReleaseEvent(QKeyEvent* event) { if (event->key() == Qt::Key_Alt && _altPressed && hasFocus()) { - if (getActiveDisplayPlugin()->isStereo()) { - VrMenu::toggle(); - } + VrMenu::toggle(); // show context menu even on non-stereo displays } _keysPressed.remove(event->key()); From cfb2fd1523c8c7ce027a720c4c5abe157fa788ef Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 27 Oct 2015 11:52:47 -0700 Subject: [PATCH 32/44] Support for runtime plugins (DLLs) --- CMakeLists.txt | 1 + cmake/externals/glew/CMakeLists.txt | 5 +- cmake/macros/SetupHifiPlugin.cmake | 33 +++++ interface/src/Application.cpp | 1 - interface/src/PluginContainerProxy.cpp | 1 - libraries/display-plugins/CMakeLists.txt | 7 +- .../AbstractHMDScriptingInterface.cpp | 5 +- .../Basic2DWindowOpenGLDisplayPlugin.cpp | 22 +-- .../src/display-plugins/DisplayPlugin.cpp | 12 -- .../src/display-plugins/DisplayPlugin.h | 131 +--------------- .../src/display-plugins/NullDisplayPlugin.cpp | 2 +- .../src/display-plugins/NullDisplayPlugin.h | 2 +- .../display-plugins/OpenGLDisplayPlugin.cpp | 1 + .../WindowOpenGLDisplayPlugin.cpp | 2 +- .../openvr/OpenVrDisplayPlugin.cpp | 4 +- .../stereo/StereoDisplayPlugin.cpp | 10 +- .../src/input-plugins/InputPlugin.h | 12 +- .../src/input-plugins/SixenseManager.cpp | 10 +- .../input-plugins/ViveControllerManager.cpp | 8 +- libraries/plugins/src/plugins/DisplayPlugin.h | 140 ++++++++++++++++++ libraries/plugins/src/plugins/Forward.h | 1 + libraries/plugins/src/plugins/InputPlugin.h | 23 +++ libraries/plugins/src/plugins/Plugin.cpp | 4 +- libraries/plugins/src/plugins/Plugin.h | 6 +- .../plugins/src/plugins/PluginManager.cpp | 73 ++++++++- libraries/plugins/src/plugins/PluginManager.h | 1 + libraries/plugins/src/plugins/RuntimePlugin.h | 36 +++++ plugins/CMakeLists.txt | 18 +++ plugins/oculus/CMakeLists.txt | 22 +++ .../oculus/src}/OculusBaseDisplayPlugin.cpp | 8 + .../oculus/src}/OculusBaseDisplayPlugin.h | 3 +- .../oculus/src}/OculusDebugDisplayPlugin.cpp | 0 .../oculus/src}/OculusDebugDisplayPlugin.h | 0 .../oculus/src}/OculusDisplayPlugin.cpp | 13 +- .../oculus/src}/OculusDisplayPlugin.h | 0 .../oculus/src}/OculusHelpers.cpp | 0 .../oculus/src}/OculusHelpers.h | 0 plugins/oculus/src/OculusProvider.cpp | 54 +++++++ plugins/oculus/src/oculus.json | 1 + plugins/oculusLegacy/CMakeLists.txt | 22 +++ plugins/oculusLegacy/src/OculusHelpers.cpp | 9 ++ plugins/oculusLegacy/src/OculusHelpers.h | 85 +++++++++++ .../src}/OculusLegacyDisplayPlugin.cpp | 34 +---- .../src}/OculusLegacyDisplayPlugin.h | 2 +- plugins/oculusLegacy/src/OculusProvider.cpp | 45 ++++++ plugins/oculusLegacy/src/oculus.json | 1 + tests/controllers/src/main.cpp | 3 - 47 files changed, 631 insertions(+), 242 deletions(-) create mode 100644 cmake/macros/SetupHifiPlugin.cmake create mode 100644 libraries/plugins/src/plugins/DisplayPlugin.h create mode 100644 libraries/plugins/src/plugins/InputPlugin.h create mode 100644 libraries/plugins/src/plugins/RuntimePlugin.h create mode 100644 plugins/CMakeLists.txt create mode 100644 plugins/oculus/CMakeLists.txt rename {libraries/display-plugins/src/display-plugins/oculus => plugins/oculus/src}/OculusBaseDisplayPlugin.cpp (95%) rename {libraries/display-plugins/src/display-plugins/oculus => plugins/oculus/src}/OculusBaseDisplayPlugin.h (96%) rename {libraries/display-plugins/src/display-plugins/oculus => plugins/oculus/src}/OculusDebugDisplayPlugin.cpp (100%) rename {libraries/display-plugins/src/display-plugins/oculus => plugins/oculus/src}/OculusDebugDisplayPlugin.h (100%) rename {libraries/display-plugins/src/display-plugins/oculus => plugins/oculus/src}/OculusDisplayPlugin.cpp (97%) rename {libraries/display-plugins/src/display-plugins/oculus => plugins/oculus/src}/OculusDisplayPlugin.h (100%) rename {libraries/display-plugins/src/display-plugins/oculus => plugins/oculus/src}/OculusHelpers.cpp (100%) rename {libraries/display-plugins/src/display-plugins/oculus => plugins/oculus/src}/OculusHelpers.h (100%) create mode 100644 plugins/oculus/src/OculusProvider.cpp create mode 100644 plugins/oculus/src/oculus.json create mode 100644 plugins/oculusLegacy/CMakeLists.txt create mode 100644 plugins/oculusLegacy/src/OculusHelpers.cpp create mode 100644 plugins/oculusLegacy/src/OculusHelpers.h rename {libraries/display-plugins/src/display-plugins/oculus => plugins/oculusLegacy/src}/OculusLegacyDisplayPlugin.cpp (90%) rename {libraries/display-plugins/src/display-plugins/oculus => plugins/oculusLegacy/src}/OculusLegacyDisplayPlugin.h (97%) create mode 100644 plugins/oculusLegacy/src/OculusProvider.cpp create mode 100644 plugins/oculusLegacy/src/oculus.json diff --git a/CMakeLists.txt b/CMakeLists.txt index efe99b550b..d1c69e4f6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,6 +203,7 @@ if (NOT ANDROID) add_subdirectory(interface) set_target_properties(interface PROPERTIES FOLDER "Apps") add_subdirectory(tests) + add_subdirectory(plugins) add_subdirectory(tools) endif () diff --git a/cmake/externals/glew/CMakeLists.txt b/cmake/externals/glew/CMakeLists.txt index 5f59cc2377..0a4a0abe71 100644 --- a/cmake/externals/glew/CMakeLists.txt +++ b/cmake/externals/glew/CMakeLists.txt @@ -7,14 +7,15 @@ endif () include(ExternalProject) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://hifi-public.s3.amazonaws.com/dependencies/glew_simple.zip - URL_MD5 0507dc08337a82a5e7ecbc5417f92cc1 + URL http://hifi-public.s3.amazonaws.com/dependencies/glew_simple2.zip + URL_MD5 f05d858e8203c32b689da208ad8b39db CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= LOG_DOWNLOAD 1 LOG_CONFIGURE 1 LOG_BUILD 1 ) + # Hide this external target (for ide users) set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") diff --git a/cmake/macros/SetupHifiPlugin.cmake b/cmake/macros/SetupHifiPlugin.cmake new file mode 100644 index 0000000000..0ee94c7816 --- /dev/null +++ b/cmake/macros/SetupHifiPlugin.cmake @@ -0,0 +1,33 @@ +# +# Created by Bradley Austin Davis on 2015/10/25 +# Copyright 2015 High Fidelity, Inc. +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html +# +macro(SETUP_HIFI_PLUGIN) + set(${TARGET_NAME}_SHARED 1) + setup_hifi_library(${ARGV}) + add_dependencies(interface ${TARGET_NAME}) + set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Plugins") + + if (APPLE) + set(PLUGIN_PATH "interface.app/Contents/MacOS/plugins") + else() + set(PLUGIN_PATH "plugins") + endif() + + # create the destination for the plugin binaries + add_custom_command( + TARGET ${TARGET_NAME} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory + "${CMAKE_BINARY_DIR}/interface/$/${PLUGIN_PATH}/" + ) + + add_custom_command(TARGET ${DIR} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy + "$" + "${CMAKE_BINARY_DIR}/interface/$/${PLUGIN_PATH}/" + ) + +endmacro() \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dc2eee000d..653f9cf906 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -392,7 +392,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _entityClipboard->createRootElement(); _pluginContainer = new PluginContainerProxy(); - Plugin::setContainer(_pluginContainer); #ifdef Q_OS_WIN installNativeEventFilter(&MyNativeEventFilter::getInstance()); #endif diff --git a/interface/src/PluginContainerProxy.cpp b/interface/src/PluginContainerProxy.cpp index 079d6d0bea..2e5c883897 100644 --- a/interface/src/PluginContainerProxy.cpp +++ b/interface/src/PluginContainerProxy.cpp @@ -13,7 +13,6 @@ #include "ui/DialogsManager.h" PluginContainerProxy::PluginContainerProxy() { - Plugin::setContainer(this); } PluginContainerProxy::~PluginContainerProxy() { diff --git a/libraries/display-plugins/CMakeLists.txt b/libraries/display-plugins/CMakeLists.txt index 14aa03de44..fad244fa5f 100644 --- a/libraries/display-plugins/CMakeLists.txt +++ b/libraries/display-plugins/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME display-plugins) setup_hifi_library(OpenGL) -link_hifi_libraries(shared plugins gpu gl) +link_hifi_libraries(shared plugins gl) target_opengl() @@ -8,11 +8,6 @@ GroupSources("src/display-plugins") target_oglplus() -add_dependency_external_projects(LibOVR) -find_package(LibOVR REQUIRED) -target_include_directories(${TARGET_NAME} PRIVATE ${LIBOVR_INCLUDE_DIRS}) -target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES}) - if (WIN32) add_dependency_external_projects(OpenVR) find_package(OpenVR REQUIRED) diff --git a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp index 9987ae345c..4b8d957e5f 100644 --- a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp +++ b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp @@ -12,7 +12,6 @@ #include "DisplayPlugin.h" #include -#include static Setting::Handle IPD_SCALE_HANDLE("hmd.ipdScale", 1.0f); @@ -26,12 +25,12 @@ float AbstractHMDScriptingInterface::getIPD() const { float AbstractHMDScriptingInterface::getEyeHeight() const { // FIXME update the display plugin interface to expose per-plugin settings - return OVR_DEFAULT_EYE_HEIGHT; + return getPlayerHeight() - 0.10f; } float AbstractHMDScriptingInterface::getPlayerHeight() const { // FIXME update the display plugin interface to expose per-plugin settings - return OVR_DEFAULT_PLAYER_HEIGHT; + return 1.755f; } float AbstractHMDScriptingInterface::getIPDScale() const { diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 914d30d58a..9366ec4403 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -35,36 +35,36 @@ QAction* _vsyncAction{ nullptr }; void Basic2DWindowOpenGLDisplayPlugin::activate() { _framerateActions.clear(); - CONTAINER->addMenuItem(MENU_PATH(), FULLSCREEN, + _container->addMenuItem(MENU_PATH(), FULLSCREEN, [this](bool clicked) { if (clicked) { - CONTAINER->setFullscreen(getFullscreenTarget()); + _container->setFullscreen(getFullscreenTarget()); } else { - CONTAINER->unsetFullscreen(); + _container->unsetFullscreen(); } }, true, false); - CONTAINER->addMenu(FRAMERATE); + _container->addMenu(FRAMERATE); _framerateActions.push_back( - CONTAINER->addMenuItem(FRAMERATE, FRAMERATE_UNLIMITED, + _container->addMenuItem(FRAMERATE, FRAMERATE_UNLIMITED, [this](bool) { updateFramerate(); }, true, true, FRAMERATE)); _framerateActions.push_back( - CONTAINER->addMenuItem(FRAMERATE, FRAMERATE_60, + _container->addMenuItem(FRAMERATE, FRAMERATE_60, [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); _framerateActions.push_back( - CONTAINER->addMenuItem(FRAMERATE, FRAMERATE_50, + _container->addMenuItem(FRAMERATE, FRAMERATE_50, [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); _framerateActions.push_back( - CONTAINER->addMenuItem(FRAMERATE, FRAMERATE_40, + _container->addMenuItem(FRAMERATE, FRAMERATE_40, [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); _framerateActions.push_back( - CONTAINER->addMenuItem(FRAMERATE, FRAMERATE_30, + _container->addMenuItem(FRAMERATE, FRAMERATE_30, [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); WindowOpenGLDisplayPlugin::activate(); // Vsync detection happens in the parent class activate, so we need to check after that if (_vsyncSupported) { - _vsyncAction = CONTAINER->addMenuItem(MENU_PATH(), VSYNC_ON, [this](bool) {}, true, true); + _vsyncAction = _container->addMenuItem(MENU_PATH(), VSYNC_ON, [this](bool) {}, true, true); } else { _vsyncAction = nullptr; } @@ -107,7 +107,7 @@ int Basic2DWindowOpenGLDisplayPlugin::getDesiredInterval() const { bool Basic2DWindowOpenGLDisplayPlugin::isThrottled() const { static const QString ThrottleFPSIfNotFocus = "Throttle FPS If Not Focus"; // FIXME - this value duplicated in Menu.h - bool shouldThrottle = (!CONTAINER->isForeground() && CONTAINER->isOptionChecked(ThrottleFPSIfNotFocus)); + bool shouldThrottle = (!_container->isForeground() && _container->isOptionChecked(ThrottleFPSIfNotFocus)); if (_isThrottled != shouldThrottle) { _isThrottled = shouldThrottle; diff --git a/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp index 4af45d299b..8155d69826 100644 --- a/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp @@ -15,9 +15,6 @@ #include "Basic2DWindowOpenGLDisplayPlugin.h" #include "openvr/OpenVrDisplayPlugin.h" -#include "oculus/OculusDisplayPlugin.h" -#include "oculus/OculusDebugDisplayPlugin.h" -#include "oculus/OculusLegacyDisplayPlugin.h" const QString& DisplayPlugin::MENU_PATH() { static const QString value = "Display"; @@ -40,15 +37,6 @@ DisplayPluginList getDisplayPlugins() { new InterleavedStereoDisplayPlugin(), // HMDs - - // Windows Oculus SDK - new OculusDisplayPlugin(), - // Windows Oculus Simulator... uses head tracking and the same rendering - // as the connected hardware, but without using the SDK to display to the - // Rift. Useful for debugging Rift performance with nSight. - new OculusDebugDisplayPlugin(), - // Mac/Linux Oculus SDK (0.5) - new OculusLegacyDisplayPlugin(), #ifdef Q_OS_WIN // SteamVR SDK new OpenVrDisplayPlugin(), diff --git a/libraries/display-plugins/src/display-plugins/DisplayPlugin.h b/libraries/display-plugins/src/display-plugins/DisplayPlugin.h index b2176e0bd1..84c6592c53 100644 --- a/libraries/display-plugins/src/display-plugins/DisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/DisplayPlugin.h @@ -5,135 +5,6 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#pragma once -#include "plugins/Plugin.h" -#include -#include -#include - -#include -#include - -#include -#include -#include - -enum Eye { - Left, - Right, - Mono -}; - -/* - * Helper method to iterate over each eye - */ -template -void for_each_eye(F f) { - f(Left); - f(Right); -} - -/* - * Helper method to iterate over each eye, with an additional lambda to take action between the eyes - */ -template -void for_each_eye(F f, FF ff) { - f(Eye::Left); - ff(); - f(Eye::Right); -} - -class QWindow; - -#define AVERAGE_HUMAN_IPD 0.064f - -class DisplayPlugin : public Plugin { - Q_OBJECT -public: - virtual bool isHmd() const { return false; } - virtual int getHmdScreen() const { return -1; } - /// By default, all HMDs are stereo - virtual bool isStereo() const { return isHmd(); } - virtual bool isThrottled() const { return false; } - - // Rendering support - - // Stop requesting renders, but don't do full deactivation - // needed to work around the issues caused by Oculus - // processing messages in the middle of submitFrame - virtual void stop() = 0; - - /** - * Called by the application before the frame rendering. Can be used for - * render timing related calls (for instance, the Oculus begin frame timing - * call) - */ - virtual void preRender() = 0; - /** - * Called by the application immediately before calling the display function. - * For OpenGL based plugins, this is the best place to put activate the output - * OpenGL context - */ - virtual void preDisplay() = 0; - - /** - * Sends the scene texture to the display plugin. - */ - virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize) = 0; - - /** - * Called by the application immeidately after display. For OpenGL based - * displays, this is the best place to put the buffer swap - */ - virtual void finishFrame() = 0; - - // Does the rendering surface have current focus? - virtual bool hasFocus() const = 0; - - // The size of the rendering target (may be larger than the device size due to distortion) - virtual glm::uvec2 getRecommendedRenderSize() const = 0; - - // The size of the UI - virtual glm::uvec2 getRecommendedUiSize() const { - return getRecommendedRenderSize(); - } - - // By default the aspect ratio is just the render size - virtual float getRecommendedAspectRatio() const { - return aspect(getRecommendedRenderSize()); - } - - // Stereo specific methods - virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const { - return baseProjection; - } - - // HMD specific methods - // TODO move these into another class? - virtual glm::mat4 getEyeToHeadTransform(Eye eye) const { - static const glm::mat4 transform; return transform; - } - - virtual glm::mat4 getHeadPose() const { - static const glm::mat4 pose; return pose; - } - - // Needed for timewarp style features - virtual void setEyeRenderPose(Eye eye, const glm::mat4& pose) { - // NOOP - } - - virtual float getIPD() const { return AVERAGE_HUMAN_IPD; } - - virtual void abandonCalibration() {} - virtual void resetSensors() {} - virtual float devicePixelRatio() { return 1.0; } - - - static const QString& MENU_PATH(); -signals: - void recommendedFramebufferSizeChanged(const QSize & size); - void requestRender(); -}; +#include diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp index 914f80d983..ce512962ff 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp @@ -25,6 +25,6 @@ bool NullDisplayPlugin::hasFocus() const { void NullDisplayPlugin::preRender() {} void NullDisplayPlugin::preDisplay() {} -void NullDisplayPlugin::display(GLuint sceneTexture, const glm::uvec2& sceneSize) {} +void NullDisplayPlugin::display(uint32_t sceneTexture, const glm::uvec2& sceneSize) {} void NullDisplayPlugin::finishFrame() {} void NullDisplayPlugin::stop() {} diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h index 4f2cc77b8f..8cd5c2bc37 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h @@ -21,7 +21,7 @@ public: virtual bool hasFocus() const override; virtual void preRender() override; virtual void preDisplay() override; - virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize) override; + virtual void display(uint32_t sceneTexture, const glm::uvec2& sceneSize) override; virtual void finishFrame() override; private: diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 3791375c9e..3ef882fe76 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include diff --git a/libraries/display-plugins/src/display-plugins/WindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/WindowOpenGLDisplayPlugin.cpp index ffea6605af..6ddc791503 100644 --- a/libraries/display-plugins/src/display-plugins/WindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/WindowOpenGLDisplayPlugin.cpp @@ -42,7 +42,7 @@ bool WindowOpenGLDisplayPlugin::hasFocus() const { void WindowOpenGLDisplayPlugin::activate() { OpenGLDisplayPlugin::activate(); - _window = CONTAINER->getPrimarySurface(); + _window = _container->getPrimarySurface(); _window->makeCurrent(); customizeContext(); _window->doneCurrent(); diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp index 245fd11ef7..174bf1bf36 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp @@ -89,7 +89,7 @@ bool OpenVrDisplayPlugin::isSupported() const { } void OpenVrDisplayPlugin::activate() { - CONTAINER->setIsOptionChecked(StandingHMDSensorMode, true); + _container->setIsOptionChecked(StandingHMDSensorMode, true); hmdRefCount++; vr::HmdError eError = vr::HmdError_None; @@ -132,7 +132,7 @@ void OpenVrDisplayPlugin::activate() { } void OpenVrDisplayPlugin::deactivate() { - CONTAINER->setIsOptionChecked(StandingHMDSensorMode, false); + _container->setIsOptionChecked(StandingHMDSensorMode, false); hmdRefCount--; diff --git a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp index 4f7b0a1a78..f7e71313df 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp @@ -74,21 +74,21 @@ void StereoDisplayPlugin::activate() { if (screen == qApp->primaryScreen()) { checked = true; } - auto action = CONTAINER->addMenuItem(MENU_PATH(), name, + auto action = _container->addMenuItem(MENU_PATH(), name, [this](bool clicked) { updateScreen(); }, true, checked, "Screens"); _screenActions[i] = action; } - CONTAINER->removeMenu(FRAMERATE); + _container->removeMenu(FRAMERATE); - CONTAINER->setFullscreen(qApp->primaryScreen()); + _container->setFullscreen(qApp->primaryScreen()); WindowOpenGLDisplayPlugin::activate(); } void StereoDisplayPlugin::updateScreen() { for (uint32_t i = 0; i < _screenActions.size(); ++i) { if (_screenActions[i]->isChecked()) { - CONTAINER->setFullscreen(qApp->screens().at(i)); + _container->setFullscreen(qApp->screens().at(i)); break; } } @@ -96,7 +96,7 @@ void StereoDisplayPlugin::updateScreen() { void StereoDisplayPlugin::deactivate() { _screenActions.clear(); - CONTAINER->unsetFullscreen(); + _container->unsetFullscreen(); WindowOpenGLDisplayPlugin::deactivate(); } diff --git a/libraries/input-plugins/src/input-plugins/InputPlugin.h b/libraries/input-plugins/src/input-plugins/InputPlugin.h index 787922e04c..d03f884ec7 100644 --- a/libraries/input-plugins/src/input-plugins/InputPlugin.h +++ b/libraries/input-plugins/src/input-plugins/InputPlugin.h @@ -10,14 +10,4 @@ // #pragma once -#include - -class InputPlugin : public Plugin { -public: - virtual bool isJointController() const = 0; - - virtual void pluginFocusOutEvent() = 0; - - virtual void pluginUpdate(float deltaTime, bool jointsCaptured) = 0; -}; - +#include diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp index 5e0f3277b1..024eb86182 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp +++ b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp @@ -94,8 +94,8 @@ void SixenseManager::activate() { _calibrationState = CALIBRATION_STATE_IDLE; _avatarPosition = DEFAULT_AVATAR_POSITION; - CONTAINER->addMenu(MENU_PATH); - CONTAINER->addMenuItem(MENU_PATH, TOGGLE_SMOOTH, + _container->addMenu(MENU_PATH); + _container->addMenuItem(MENU_PATH, TOGGLE_SMOOTH, [this] (bool clicked) { this->setSixenseFilter(clicked); }, true, true); @@ -136,8 +136,8 @@ void SixenseManager::deactivate() { InputPlugin::deactivate(); #ifdef HAVE_SIXENSE - CONTAINER->removeMenuItem(MENU_NAME, TOGGLE_SMOOTH); - CONTAINER->removeMenu(MENU_PATH); + _container->removeMenuItem(MENU_NAME, TOGGLE_SMOOTH); + _container->removeMenu(MENU_PATH); _poseStateMap.clear(); _collectedSamples.clear(); @@ -319,7 +319,7 @@ void SixenseManager::updateCalibration(void* controllersX) { _avatarRotation = glm::inverse(glm::quat_cast(glm::mat3(xAxis, Vectors::UNIT_Y, zAxis))); const float Y_OFFSET_CALIBRATED_HANDS_TO_AVATAR = -0.3f; _avatarPosition.y += Y_OFFSET_CALIBRATED_HANDS_TO_AVATAR; - CONTAINER->requestReset(); + _container->requestReset(); qCDebug(inputplugins, "succeess: sixense calibration"); } break; diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp index e90006e014..69b2b5b2c6 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp +++ b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp @@ -75,8 +75,8 @@ bool ViveControllerManager::isSupported() const { void ViveControllerManager::activate() { InputPlugin::activate(); #ifdef Q_OS_WIN - CONTAINER->addMenu(MENU_PATH); - CONTAINER->addMenuItem(MENU_PATH, RENDER_CONTROLLERS, + _container->addMenu(MENU_PATH); + _container->addMenuItem(MENU_PATH, RENDER_CONTROLLERS, [this] (bool clicked) { this->setRenderControllers(clicked); }, true, true); @@ -146,8 +146,8 @@ void ViveControllerManager::deactivate() { InputPlugin::deactivate(); #ifdef Q_OS_WIN - CONTAINER->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS); - CONTAINER->removeMenu(MENU_PATH); + _container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS); + _container->removeMenu(MENU_PATH); hmdRefCount--; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h new file mode 100644 index 0000000000..5b00391f09 --- /dev/null +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -0,0 +1,140 @@ +// +// Created by Bradley Austin Davis on 2015/05/29 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#pragma once + +#include + +#include +#include + +#include +#include + +#include +#include + +#include "Plugin.h" + +enum Eye { + Left, + Right, + Mono +}; + +/* + * Helper method to iterate over each eye + */ +template +void for_each_eye(F f) { + f(Left); + f(Right); +} + +/* + * Helper method to iterate over each eye, with an additional lambda to take action between the eyes + */ +template +void for_each_eye(F f, FF ff) { + f(Eye::Left); + ff(); + f(Eye::Right); +} + +class QWindow; + +#define AVERAGE_HUMAN_IPD 0.064f + +class DisplayPlugin : public Plugin { + Q_OBJECT +public: + virtual bool isHmd() const { return false; } + virtual int getHmdScreen() const { return -1; } + /// By default, all HMDs are stereo + virtual bool isStereo() const { return isHmd(); } + virtual bool isThrottled() const { return false; } + + // Rendering support + + // Stop requesting renders, but don't do full deactivation + // needed to work around the issues caused by Oculus + // processing messages in the middle of submitFrame + virtual void stop() = 0; + + /** + * Called by the application before the frame rendering. Can be used for + * render timing related calls (for instance, the Oculus begin frame timing + * call) + */ + virtual void preRender() = 0; + /** + * Called by the application immediately before calling the display function. + * For OpenGL based plugins, this is the best place to put activate the output + * OpenGL context + */ + virtual void preDisplay() = 0; + + /** + * Sends the scene texture to the display plugin. + */ + virtual void display(uint32_t sceneTexture, const glm::uvec2& sceneSize) = 0; + + /** + * Called by the application immeidately after display. For OpenGL based + * displays, this is the best place to put the buffer swap + */ + virtual void finishFrame() = 0; + + // Does the rendering surface have current focus? + virtual bool hasFocus() const = 0; + + // The size of the rendering target (may be larger than the device size due to distortion) + virtual glm::uvec2 getRecommendedRenderSize() const = 0; + + // The size of the UI + virtual glm::uvec2 getRecommendedUiSize() const { + return getRecommendedRenderSize(); + } + + // By default the aspect ratio is just the render size + virtual float getRecommendedAspectRatio() const { + return aspect(getRecommendedRenderSize()); + } + + // Stereo specific methods + virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const { + return baseProjection; + } + + // HMD specific methods + // TODO move these into another class? + virtual glm::mat4 getEyeToHeadTransform(Eye eye) const { + static const glm::mat4 transform; return transform; + } + + virtual glm::mat4 getHeadPose() const { + static const glm::mat4 pose; return pose; + } + + // Needed for timewarp style features + virtual void setEyeRenderPose(Eye eye, const glm::mat4& pose) { + // NOOP + } + + virtual float getIPD() const { return AVERAGE_HUMAN_IPD; } + + virtual void abandonCalibration() {} + virtual void resetSensors() {} + virtual float devicePixelRatio() { return 1.0; } + + + static const QString& MENU_PATH(); +signals: + void recommendedFramebufferSizeChanged(const QSize & size); + void requestRender(); +}; + diff --git a/libraries/plugins/src/plugins/Forward.h b/libraries/plugins/src/plugins/Forward.h index 1a9298d13c..78ec8fdcb3 100644 --- a/libraries/plugins/src/plugins/Forward.h +++ b/libraries/plugins/src/plugins/Forward.h @@ -21,3 +21,4 @@ using DisplayPluginPointer = QSharedPointer; using DisplayPluginList = QVector; using InputPluginPointer = QSharedPointer; using InputPluginList = QVector; + diff --git a/libraries/plugins/src/plugins/InputPlugin.h b/libraries/plugins/src/plugins/InputPlugin.h new file mode 100644 index 0000000000..e9d8ac8d86 --- /dev/null +++ b/libraries/plugins/src/plugins/InputPlugin.h @@ -0,0 +1,23 @@ +// +// InputPlugin.h +// input-plugins/src/input-plugins +// +// Created by Sam Gondelman on 7/13/2015 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#pragma once + +#include "Plugin.h" + +class InputPlugin : public Plugin { +public: + virtual bool isJointController() const = 0; + + virtual void pluginFocusOutEvent() = 0; + + virtual void pluginUpdate(float deltaTime, bool jointsCaptured) = 0; +}; + diff --git a/libraries/plugins/src/plugins/Plugin.cpp b/libraries/plugins/src/plugins/Plugin.cpp index 2c0b9fa5cf..7c30f252c9 100644 --- a/libraries/plugins/src/plugins/Plugin.cpp +++ b/libraries/plugins/src/plugins/Plugin.cpp @@ -7,12 +7,10 @@ // #include "Plugin.h" -PluginContainer* Plugin::CONTAINER{ nullptr }; - QString Plugin::UNKNOWN_PLUGIN_ID("unknown"); void Plugin::setContainer(PluginContainer* container) { - CONTAINER = container; + _container = container; } bool Plugin::isSupported() const { return true; } diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index f53d309e97..c030b1073f 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -24,7 +24,7 @@ public: virtual bool isSupported() const; - static void setContainer(PluginContainer* container); + void setContainer(PluginContainer* container); /// Called when plugin is initially loaded, typically at application start virtual void init(); @@ -57,8 +57,8 @@ public: virtual void loadSettings() {} protected: - bool _active{ false }; - static PluginContainer* CONTAINER; + bool _active { false }; + PluginContainer* _container { nullptr }; static QString UNKNOWN_PLUGIN_ID; }; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index 2deb41fb13..27e326fcba 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -6,15 +6,54 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "PluginManager.h" + #include -#include "Forward.h" +#include +#include +#include +#include + +#include "RuntimePlugin.h" +#include "DisplayPlugin.h" +#include "InputPlugin.h" +#include "PluginContainer.h" + PluginManager* PluginManager::getInstance() { static PluginManager _manager; return &_manager; } +using Loader = QSharedPointer; +using LoaderList = QList; + +const LoaderList& getLoadedPlugins() { + static std::once_flag once; + static LoaderList loadedPlugins; + std::call_once(once, [&] { + QString pluginPath = QCoreApplication::applicationDirPath() + "/plugins/"; + QDir pluginDir(pluginPath); + pluginDir.setFilter(QDir::Files); + if (pluginDir.exists()) { + qDebug() << "Loading runtime plugins from " << pluginPath; + auto candidates = pluginDir.entryList(); + for (auto plugin : candidates) { + qDebug() << "Attempting plugins " << plugin; + QSharedPointer loader(new QPluginLoader(pluginPath + plugin)); + if (loader->load()) { + qDebug() << "Plugins " << plugin << " success"; + loadedPlugins.push_back(loader); + } + } + } + }); + return loadedPlugins; +} + +PluginManager::PluginManager() { +} + // TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class extern DisplayPluginList getDisplayPlugins(); extern InputPluginList getInputPlugins(); @@ -23,8 +62,25 @@ extern void saveInputPluginSettings(const InputPluginList& plugins); const DisplayPluginList& PluginManager::getDisplayPlugins() { static DisplayPluginList displayPlugins; static std::once_flag once; + std::call_once(once, [&] { + // Grab the built in plugins displayPlugins = ::getDisplayPlugins(); + + // Now grab the dynamic plugins + for (auto loader : getLoadedPlugins()) { + DisplayProvider* displayProvider = qobject_cast(loader->instance()); + if (displayProvider) { + for (auto displayPlugin : displayProvider->getDisplayPlugins()) { + displayPlugins.push_back(displayPlugin); + } + } + } + auto& container = PluginContainer::getInstance(); + for (auto plugin : displayPlugins) { + plugin->setContainer(&container); + } + }); return displayPlugins; } @@ -34,6 +90,21 @@ const InputPluginList& PluginManager::getInputPlugins() { static std::once_flag once; std::call_once(once, [&] { inputPlugins = ::getInputPlugins(); + + // Now grab the dynamic plugins + for (auto loader : getLoadedPlugins()) { + InputProvider* inputProvider = qobject_cast(loader->instance()); + if (inputProvider) { + for (auto inputPlugin : inputProvider->getInputPlugins()) { + inputPlugins.push_back(inputPlugin); + } + } + } + + auto& container = PluginContainer::getInstance(); + for (auto plugin : inputPlugins) { + plugin->setContainer(&container); + } }); return inputPlugins; } diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index 09dcc9d107..17619a93c0 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -12,6 +12,7 @@ class PluginManager : public QObject { public: static PluginManager* getInstance(); + PluginManager(); const DisplayPluginList& getDisplayPlugins(); const InputPluginList& getInputPlugins(); diff --git a/libraries/plugins/src/plugins/RuntimePlugin.h b/libraries/plugins/src/plugins/RuntimePlugin.h new file mode 100644 index 0000000000..d7bf31ea28 --- /dev/null +++ b/libraries/plugins/src/plugins/RuntimePlugin.h @@ -0,0 +1,36 @@ +// +// Created by Bradley Austin Davis on 2015/10/24 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#pragma once + +#include + +#include +#include + +#include "Forward.h" + +class DisplayProvider { +public: + virtual ~DisplayProvider() {} + + virtual DisplayPluginList getDisplayPlugins() = 0; +}; + +#define DisplayProvider_iid "com.highfidelity.plugins.display" +Q_DECLARE_INTERFACE(DisplayProvider, DisplayProvider_iid) + + +class InputProvider { +public: + virtual ~InputProvider() {} + virtual InputPluginList getInputPlugins() = 0; +}; + +#define InputProvider_iid "com.highfidelity.plugins.input" +Q_DECLARE_INTERFACE(InputProvider, InputProvider_iid) + diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt new file mode 100644 index 0000000000..55b18b122c --- /dev/null +++ b/plugins/CMakeLists.txt @@ -0,0 +1,18 @@ +# +# Created by Bradley Austin Davis on 2015/10/25 +# Copyright 2015 High Fidelity, Inc. +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html +# + +# add the plugin directories +file(GLOB PLUGIN_SUBDIRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*") +list(REMOVE_ITEM PLUGIN_SUBDIRS "CMakeFiles") + +foreach(DIR ${PLUGIN_SUBDIRS}) + if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${DIR}") + add_subdirectory(${DIR}) + endif() +endforeach() + diff --git a/plugins/oculus/CMakeLists.txt b/plugins/oculus/CMakeLists.txt new file mode 100644 index 0000000000..62999cbb7e --- /dev/null +++ b/plugins/oculus/CMakeLists.txt @@ -0,0 +1,22 @@ +# +# Created by Bradley Austin Davis on 2015/10/25 +# Copyright 2015 High Fidelity, Inc. +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html +# + +if (WIN32) + + set(TARGET_NAME oculus) + setup_hifi_plugin() + link_hifi_libraries(shared gl plugins display-plugins) + + include_hifi_library_headers(octree) + + add_dependency_external_projects(LibOVR) + find_package(LibOVR REQUIRED) + target_include_directories(${TARGET_NAME} PRIVATE ${LIBOVR_INCLUDE_DIRS}) + target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES}) + +endif() \ No newline at end of file diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp similarity index 95% rename from libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp rename to plugins/oculus/src/OculusBaseDisplayPlugin.cpp index 859a4a810a..4c80b9a51d 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -61,6 +61,14 @@ bool OculusBaseDisplayPlugin::isSupported() const { #endif } +// DLL based display plugins MUST initialize GLEW inside the DLL code. +void OculusBaseDisplayPlugin::customizeContext() { + glewExperimental = true; + GLenum err = glewInit(); + glGetError(); + WindowOpenGLDisplayPlugin::customizeContext(); +} + void OculusBaseDisplayPlugin::init() { } diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h similarity index 96% rename from libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h rename to plugins/oculus/src/OculusBaseDisplayPlugin.h index 6307f6bbf9..ba1924bfff 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -7,7 +7,7 @@ // #pragma once -#include "../WindowOpenGLDisplayPlugin.h" +#include #include @@ -35,6 +35,7 @@ public: virtual float getIPD() const override final; protected: + virtual void customizeContext() override; virtual void preRender() override final; virtual void display(GLuint finalTexture, const glm::uvec2& sceneSize) override; diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusDebugDisplayPlugin.cpp b/plugins/oculus/src/OculusDebugDisplayPlugin.cpp similarity index 100% rename from libraries/display-plugins/src/display-plugins/oculus/OculusDebugDisplayPlugin.cpp rename to plugins/oculus/src/OculusDebugDisplayPlugin.cpp diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusDebugDisplayPlugin.h b/plugins/oculus/src/OculusDebugDisplayPlugin.h similarity index 100% rename from libraries/display-plugins/src/display-plugins/oculus/OculusDebugDisplayPlugin.h rename to plugins/oculus/src/OculusDebugDisplayPlugin.h diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp similarity index 97% rename from libraries/display-plugins/src/display-plugins/oculus/OculusDisplayPlugin.cpp rename to plugins/oculus/src/OculusDisplayPlugin.cpp index 3e2290f104..923b8bde6e 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -7,11 +7,14 @@ // #include "OculusDisplayPlugin.h" -#include +#include + +// FIXME get rid of this +#include +#include #include "OculusHelpers.h" -#include #if (OVR_MAJOR_VERSION >= 6) @@ -142,16 +145,16 @@ static const QString FRAMERATE = DisplayPlugin::MENU_PATH() + ">Framerate"; void OculusDisplayPlugin::activate() { - CONTAINER->addMenuItem(MENU_PATH(), MONO_PREVIEW, + _container->addMenuItem(MENU_PATH(), MONO_PREVIEW, [this](bool clicked) { _monoPreview = clicked; }, true, true); - CONTAINER->removeMenu(FRAMERATE); + _container->removeMenu(FRAMERATE); OculusBaseDisplayPlugin::activate(); } void OculusDisplayPlugin::customizeContext() { - WindowOpenGLDisplayPlugin::customizeContext(); + OculusBaseDisplayPlugin::customizeContext(); #if (OVR_MAJOR_VERSION >= 6) _sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_hmd)); _sceneFbo->Init(getRecommendedRenderSize()); diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h similarity index 100% rename from libraries/display-plugins/src/display-plugins/oculus/OculusDisplayPlugin.h rename to plugins/oculus/src/OculusDisplayPlugin.h diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusHelpers.cpp b/plugins/oculus/src/OculusHelpers.cpp similarity index 100% rename from libraries/display-plugins/src/display-plugins/oculus/OculusHelpers.cpp rename to plugins/oculus/src/OculusHelpers.cpp diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusHelpers.h b/plugins/oculus/src/OculusHelpers.h similarity index 100% rename from libraries/display-plugins/src/display-plugins/oculus/OculusHelpers.h rename to plugins/oculus/src/OculusHelpers.h diff --git a/plugins/oculus/src/OculusProvider.cpp b/plugins/oculus/src/OculusProvider.cpp new file mode 100644 index 0000000000..40dfb9df9a --- /dev/null +++ b/plugins/oculus/src/OculusProvider.cpp @@ -0,0 +1,54 @@ +// +// Created by Bradley Austin Davis on 2015/10/25 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include +#include +#include + +#include +#include + +#include "OculusDisplayPlugin.h" +#include "OculusDebugDisplayPlugin.h" + +class OculusProvider : public QObject, public DisplayProvider +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DisplayProvider_iid FILE "oculus.json") + Q_INTERFACES(DisplayProvider) + +public: + OculusProvider(QObject* parent = nullptr) : QObject(parent) {} + virtual ~OculusProvider() {} + + virtual DisplayPluginList getDisplayPlugins() override { + static std::once_flag once; + std::call_once(once, [&] { + DisplayPluginPointer plugin(new OculusDisplayPlugin()); + if (plugin->isSupported()) { + _displayPlugins.push_back(plugin); + } + + // Windows Oculus Simulator... uses head tracking and the same rendering + // as the connected hardware, but without using the SDK to display to the + // Rift. Useful for debugging Rift performance with nSight. + plugin = DisplayPluginPointer(new OculusDebugDisplayPlugin()); + if (plugin->isSupported()) { + _displayPlugins.push_back(plugin); + } + }); + return _displayPlugins; + } + +private: + DisplayPluginList _displayPlugins; +}; + +#include "OculusProvider.moc" diff --git a/plugins/oculus/src/oculus.json b/plugins/oculus/src/oculus.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/plugins/oculus/src/oculus.json @@ -0,0 +1 @@ +{} diff --git a/plugins/oculusLegacy/CMakeLists.txt b/plugins/oculusLegacy/CMakeLists.txt new file mode 100644 index 0000000000..bf9d22410d --- /dev/null +++ b/plugins/oculusLegacy/CMakeLists.txt @@ -0,0 +1,22 @@ +# +# Created by Bradley Austin Davis on 2015/10/25 +# Copyright 2015 High Fidelity, Inc. +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html +# + +if (NOT WIN32) + + set(TARGET_NAME oculusLegacy) + setup_hifi_plugin() + link_hifi_libraries(shared gl plugins display-plugins) + + include_hifi_library_headers(octree) + + add_dependency_external_projects(LibOVR) + find_package(LibOVR REQUIRED) + target_include_directories(${TARGET_NAME} PRIVATE ${LIBOVR_INCLUDE_DIRS}) + target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES}) + +endif() \ No newline at end of file diff --git a/plugins/oculusLegacy/src/OculusHelpers.cpp b/plugins/oculusLegacy/src/OculusHelpers.cpp new file mode 100644 index 0000000000..fff2a38344 --- /dev/null +++ b/plugins/oculusLegacy/src/OculusHelpers.cpp @@ -0,0 +1,9 @@ +// +// Created by Bradley Austin Davis on 2015/08/08 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "OculusHelpers.h" diff --git a/plugins/oculusLegacy/src/OculusHelpers.h b/plugins/oculusLegacy/src/OculusHelpers.h new file mode 100644 index 0000000000..b4bcdc1511 --- /dev/null +++ b/plugins/oculusLegacy/src/OculusHelpers.h @@ -0,0 +1,85 @@ +// +// Created by Bradley Austin Davis on 2015/05/26 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#pragma once + +#include +#include +#include +#include + +// Convenience method for looping over each eye with a lambda +template +inline void ovr_for_each_eye(Function function) { + for (ovrEyeType eye = ovrEyeType::ovrEye_Left; + eye < ovrEyeType::ovrEye_Count; + eye = static_cast(eye + 1)) { + function(eye); + } +} + +inline glm::mat4 toGlm(const ovrMatrix4f & om) { + return glm::transpose(glm::make_mat4(&om.M[0][0])); +} + +inline glm::mat4 toGlm(const ovrFovPort & fovport, float nearPlane = 0.01f, float farPlane = 10000.0f) { + return toGlm(ovrMatrix4f_Projection(fovport, nearPlane, farPlane, true)); +} + +inline glm::vec3 toGlm(const ovrVector3f & ov) { + return glm::make_vec3(&ov.x); +} + +inline glm::vec2 toGlm(const ovrVector2f & ov) { + return glm::make_vec2(&ov.x); +} + +inline glm::uvec2 toGlm(const ovrSizei & ov) { + return glm::uvec2(ov.w, ov.h); +} + +inline glm::quat toGlm(const ovrQuatf & oq) { + return glm::make_quat(&oq.x); +} + +inline glm::mat4 toGlm(const ovrPosef & op) { + glm::mat4 orientation = glm::mat4_cast(toGlm(op.Orientation)); + glm::mat4 translation = glm::translate(glm::mat4(), toGlm(op.Position)); + return translation * orientation; +} + +inline ovrMatrix4f ovrFromGlm(const glm::mat4 & m) { + ovrMatrix4f result; + glm::mat4 transposed(glm::transpose(m)); + memcpy(result.M, &(transposed[0][0]), sizeof(float) * 16); + return result; +} + +inline ovrVector3f ovrFromGlm(const glm::vec3 & v) { + return{ v.x, v.y, v.z }; +} + +inline ovrVector2f ovrFromGlm(const glm::vec2 & v) { + return{ v.x, v.y }; +} + +inline ovrSizei ovrFromGlm(const glm::uvec2 & v) { + return{ (int)v.x, (int)v.y }; +} + +inline ovrQuatf ovrFromGlm(const glm::quat & q) { + return{ q.x, q.y, q.z, q.w }; +} + +inline ovrPosef ovrPoseFromGlm(const glm::mat4 & m) { + glm::vec3 translation = glm::vec3(m[3]) / m[3].w; + glm::quat orientation = glm::quat_cast(m); + ovrPosef result; + result.Orientation = ovrFromGlm(orientation); + result.Position = ovrFromGlm(translation); + return result; +} diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp similarity index 90% rename from libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp rename to plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp index 205444397f..5a253cdbbf 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp @@ -42,10 +42,8 @@ uvec2 OculusLegacyDisplayPlugin::getRecommendedRenderSize() const { } void OculusLegacyDisplayPlugin::preRender() { -#if (OVR_MAJOR_VERSION == 5) ovrHmd_GetEyePoses(_hmd, _frameIndex, _eyeOffsets, _eyePoses, &_trackingState); ovrHmd_BeginFrame(_hmd, _frameIndex); -#endif WindowOpenGLDisplayPlugin::preRender(); } @@ -54,32 +52,21 @@ glm::mat4 OculusLegacyDisplayPlugin::getProjection(Eye eye, const glm::mat4& bas } void OculusLegacyDisplayPlugin::resetSensors() { -#if (OVR_MAJOR_VERSION == 5) ovrHmd_RecenterPose(_hmd); -#endif } glm::mat4 OculusLegacyDisplayPlugin::getEyeToHeadTransform(Eye eye) const { -#if (OVR_MAJOR_VERSION == 5) return toGlm(_eyePoses[eye]); -#else - return WindowOpenGLDisplayPlugin::getEyeToHeadTransform(eye); -#endif } // Should NOT be used for rendering as this will mess up timewarp. Use the getModelview() method above for // any use of head poses for rendering, ensuring you use the correct eye glm::mat4 OculusLegacyDisplayPlugin::getHeadPose() const { -#if (OVR_MAJOR_VERSION == 5) return toGlm(_trackingState.HeadPose.ThePose); -#else - return WindowOpenGLDisplayPlugin::getHeadPose(); -#endif } bool OculusLegacyDisplayPlugin::isSupported() const { -#if (OVR_MAJOR_VERSION == 5) if (!ovr_Initialize(nullptr)) { return false; } @@ -104,14 +91,10 @@ bool OculusLegacyDisplayPlugin::isSupported() const { ovr_Shutdown(); return result; -#else - return false; -#endif } void OculusLegacyDisplayPlugin::activate() { -#if (OVR_MAJOR_VERSION == 5) - if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { + if (!(ovr_Initialize(nullptr))) { Q_ASSERT(false); qFatal("Failed to Initialize SDK"); } @@ -149,8 +132,8 @@ void OculusLegacyDisplayPlugin::activate() { _frameIndex = 0; - if (!OVR_SUCCESS(ovrHmd_ConfigureTracking(_hmd, - ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) { + if (!ovrHmd_ConfigureTracking(_hmd, + ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0)) { qFatal("Could not attach to sensor device"); } @@ -158,7 +141,7 @@ void OculusLegacyDisplayPlugin::activate() { int screen = getHmdScreen(); if (screen != -1) { - CONTAINER->setFullscreen(qApp->screens()[screen]); + _container->setFullscreen(qApp->screens()[screen]); } _window->installEventFilter(this); @@ -189,11 +172,9 @@ void OculusLegacyDisplayPlugin::activate() { #endif ovrHmd_ConfigureRendering(_hmd, &config.Config, distortionCaps, _eyeFovs, _eyeRenderDescs); Q_ASSERT(result); -#endif } void OculusLegacyDisplayPlugin::deactivate() { -#if (OVR_MAJOR_VERSION == 5) _window->removeEventFilter(this); WindowOpenGLDisplayPlugin::deactivate(); @@ -202,12 +183,11 @@ void OculusLegacyDisplayPlugin::deactivate() { if (_hmdScreen >= 0) { riftScreen = qApp->screens()[_hmdScreen]; } - CONTAINER->unsetFullscreen(riftScreen); + _container->unsetFullscreen(riftScreen); ovrHmd_Destroy(_hmd); _hmd = nullptr; ovr_Shutdown(); -#endif } void OculusLegacyDisplayPlugin::preDisplay() { @@ -216,17 +196,14 @@ void OculusLegacyDisplayPlugin::preDisplay() { void OculusLegacyDisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSize) { ++_frameIndex; -#if (OVR_MAJOR_VERSION == 5) ovr_for_each_eye([&](ovrEyeType eye) { reinterpret_cast(_eyeTextures[eye]).OGL.TexId = finalTexture; }); ovrHmd_EndFrame(_hmd, _eyePoses, _eyeTextures); -#endif } // Pass input events on to the application bool OculusLegacyDisplayPlugin::eventFilter(QObject* receiver, QEvent* event) { -#if (OVR_MAJOR_VERSION == 5) if (!_hswDismissed && (event->type() == QEvent::KeyPress)) { static ovrHSWDisplayState hswState; ovrHmd_GetHSWDisplayState(_hmd, &hswState); @@ -236,7 +213,6 @@ bool OculusLegacyDisplayPlugin::eventFilter(QObject* receiver, QEvent* event) { _hswDismissed = true; } } -#endif return WindowOpenGLDisplayPlugin::eventFilter(receiver, event); } diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.h b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h similarity index 97% rename from libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.h rename to plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h index 9e2e47f434..2e95cee9bb 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.h +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h @@ -7,7 +7,7 @@ // #pragma once -#include "../WindowOpenGLDisplayPlugin.h" +#include #include diff --git a/plugins/oculusLegacy/src/OculusProvider.cpp b/plugins/oculusLegacy/src/OculusProvider.cpp new file mode 100644 index 0000000000..606563e0ad --- /dev/null +++ b/plugins/oculusLegacy/src/OculusProvider.cpp @@ -0,0 +1,45 @@ +// +// Created by Bradley Austin Davis on 2015/10/25 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include +#include +#include + +#include +#include + +#include "OculusLegacyDisplayPlugin.h" + +class OculusProvider : public QObject, public DisplayProvider +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DisplayProvider_iid FILE "oculus.json") + Q_INTERFACES(DisplayProvider) + +public: + OculusProvider(QObject* parent = nullptr) : QObject(parent) {} + virtual ~OculusProvider() {} + + virtual DisplayPluginList getDisplayPlugins() override { + static std::once_flag once; + std::call_once(once, [&] { + DisplayPluginPointer plugin(new OculusLegacyDisplayPlugin()); + if (plugin->isSupported()) { + _displayPlugins.push_back(plugin); + } + }); + return _displayPlugins; + } + +private: + DisplayPluginList _displayPlugins; +}; + +#include "OculusProvider.moc" diff --git a/plugins/oculusLegacy/src/oculus.json b/plugins/oculusLegacy/src/oculus.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/plugins/oculusLegacy/src/oculus.json @@ -0,0 +1 @@ +{} diff --git a/tests/controllers/src/main.cpp b/tests/controllers/src/main.cpp index a7b1be15ca..139d9b282c 100644 --- a/tests/controllers/src/main.cpp +++ b/tests/controllers/src/main.cpp @@ -80,9 +80,6 @@ using namespace controller; class PluginContainerProxy : public QObject, PluginContainer { Q_OBJECT public: - PluginContainerProxy() { - Plugin::setContainer(this); - } virtual ~PluginContainerProxy() {} virtual void addMenu(const QString& menuName) override {} virtual void removeMenu(const QString& menuName) override {} From 43df5b55fe5adf6c3fefdc61c431225fe7587668 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 1 Nov 2015 11:55:55 -0800 Subject: [PATCH 33/44] fix linker warnings --- .../controllers/src/controllers/DeviceProxy.cpp | 11 +++++++---- .../controllers/src/controllers/impl/Endpoint.cpp | 12 +++++++----- .../controllers/src/controllers/impl/Mapping.cpp | 9 ++++++++- libraries/controllers/src/controllers/impl/Route.cpp | 8 +++++++- .../impl/conditionals/EndpointConditional.cpp | 8 +++++++- .../controllers/impl/conditionals/NotConditional.cpp | 8 +++++++- .../src/controllers/impl/endpoints/ArrayEndpoint.cpp | 8 +++++++- .../src/controllers/impl/endpoints/JSEndpoint.cpp | 8 +++++++- .../controllers/impl/endpoints/StandardEndpoint.cpp | 8 +++++++- .../impl/filters/ConstrainToIntegerFilter.cpp | 8 +++++++- .../filters/ConstrainToPositiveIntegerFilter.cpp | 8 +++++++- .../src/controllers/impl/filters/InvertFilter.cpp | 8 +++++++- 12 files changed, 85 insertions(+), 19 deletions(-) diff --git a/libraries/controllers/src/controllers/DeviceProxy.cpp b/libraries/controllers/src/controllers/DeviceProxy.cpp index f3e9526080..f03354c52d 100644 --- a/libraries/controllers/src/controllers/DeviceProxy.cpp +++ b/libraries/controllers/src/controllers/DeviceProxy.cpp @@ -7,8 +7,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "DeviceProxy.h" - -namespace controller { -} +// NOTE: we don't need to include this header unless/until we add additional symbols. +// By removing this header we prevent these warnings on windows: +// +// warning LNK4221: This object file does not define any previously undefined public symbols, +// so it will not be used by any link operation that consumes this library +// +//#include "DeviceProxy.h" diff --git a/libraries/controllers/src/controllers/impl/Endpoint.cpp b/libraries/controllers/src/controllers/impl/Endpoint.cpp index 9e9b13f8ea..e771b1916f 100644 --- a/libraries/controllers/src/controllers/impl/Endpoint.cpp +++ b/libraries/controllers/src/controllers/impl/Endpoint.cpp @@ -6,9 +6,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "Endpoint.h" - -namespace controller { - -} +// NOTE: we don't need to include this header unless/until we add additional symbols. +// By removing this header we prevent these warnings on windows: +// +// warning LNK4221: This object file does not define any previously undefined public symbols, +// so it will not be used by any link operation that consumes this library +// +//#include "Endpoint.h" diff --git a/libraries/controllers/src/controllers/impl/Mapping.cpp b/libraries/controllers/src/controllers/impl/Mapping.cpp index 68c43da393..dd8e1c1d48 100644 --- a/libraries/controllers/src/controllers/impl/Mapping.cpp +++ b/libraries/controllers/src/controllers/impl/Mapping.cpp @@ -5,4 +5,11 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "Mapping.h" + +// NOTE: we don't need to include this header unless/until we add additional symbols. +// By removing this header we prevent these warnings on windows: +// +// warning LNK4221: This object file does not define any previously undefined public symbols, +// so it will not be used by any link operation that consumes this library +// +//#include "Mapping.h" diff --git a/libraries/controllers/src/controllers/impl/Route.cpp b/libraries/controllers/src/controllers/impl/Route.cpp index 56590e564a..c74f809195 100644 --- a/libraries/controllers/src/controllers/impl/Route.cpp +++ b/libraries/controllers/src/controllers/impl/Route.cpp @@ -6,4 +6,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "Route.h" +// NOTE: we don't need to include this header unless/until we add additional symbols. +// By removing this header we prevent these warnings on windows: +// +// warning LNK4221: This object file does not define any previously undefined public symbols, +// so it will not be used by any link operation that consumes this library +// +//#include "Route.h" diff --git a/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.cpp b/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.cpp index 03e16b8cf9..f833eedb60 100644 --- a/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.cpp +++ b/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.cpp @@ -6,4 +6,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "EndpointConditional.h" \ No newline at end of file +// NOTE: we don't need to include this header unless/until we add additional symbols. +// By removing this header we prevent these warnings on windows: +// +// warning LNK4221: This object file does not define any previously undefined public symbols, +// so it will not be used by any link operation that consumes this library +// +//#include "EndpointConditional.h" \ No newline at end of file diff --git a/libraries/controllers/src/controllers/impl/conditionals/NotConditional.cpp b/libraries/controllers/src/controllers/impl/conditionals/NotConditional.cpp index 0c8d602b9e..e30b060985 100644 --- a/libraries/controllers/src/controllers/impl/conditionals/NotConditional.cpp +++ b/libraries/controllers/src/controllers/impl/conditionals/NotConditional.cpp @@ -6,4 +6,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "NotConditional.h" +// NOTE: we don't need to include this header unless/until we add additional symbols. +// By removing this header we prevent these warnings on windows: +// +// warning LNK4221: This object file does not define any previously undefined public symbols, +// so it will not be used by any link operation that consumes this library +// +//#include "NotConditional.h" diff --git a/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.cpp index c083a7147d..5dea1de34e 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.cpp +++ b/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.cpp @@ -6,4 +6,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "ArrayEndpoint.h" \ No newline at end of file +// NOTE: we don't need to include this header unless/until we add additional symbols. +// By removing this header we prevent these warnings on windows: +// +// warning LNK4221: This object file does not define any previously undefined public symbols, +// so it will not be used by any link operation that consumes this library +// +//#include "ArrayEndpoint.h" \ No newline at end of file diff --git a/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.cpp index 4560741d12..7f0e80cbae 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.cpp +++ b/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.cpp @@ -6,4 +6,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "JSEndpoint.h" \ No newline at end of file +// NOTE: we don't need to include this header unless/until we add additional symbols. +// By removing this header we prevent these warnings on windows: +// +// warning LNK4221: This object file does not define any previously undefined public symbols, +// so it will not be used by any link operation that consumes this library +// +//#include "JSEndpoint.h" \ No newline at end of file diff --git a/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.cpp index 09920d249c..89bbe5d777 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.cpp +++ b/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.cpp @@ -6,4 +6,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "StandardEndpoint.h" \ No newline at end of file +// NOTE: we don't need to include this header unless/until we add additional symbols. +// By removing this header we prevent these warnings on windows: +// +// warning LNK4221: This object file does not define any previously undefined public symbols, +// so it will not be used by any link operation that consumes this library +// +//#include "StandardEndpoint.h" \ No newline at end of file diff --git a/libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.cpp b/libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.cpp index 78ffb47693..8bd3d2db89 100644 --- a/libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.cpp +++ b/libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.cpp @@ -6,4 +6,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "ConstrainToIntegerFilter.h" +// NOTE: we don't need to include this header unless/until we add additional symbols. +// By removing this header we prevent these warnings on windows: +// +// warning LNK4221: This object file does not define any previously undefined public symbols, +// so it will not be used by any link operation that consumes this library +// +//#include "ConstrainToIntegerFilter.h" diff --git a/libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.cpp b/libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.cpp index d78942b18f..f1abc8cecd 100644 --- a/libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.cpp +++ b/libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.cpp @@ -6,4 +6,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "ConstrainToPositiveIntegerFilter.h" +// NOTE: we don't need to include this header unless/until we add additional symbols. +// By removing this header we prevent these warnings on windows: +// +// warning LNK4221: This object file does not define any previously undefined public symbols, +// so it will not be used by any link operation that consumes this library +// +//#include "ConstrainToPositiveIntegerFilter.h" diff --git a/libraries/controllers/src/controllers/impl/filters/InvertFilter.cpp b/libraries/controllers/src/controllers/impl/filters/InvertFilter.cpp index db582b84cc..5407c6dd1d 100644 --- a/libraries/controllers/src/controllers/impl/filters/InvertFilter.cpp +++ b/libraries/controllers/src/controllers/impl/filters/InvertFilter.cpp @@ -6,4 +6,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "InvertFilter.h" +// NOTE: we don't need to include this header unless/until we add additional symbols. +// By removing this header we prevent these warnings on windows: +// +// warning LNK4221: This object file does not define any previously undefined public symbols, +// so it will not be used by any link operation that consumes this library +// +//#include "InvertFilter.h" From 4a08329d22cd094b984622ab575a898b6a1de78b Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 1 Nov 2015 12:10:42 -0800 Subject: [PATCH 34/44] fix unix warnings for comparing enums to enums --- .../src/input-plugins/SDL2Manager.cpp | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/SDL2Manager.cpp b/libraries/input-plugins/src/input-plugins/SDL2Manager.cpp index ec2fa2ed07..c6f5491a5a 100644 --- a/libraries/input-plugins/src/input-plugins/SDL2Manager.cpp +++ b/libraries/input-plugins/src/input-plugins/SDL2Manager.cpp @@ -20,27 +20,27 @@ #ifdef HAVE_SDL2 static_assert( - controller::A == SDL_CONTROLLER_BUTTON_A && - controller::B == SDL_CONTROLLER_BUTTON_B && - controller::X == SDL_CONTROLLER_BUTTON_X && - controller::Y == SDL_CONTROLLER_BUTTON_Y && - controller::BACK == SDL_CONTROLLER_BUTTON_BACK && - controller::GUIDE == SDL_CONTROLLER_BUTTON_GUIDE && - controller::START == SDL_CONTROLLER_BUTTON_START && - controller::LS == SDL_CONTROLLER_BUTTON_LEFTSTICK && - controller::RS == SDL_CONTROLLER_BUTTON_RIGHTSTICK && - controller::LB == SDL_CONTROLLER_BUTTON_LEFTSHOULDER && - controller::RB == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER && - controller::DU == SDL_CONTROLLER_BUTTON_DPAD_UP && - controller::DD == SDL_CONTROLLER_BUTTON_DPAD_DOWN && - controller::DL == SDL_CONTROLLER_BUTTON_DPAD_LEFT && - controller::DR == SDL_CONTROLLER_BUTTON_DPAD_RIGHT && - controller::LX == SDL_CONTROLLER_AXIS_LEFTX && - controller::LY == SDL_CONTROLLER_AXIS_LEFTY && - controller::RX == SDL_CONTROLLER_AXIS_RIGHTX && - controller::RY == SDL_CONTROLLER_AXIS_RIGHTY && - controller::LT == SDL_CONTROLLER_AXIS_TRIGGERLEFT && - controller::RT == SDL_CONTROLLER_AXIS_TRIGGERRIGHT, + (int)controller::A == (int)SDL_CONTROLLER_BUTTON_A && + (int)controller::B == (int)SDL_CONTROLLER_BUTTON_B && + (int)controller::X == (int)SDL_CONTROLLER_BUTTON_X && + (int)controller::Y == (int)SDL_CONTROLLER_BUTTON_Y && + (int)controller::BACK == (int)SDL_CONTROLLER_BUTTON_BACK && + (int)controller::GUIDE == (int)SDL_CONTROLLER_BUTTON_GUIDE && + (int)controller::START == (int)SDL_CONTROLLER_BUTTON_START && + (int)controller::LS == (int)SDL_CONTROLLER_BUTTON_LEFTSTICK && + (int)controller::RS == (int)SDL_CONTROLLER_BUTTON_RIGHTSTICK && + (int)controller::LB == (int)SDL_CONTROLLER_BUTTON_LEFTSHOULDER && + (int)controller::RB == (int)SDL_CONTROLLER_BUTTON_RIGHTSHOULDER && + (int)controller::DU == (int)SDL_CONTROLLER_BUTTON_DPAD_UP && + (int)controller::DD == (int)SDL_CONTROLLER_BUTTON_DPAD_DOWN && + (int)controller::DL == (int)SDL_CONTROLLER_BUTTON_DPAD_LEFT && + (int)controller::DR == (int)SDL_CONTROLLER_BUTTON_DPAD_RIGHT && + (int)controller::LX == (int)SDL_CONTROLLER_AXIS_LEFTX && + (int)controller::LY == (int)SDL_CONTROLLER_AXIS_LEFTY && + (int)controller::RX == (int)SDL_CONTROLLER_AXIS_RIGHTX && + (int)controller::RY == (int)SDL_CONTROLLER_AXIS_RIGHTY && + (int)controller::LT == (int)SDL_CONTROLLER_AXIS_TRIGGERLEFT && + (int)controller::RT == (int)SDL_CONTROLLER_AXIS_TRIGGERRIGHT, "SDL2 equvalence: Enums and values from StandardControls.h are assumed to match enums from SDL_gamecontroller.h"); #endif From e0ac48fe27b442efb7ef1a28ac4ce130b5aedb2a Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sun, 1 Nov 2015 11:28:38 -0800 Subject: [PATCH 35/44] PR comments --- BUILD.md | 17 +++++++++++++---- cmake/macros/TargetZlib.cmake | 11 ++++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/BUILD.md b/BUILD.md index 7ad2ddeee0..72dfa5725e 100644 --- a/BUILD.md +++ b/BUILD.md @@ -5,15 +5,24 @@ * [OpenSSL](https://www.openssl.org/related/binaries.html) ~> 1.0.1m * IMPORTANT: Using the recommended version of OpenSSL is critical to avoid security vulnerabilities. * [VHACD](https://github.com/virneo/v-hacd)(clone this repository)(Optional) -* [zlib](http://www.zlib.net/) ####CMake External Project Dependencies +* [boostconfig](https://github.com/boostorg/config) ~> 1.58 * [Bullet Physics Engine](https://code.google.com/p/bullet/downloads/list) ~> 2.82 -* [Intel Threading Building Blocks](https://www.threadingbuildingblocks.org/) ~> 4.3 +* [Faceshift](http://www.faceshift.com/) ~> 4.3 +* [GLEW](http://glew.sourceforge.net/) * [glm](http://glm.g-truc.net/0.9.5/index.html) ~> 0.9.5.4 * [gverb](https://github.com/highfidelity/gverb) +* [Oculus SDK](https://developer.oculus.com/downloads/) ~> 0.6 (Win32) / 0.5 (Mac / Linux) +* [oglplus](http://oglplus.org/) ~> 0.63 +* [OpenVR](https://github.com/ValveSoftware/openvr) ~> 0.91 (Win32 only) +* [Polyvox](http://www.volumesoffun.com/) ~> 0.2.1 * [SDL2](https://www.libsdl.org/download-2.0.php) ~> 2.0.3 +* [soxr](http://soxr.sourceforge.net) ~> 0.1.1 +* [Intel Threading Building Blocks](https://www.threadingbuildingblocks.org/) ~> 4.3 +* [Sixense](http://sixense.com/) ~> 071615 +* [zlib](http://www.zlib.net/) ~> 1.28 (Win32 only) The above dependencies will be downloaded, built, linked and included automatically by CMake where we require them. The CMakeLists files that handle grabbing each of the following external dependencies can be found in the [cmake/externals folder](cmake/externals). The resulting downloads, source files and binaries will be placed in the `build/ext` folder in each of the subfolders for each external project. @@ -59,7 +68,7 @@ For example, to pass the QT_CMAKE_PREFIX_PATH variable during build file generat ####Finding Dependencies -The following applies for dependencies we do not grab via CMake ExternalProject (OpenSSL is an example), or for dependencies you have opted not to grab as a CMake ExternalProject (via -DGET_$NAME=0). The list of dependencies we grab by default as external projects can be found in [the CMake External Project Dependencies section](#cmake-external-project-dependencies). +The following applies for dependencies we do not grab via CMake ExternalProject (OpenSSL is an example), or for dependencies you have opted not to grab as a CMake ExternalProject (via -DUSE_LOCAL_$NAME=0). The list of dependencies we grab by default as external projects can be found in [the CMake External Project Dependencies section](#cmake-external-project-dependencies). You can point our [Cmake find modules](cmake/modules/) to the correct version of dependencies by setting one of the three following variables to the location of the correct version of the dependency. @@ -73,5 +82,5 @@ In the examples below the variable $NAME would be replaced by the name of the de ####Devices -You can support external input/output devices such as Oculus Rift, Leap Motion, Faceshift, MIDI, Razr Hydra and more by adding each individual SDK in the visible building path. Refer to the readme file available in each device folder in [interface/external/](interface/external) for the detailed explanation of the requirements to use the device. +You can support external input/output devices such as Leap Motion, MIDI, and more by adding each individual SDK in the visible building path. Refer to the readme file available in each device folder in [interface/external/](interface/external) for the detailed explanation of the requirements to use the device. diff --git a/cmake/macros/TargetZlib.cmake b/cmake/macros/TargetZlib.cmake index 11eb8c132e..3eb0322ea0 100644 --- a/cmake/macros/TargetZlib.cmake +++ b/cmake/macros/TargetZlib.cmake @@ -6,12 +6,17 @@ # See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html # macro(TARGET_ZLIB) + if (WIN32) add_dependency_external_projects(zlib) - add_paths_to_fixup_libs(${ZLIB_DLL_PATH}) - else() - find_package(ZLIB REQUIRED) endif() + + find_package(ZLIB REQUIRED) + + if (WIN32) + add_paths_to_fixup_libs(${ZLIB_DLL_PATH}) + endif() + target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${ZLIB_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES}) endmacro() From 13e805ac15f4ccf8ccefc51e9d722344adc8b8e4 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 1 Nov 2015 13:18:53 -0800 Subject: [PATCH 36/44] replace copy_resolved_item_into_bundle with a version that doesn't report warnings for a status case --- cmake/templates/FixupBundlePostBuild.cmake.in | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/cmake/templates/FixupBundlePostBuild.cmake.in b/cmake/templates/FixupBundlePostBuild.cmake.in index 7d98e9796c..4afe4de403 100644 --- a/cmake/templates/FixupBundlePostBuild.cmake.in +++ b/cmake/templates/FixupBundlePostBuild.cmake.in @@ -10,5 +10,35 @@ # include(BundleUtilities) + + +# replace copy_resolved_item_into_bundle +# +# The official version of copy_resolved_item_into_bundle will print out a "warning:" when +# the resolved item matches the resolved embedded item. This not not really an issue that +# should rise to the level of a "warning" so we replace this message with a "status:" +# +function(copy_resolved_item_into_bundle resolved_item resolved_embedded_item) + if(WIN32) + # ignore case on Windows + string(TOLOWER "${resolved_item}" resolved_item_compare) + string(TOLOWER "${resolved_embedded_item}" resolved_embedded_item_compare) + else() + set(resolved_item_compare "${resolved_item}") + set(resolved_embedded_item_compare "${resolved_embedded_item}") + endif() + + if("${resolved_item_compare}" STREQUAL "${resolved_embedded_item_compare}") + # this is our only change from the original version + message(STATUS "status: resolved_item == resolved_embedded_item - not copying...") + else() + #message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy ${resolved_item} ${resolved_embedded_item}") + execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}") + if(UNIX AND NOT APPLE) + file(RPATH_REMOVE FILE "${resolved_embedded_item}") + endif() + endif() +endfunction() + message(STATUS "FIXUP_LIBS for fixup_bundle called for bundle ${BUNDLE_EXECUTABLE} are @FIXUP_LIBS@") fixup_bundle("${BUNDLE_EXECUTABLE}" "" "@FIXUP_LIBS@") \ No newline at end of file From 1e47a536031829dfad3a527b428447f3df96c0af Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sun, 1 Nov 2015 14:34:03 -0800 Subject: [PATCH 37/44] Fixing mac oculus crash --- plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp | 8 ++++++++ plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h | 1 + 2 files changed, 9 insertions(+) diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp index 5a253cdbbf..0120bcf2aa 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp @@ -190,6 +190,14 @@ void OculusLegacyDisplayPlugin::deactivate() { ovr_Shutdown(); } +// DLL based display plugins MUST initialize GLEW inside the DLL code. +void OculusLegacyDisplayPlugin::customizeContext() { + glewExperimental = true; + GLenum err = glewInit(); + glGetError(); + WindowOpenGLDisplayPlugin::customizeContext(); +} + void OculusLegacyDisplayPlugin::preDisplay() { _window->makeCurrent(); } diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h index 2e95cee9bb..6e3f864aee 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h @@ -35,6 +35,7 @@ public: virtual glm::mat4 getHeadPose() const override; protected: + virtual void customizeContext() override; virtual void preRender() override; virtual void preDisplay() override; virtual void display(GLuint finalTexture, const glm::uvec2& sceneSize) override; From b9d60e803b566dbcd8ae00c98202d8fc96936a20 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 1 Nov 2015 15:13:28 -0800 Subject: [PATCH 38/44] fix mac warning --- plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp index 0120bcf2aa..d8dc3667ae 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp @@ -193,7 +193,7 @@ void OculusLegacyDisplayPlugin::deactivate() { // DLL based display plugins MUST initialize GLEW inside the DLL code. void OculusLegacyDisplayPlugin::customizeContext() { glewExperimental = true; - GLenum err = glewInit(); + glewInit(); glGetError(); WindowOpenGLDisplayPlugin::customizeContext(); } From 92bcd9ca9eb583252b63fbcd0c397390521a5779 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 1 Nov 2015 15:48:01 -0800 Subject: [PATCH 39/44] make oculus plugin use static glew --- plugins/oculus/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/oculus/CMakeLists.txt b/plugins/oculus/CMakeLists.txt index 62999cbb7e..fe1a87d6b6 100644 --- a/plugins/oculus/CMakeLists.txt +++ b/plugins/oculus/CMakeLists.txt @@ -8,6 +8,9 @@ if (WIN32) + # we're using static GLEW, so define GLEW_STATIC + add_definitions(-DGLEW_STATIC) + set(TARGET_NAME oculus) setup_hifi_plugin() link_hifi_libraries(shared gl plugins display-plugins) From 70b9aa5ff198f074fd9b5ae1989bec1fff033626 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Mon, 2 Nov 2015 07:42:52 -0800 Subject: [PATCH 40/44] remove right click context menu until we can make it work with camera move better --- interface/resources/controllers/keyboardMouse.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/resources/controllers/keyboardMouse.json b/interface/resources/controllers/keyboardMouse.json index 9c3ba79d76..8af6b1dc98 100644 --- a/interface/resources/controllers/keyboardMouse.json +++ b/interface/resources/controllers/keyboardMouse.json @@ -81,7 +81,6 @@ { "from": "Keyboard.Space", "to": "Actions.SHIFT" }, { "from": "Keyboard.R", "to": "Actions.ACTION1" }, - { "from": "Keyboard.T", "to": "Actions.ACTION2" }, - { "from": "Keyboard.RightMouseClick", "to": "Actions.ContextMenu" } + { "from": "Keyboard.T", "to": "Actions.ACTION2" } ] } From 017e42bbc25478ab9ad8c1f733ea617ed42cccdf Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 2 Nov 2015 08:27:51 -0800 Subject: [PATCH 41/44] Update sixense SDK --- cmake/externals/sixense/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/sixense/CMakeLists.txt b/cmake/externals/sixense/CMakeLists.txt index 07cf1c1163..8ae18e638a 100644 --- a/cmake/externals/sixense/CMakeLists.txt +++ b/cmake/externals/sixense/CMakeLists.txt @@ -6,8 +6,8 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://hifi-public.s3.amazonaws.com/dependencies/SixenseSDK_071615.zip - URL_MD5 752a3901f334124e9cffc2ba4136ef7d + URL https://hifi-public.s3.amazonaws.com/dependencies/SixenseSDK_102215.zip + URL_MD5 93c3a6795cce777a0f472b09532935f1 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" From b00f572e1a278e4eadc7b0947fe867ebdf0658c5 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Mon, 2 Nov 2015 09:21:15 -0800 Subject: [PATCH 42/44] add mouseClicked inputs vs mouseButton inputs, make right-click work without right button drag --- .../resources/controllers/keyboardMouse.json | 19 +++++----- .../src/input-plugins/KeyboardMouseDevice.cpp | 37 +++++++++++++++---- .../src/input-plugins/KeyboardMouseDevice.h | 7 +++- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/interface/resources/controllers/keyboardMouse.json b/interface/resources/controllers/keyboardMouse.json index 8af6b1dc98..f99472b0e9 100644 --- a/interface/resources/controllers/keyboardMouse.json +++ b/interface/resources/controllers/keyboardMouse.json @@ -4,8 +4,8 @@ { "from": "Keyboard.A", "when": "Keyboard.Shift", "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.D", "when": "Keyboard.Shift", "to": "Actions.LATERAL_RIGHT" }, - { "from": "Keyboard.A", "when": "Keyboard.RightMouseClick", "to": "Actions.LATERAL_LEFT" }, - { "from": "Keyboard.D", "when": "Keyboard.RightMouseClick", "to": "Actions.LATERAL_RIGHT" }, + { "from": "Keyboard.A", "when": "Keyboard.RightMouseButton", "to": "Actions.LATERAL_LEFT" }, + { "from": "Keyboard.D", "when": "Keyboard.RightMouseButton", "to": "Actions.LATERAL_RIGHT" }, { "from": "Keyboard.E", "when": "Keyboard.Shift", "to": "Actions.BOOM_IN", "filters": [ { "type": "scale", "scale": 0.05 } ] }, { "from": "Keyboard.C", "when": "Keyboard.Shift", "to": "Actions.BOOM_OUT", "filters": [ { "type": "scale", "scale": 0.05 } ] }, { "from": "Keyboard.S", "when": "Keyboard.Shift", "to": "Actions.PITCH_DOWN" }, @@ -13,7 +13,7 @@ { "from": { "makeAxis" : ["Keyboard.MouseMoveLeft", "Keyboard.MouseMoveRight"] }, - "when": [ "Application.InHMD", "Application.ComfortMode", "Keyboard.RightMouseClick" ], + "when": [ "Application.InHMD", "Application.ComfortMode", "Keyboard.RightMouseButton" ], "to": "Actions.StepYaw", "filters": [ @@ -46,7 +46,7 @@ }, { "from": { "makeAxis" : ["Keyboard.MouseMoveLeft", "Keyboard.MouseMoveRight"] }, - "when": "Keyboard.RightMouseClick", + "when": "Keyboard.RightMouseButton", "to": "Actions.Yaw" }, @@ -55,8 +55,8 @@ { "from": "Keyboard.C", "to": "Actions.VERTICAL_DOWN" }, { "from": "Keyboard.E", "to": "Actions.VERTICAL_UP" }, - { "from": "Keyboard.Left", "when": "Keyboard.RightMouseClick", "to": "Actions.LATERAL_LEFT" }, - { "from": "Keyboard.Right", "when": "Keyboard.RightMouseClick", "to": "Actions.LATERAL_RIGHT" }, + { "from": "Keyboard.Left", "when": "Keyboard.RightMouseButton", "to": "Actions.LATERAL_LEFT" }, + { "from": "Keyboard.Right", "when": "Keyboard.RightMouseButton", "to": "Actions.LATERAL_RIGHT" }, { "from": "Keyboard.Left", "when": "Keyboard.Shift", "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.Right", "when": "Keyboard.Shift", "to": "Actions.LATERAL_RIGHT" }, { "from": "Keyboard.Down", "when": "Keyboard.Shift", "to": "Actions.PITCH_DOWN" }, @@ -68,8 +68,8 @@ { "from": "Keyboard.PgDown", "to": "Actions.VERTICAL_DOWN" }, { "from": "Keyboard.PgUp", "to": "Actions.VERTICAL_UP" }, - { "from": "Keyboard.MouseMoveUp", "when": "Keyboard.RightMouseClick", "to": "Actions.PITCH_UP" }, - { "from": "Keyboard.MouseMoveDown", "when": "Keyboard.RightMouseClick", "to": "Actions.PITCH_DOWN" }, + { "from": "Keyboard.MouseMoveUp", "when": "Keyboard.RightMouseButton", "to": "Actions.PITCH_UP" }, + { "from": "Keyboard.MouseMoveDown", "when": "Keyboard.RightMouseButton", "to": "Actions.PITCH_DOWN" }, { "from": "Keyboard.TouchpadDown", "to": "Actions.PITCH_DOWN" }, { "from": "Keyboard.TouchpadUp", "to": "Actions.PITCH_UP" }, @@ -81,6 +81,7 @@ { "from": "Keyboard.Space", "to": "Actions.SHIFT" }, { "from": "Keyboard.R", "to": "Actions.ACTION1" }, - { "from": "Keyboard.T", "to": "Actions.ACTION2" } + { "from": "Keyboard.T", "to": "Actions.ACTION2" }, + { "from": "Keyboard.RightMouseClicked", "to": "Actions.ContextMenu" } ] } diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index 9cd510c521..42081aca30 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -59,11 +59,25 @@ void KeyboardMouseDevice::mousePressEvent(QMouseEvent* event, unsigned int devic // key pressed again ? without catching the release event ? } _lastCursor = event->pos(); + _mousePressAt = event->pos(); + + eraseMouseClicked(); } void KeyboardMouseDevice::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) { auto input = makeInput((Qt::MouseButton) event->button()); _buttonPressedMap.erase(input.getChannel()); + + if (_mousePressAt == event->pos()) { + auto input = makeInput((Qt::MouseButton) event->button(), true); // clicked + auto result = _buttonPressedMap.insert(input.getChannel()); + } +} + +void KeyboardMouseDevice::eraseMouseClicked() { + _buttonPressedMap.erase(makeInput(Qt::LeftButton, true).getChannel()); + _buttonPressedMap.erase(makeInput(Qt::MiddleButton, true).getChannel()); + _buttonPressedMap.erase(makeInput(Qt::RightButton, true).getChannel()); } void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) { @@ -77,6 +91,8 @@ void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event, unsigned int device _axisStateMap[makeInput(MOUSE_AXIS_Y_NEG).getChannel()] = (currentMove.y() > 0 ? currentMove.y() : 0.0f); _lastCursor = currentPos; + + eraseMouseClicked(); } void KeyboardMouseDevice::wheelEvent(QWheelEvent* event) { @@ -138,14 +154,17 @@ controller::Input KeyboardMouseDevice::makeInput(Qt::Key code) const { return controller::Input(_deviceID, shortCode, controller::ChannelType::BUTTON); } -controller::Input KeyboardMouseDevice::makeInput(Qt::MouseButton code) const { +controller::Input KeyboardMouseDevice::makeInput(Qt::MouseButton code, bool quickClicked) const { switch (code) { case Qt::LeftButton: - return controller::Input(_deviceID, MOUSE_BUTTON_LEFT, controller::ChannelType::BUTTON); + return controller::Input(_deviceID, quickClicked ? MOUSE_BUTTON_LEFT_QUICK_CLICK : + MOUSE_BUTTON_LEFT, controller::ChannelType::BUTTON); case Qt::RightButton: - return controller::Input(_deviceID, MOUSE_BUTTON_RIGHT, controller::ChannelType::BUTTON); + return controller::Input(_deviceID, quickClicked ? MOUSE_BUTTON_RIGHT_QUICK_CLICK : + MOUSE_BUTTON_RIGHT, controller::ChannelType::BUTTON); case Qt::MiddleButton: - return controller::Input(_deviceID, MOUSE_BUTTON_MIDDLE, controller::ChannelType::BUTTON); + return controller::Input(_deviceID, quickClicked ? MOUSE_BUTTON_MIDDLE_QUICK_CLICK : + MOUSE_BUTTON_MIDDLE, controller::ChannelType::BUTTON); default: return controller::Input(); }; @@ -182,9 +201,13 @@ controller::Input::NamedVector KeyboardMouseDevice::getAvailableInputs() const { availableInputs.append(Input::NamedPair(makeInput(Qt::Key_PageUp), QKeySequence(Qt::Key_PageUp).toString())); availableInputs.append(Input::NamedPair(makeInput(Qt::Key_PageDown), QKeySequence(Qt::Key_PageDown).toString())); - availableInputs.append(Input::NamedPair(makeInput(Qt::LeftButton), "LeftMouseClick")); - availableInputs.append(Input::NamedPair(makeInput(Qt::MiddleButton), "MiddleMouseClick")); - availableInputs.append(Input::NamedPair(makeInput(Qt::RightButton), "RightMouseClick")); + availableInputs.append(Input::NamedPair(makeInput(Qt::LeftButton), "LeftMouseButton")); + availableInputs.append(Input::NamedPair(makeInput(Qt::MiddleButton), "MiddleMouseButton")); + availableInputs.append(Input::NamedPair(makeInput(Qt::RightButton), "RightMouseButton")); + + availableInputs.append(Input::NamedPair(makeInput(Qt::LeftButton, true), "LeftMouseClicked")); + availableInputs.append(Input::NamedPair(makeInput(Qt::MiddleButton, true), "MiddleMouseClicked")); + availableInputs.append(Input::NamedPair(makeInput(Qt::RightButton, true), "RightMouseClicked")); availableInputs.append(Input::NamedPair(makeInput(MOUSE_AXIS_X_POS), "MouseMoveRight")); availableInputs.append(Input::NamedPair(makeInput(MOUSE_AXIS_X_NEG), "MouseMoveLeft")); diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h index 1ff77d2dce..75a1159b92 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h @@ -37,6 +37,9 @@ public: MOUSE_BUTTON_LEFT = KEYBOARD_LAST + 1, MOUSE_BUTTON_RIGHT, MOUSE_BUTTON_MIDDLE, + MOUSE_BUTTON_LEFT_QUICK_CLICK, + MOUSE_BUTTON_RIGHT_QUICK_CLICK, + MOUSE_BUTTON_MIDDLE_QUICK_CLICK, }; enum MouseAxisChannel { @@ -83,6 +86,7 @@ public: void mouseMoveEvent(QMouseEvent* event, unsigned int deviceID = 0); void mousePressEvent(QMouseEvent* event, unsigned int deviceID = 0); void mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID = 0); + void eraseMouseClicked(); void touchBeginEvent(const QTouchEvent* event); void touchEndEvent(const QTouchEvent* event); @@ -92,7 +96,7 @@ public: // Let's make it easy for Qt because we assume we love Qt forever controller::Input makeInput(Qt::Key code) const; - controller::Input makeInput(Qt::MouseButton code) const; + controller::Input makeInput(Qt::MouseButton code, bool quickClicked = false) const; controller::Input makeInput(MouseAxisChannel axis) const; controller::Input makeInput(TouchAxisChannel axis) const; controller::Input makeInput(TouchButtonChannel button) const; @@ -101,6 +105,7 @@ public: protected: QPoint _lastCursor; + QPoint _mousePressAt; glm::vec2 _lastTouch; bool _isTouching = false; From c3a78ed151a60dd9530765e631f6270ca4e1b887 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Mon, 2 Nov 2015 09:27:35 -0800 Subject: [PATCH 43/44] cleanup --- .../src/input-plugins/KeyboardMouseDevice.cpp | 12 +++++++----- .../src/input-plugins/KeyboardMouseDevice.h | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index 42081aca30..247e08ada1 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -68,9 +68,11 @@ void KeyboardMouseDevice::mouseReleaseEvent(QMouseEvent* event, unsigned int dev auto input = makeInput((Qt::MouseButton) event->button()); _buttonPressedMap.erase(input.getChannel()); + // if we pressed and released at the same location, then create a "_CLICKED" input for this button + // we might want to add some small tolerance to this so if you do a small drag it still counts as + // a clicked. if (_mousePressAt == event->pos()) { - auto input = makeInput((Qt::MouseButton) event->button(), true); // clicked - auto result = _buttonPressedMap.insert(input.getChannel()); + _buttonPressedMap.insert(makeInput((Qt::MouseButton) event->button(), true).getChannel()); } } @@ -157,13 +159,13 @@ controller::Input KeyboardMouseDevice::makeInput(Qt::Key code) const { controller::Input KeyboardMouseDevice::makeInput(Qt::MouseButton code, bool quickClicked) const { switch (code) { case Qt::LeftButton: - return controller::Input(_deviceID, quickClicked ? MOUSE_BUTTON_LEFT_QUICK_CLICK : + return controller::Input(_deviceID, quickClicked ? MOUSE_BUTTON_LEFT_CLICKED : MOUSE_BUTTON_LEFT, controller::ChannelType::BUTTON); case Qt::RightButton: - return controller::Input(_deviceID, quickClicked ? MOUSE_BUTTON_RIGHT_QUICK_CLICK : + return controller::Input(_deviceID, quickClicked ? MOUSE_BUTTON_RIGHT_CLICKED : MOUSE_BUTTON_RIGHT, controller::ChannelType::BUTTON); case Qt::MiddleButton: - return controller::Input(_deviceID, quickClicked ? MOUSE_BUTTON_MIDDLE_QUICK_CLICK : + return controller::Input(_deviceID, quickClicked ? MOUSE_BUTTON_MIDDLE_CLICKED : MOUSE_BUTTON_MIDDLE, controller::ChannelType::BUTTON); default: return controller::Input(); diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h index 75a1159b92..b6681e2ae0 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h @@ -37,9 +37,9 @@ public: MOUSE_BUTTON_LEFT = KEYBOARD_LAST + 1, MOUSE_BUTTON_RIGHT, MOUSE_BUTTON_MIDDLE, - MOUSE_BUTTON_LEFT_QUICK_CLICK, - MOUSE_BUTTON_RIGHT_QUICK_CLICK, - MOUSE_BUTTON_MIDDLE_QUICK_CLICK, + MOUSE_BUTTON_LEFT_CLICKED, + MOUSE_BUTTON_RIGHT_CLICKED, + MOUSE_BUTTON_MIDDLE_CLICKED, }; enum MouseAxisChannel { From d9dd045886fba3a416eda545a74a3be5bb5d55ad Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Mon, 2 Nov 2015 09:29:09 -0800 Subject: [PATCH 44/44] better parameter name --- .../src/input-plugins/KeyboardMouseDevice.cpp | 8 ++++---- .../input-plugins/src/input-plugins/KeyboardMouseDevice.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index 247e08ada1..2157a3a010 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -156,16 +156,16 @@ controller::Input KeyboardMouseDevice::makeInput(Qt::Key code) const { return controller::Input(_deviceID, shortCode, controller::ChannelType::BUTTON); } -controller::Input KeyboardMouseDevice::makeInput(Qt::MouseButton code, bool quickClicked) const { +controller::Input KeyboardMouseDevice::makeInput(Qt::MouseButton code, bool clicked) const { switch (code) { case Qt::LeftButton: - return controller::Input(_deviceID, quickClicked ? MOUSE_BUTTON_LEFT_CLICKED : + return controller::Input(_deviceID, clicked ? MOUSE_BUTTON_LEFT_CLICKED : MOUSE_BUTTON_LEFT, controller::ChannelType::BUTTON); case Qt::RightButton: - return controller::Input(_deviceID, quickClicked ? MOUSE_BUTTON_RIGHT_CLICKED : + return controller::Input(_deviceID, clicked ? MOUSE_BUTTON_RIGHT_CLICKED : MOUSE_BUTTON_RIGHT, controller::ChannelType::BUTTON); case Qt::MiddleButton: - return controller::Input(_deviceID, quickClicked ? MOUSE_BUTTON_MIDDLE_CLICKED : + return controller::Input(_deviceID, clicked ? MOUSE_BUTTON_MIDDLE_CLICKED : MOUSE_BUTTON_MIDDLE, controller::ChannelType::BUTTON); default: return controller::Input(); diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h index b6681e2ae0..5d86821db1 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h @@ -96,7 +96,7 @@ public: // Let's make it easy for Qt because we assume we love Qt forever controller::Input makeInput(Qt::Key code) const; - controller::Input makeInput(Qt::MouseButton code, bool quickClicked = false) const; + controller::Input makeInput(Qt::MouseButton code, bool clicked = false) const; controller::Input makeInput(MouseAxisChannel axis) const; controller::Input makeInput(TouchAxisChannel axis) const; controller::Input makeInput(TouchButtonChannel button) const;