diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js
index 32ec12b640..a2a112d8e5 100644
--- a/examples/particle_explorer/main.js
+++ b/examples/particle_explorer/main.js
@@ -74,7 +74,9 @@ var keysToIgnore = [
'shapeType',
'isEmitting',
'sittingPoints',
- 'originalTextures'
+ 'originalTextures',
+ 'parentJointIndex',
+ 'parentID'
];
var individualKeys = [];
diff --git a/examples/toybox/bow/bow.js b/examples/toybox/bow/bow.js
index 90199fb70f..f0128acc77 100644
--- a/examples/toybox/bow/bow.js
+++ b/examples/toybox/bow/bow.js
@@ -66,21 +66,6 @@
max2: 15
}
- var BOW_SPATIAL_KEY = {
- leftRelativePosition: {
- x: 0.05,
- y: 0.06,
- z: -0.05
- },
- rightRelativePosition: {
- x: -0.05,
- y: 0.06,
- z: -0.05
- },
- relativeRotation: Quat.fromPitchYawRollDegrees(0, 90, -90)
- }
-
-
var USE_DEBOUNCE = false;
var TRIGGER_CONTROLS = [
@@ -168,11 +153,9 @@
var handToDisable = this.initialHand === 'right' ? 'left' : 'right';
Messages.sendMessage('Hifi-Hand-Disabler', handToDisable);
- setEntityCustomData('grabbableKey', this.entityID, {
- grabbable: false,
- invertSolidWhileHeld: true,
- spatialKey: BOW_SPATIAL_KEY
- });
+ var data = getEntityCustomData('grabbableKey', this.entityID, {});
+ data.grabbable = false;
+ setEntityCustomData('grabbableKey', this.entityID, data);
},
continueNearGrab: function() {
@@ -226,11 +209,10 @@
this.isGrabbed = false;
this.stringDrawn = false;
this.deleteStrings();
- setEntityCustomData('grabbableKey', this.entityID, {
- grabbable: true,
- invertSolidWhileHeld: true,
- spatialKey: BOW_SPATIAL_KEY
- });
+
+ var data = getEntityCustomData('grabbableKey', this.entityID, {});
+ data.grabbable = true;
+ setEntityCustomData('grabbableKey', this.entityID, data);
Entities.deleteEntity(this.preNotchString);
Entities.deleteEntity(this.arrow);
this.aiming = false;
diff --git a/examples/toybox/bow/createBow.js b/examples/toybox/bow/createBow.js
index 9a9ed98c20..4f0cddfc0d 100644
--- a/examples/toybox/bow/createBow.js
+++ b/examples/toybox/bow/createBow.js
@@ -49,14 +49,14 @@ var bow = Entities.addEntity({
invertSolidWhileHeld: true,
spatialKey: {
leftRelativePosition: {
- x: 0.05,
- y: 0.06,
- z: -0.05
+ x: -0.02,
+ y: 0.08,
+ z: 0.09
},
- rightRelativePosition: {
- x: -0.05,
- y: 0.06,
- z: -0.05
+ relativePosition: {
+ x: 0.02,
+ y: 0.08,
+ z: 0.09
},
relativeRotation: Quat.fromPitchYawRollDegrees(0, 90, -90)
}
diff --git a/examples/toybox/bubblewand/createWand.js b/examples/toybox/bubblewand/createWand.js
index 6b4f9717ec..efd86b046f 100644
--- a/examples/toybox/bubblewand/createWand.js
+++ b/examples/toybox/bubblewand/createWand.js
@@ -53,8 +53,13 @@ var wand = Entities.addEntity({
y: 0.1,
z: 0
},
- relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 90)
+ relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, -90)
}
}
})
-});
\ No newline at end of file
+});
+
+function scriptEnding() {
+ Entities.deleteEntity(wand);
+}
+Script.scriptEnding.connect(scriptEnding);
diff --git a/examples/toybox/flashlight/flashlight.js b/examples/toybox/flashlight/flashlight.js
index 8911c0ecd8..251ca71b7a 100644
--- a/examples/toybox/flashlight/flashlight.js
+++ b/examples/toybox/flashlight/flashlight.js
@@ -25,7 +25,7 @@
//we are creating lights that we don't want to get stranded so lets make sure that we can get rid of them
var startTime = Date.now();
//if you're going to be using this in a dungeon or something and holding it for a long time, increase this lifetime value.
- var LIFETIME = 25;
+ var LIFETIME = 100;
var MSEC_PER_SEC = 1000.0;
// this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember
@@ -85,9 +85,14 @@
this.hand = 'LEFT';
},
- startNearGrab: function() {
+ startNearGrab: function(entityID) {
if (!this.hasSpotlight) {
+ var modelProperties = Entities.getEntityProperties(this.entityID, ['position', 'rotation']);
+ var lightTransform = evalLightWorldTransform(modelProperties.position, modelProperties.rotation);
+ var glowLightTransform = glowLightWorldTransform(modelProperties.position, modelProperties.rotation);
+
+
//this light casts the beam
this.spotlight = Entities.addEntity({
type: "Light",
@@ -97,6 +102,7 @@
y: 2,
z: 20
},
+ parentID: this.entityID,
color: {
red: 255,
green: 255,
@@ -105,7 +111,9 @@
intensity: 2,
exponent: 0.3,
cutoff: 20,
- lifetime: LIFETIME
+ lifetime: LIFETIME,
+ position: lightTransform.p,
+ rotation: lightTransform.q,
});
//this light creates the effect of a bulb at the end of the flashlight
@@ -116,6 +124,7 @@
y: 0.25,
z: 0.25
},
+ parentID: this.entityID,
isSpotlight: false,
color: {
red: 255,
@@ -123,8 +132,11 @@
blue: 255
},
exponent: 0,
+ lifetime: LIFETIME,
cutoff: 90, // in degrees
- lifetime: LIFETIME
+ position: glowLightTransform.p,
+ rotation: glowLightTransform.q,
+
});
this.hasSpotlight = true;
@@ -142,7 +154,6 @@
//only set the active hand once -- if we always read the current hand, our 'holding' hand will get overwritten
this.setWhichHand();
} else {
- this.updateLightPositions();
this.changeLightWithTriggerPressure(this.whichHand);
}
},
@@ -159,29 +170,7 @@
this.lightOn = false;
}
},
-
- updateLightPositions: function() {
- var modelProperties = Entities.getEntityProperties(this.entityID, ['position', 'rotation']);
-
- //move the two lights along the vectors we set above
- var lightTransform = evalLightWorldTransform(modelProperties.position, modelProperties.rotation);
- var glowLightTransform = glowLightWorldTransform(modelProperties.position, modelProperties.rotation);
-
- //move them with the entity model
- Entities.editEntity(this.spotlight, {
- position: lightTransform.p,
- rotation: lightTransform.q,
- lifetime: (Date.now() - startTime) / MSEC_PER_SEC + LIFETIME
- });
-
- Entities.editEntity(this.glowLight, {
- position: glowLightTransform.p,
- rotation: glowLightTransform.q,
- lifetime: (Date.now() - startTime) / MSEC_PER_SEC + LIFETIME
- });
-
- },
-
+
changeLightWithTriggerPressure: function(flashLightHand) {
if (flashLightHand === 'LEFT') {
diff --git a/examples/toybox/pistol/createPistol.js b/examples/toybox/pistol/createPistol.js
index d804150cbe..693c53b9b4 100644
--- a/examples/toybox/pistol/createPistol.js
+++ b/examples/toybox/pistol/createPistol.js
@@ -28,10 +28,10 @@ var pistol = Entities.addEntity({
spatialKey: {
relativePosition: {
x: 0,
- y: 0,
- z: 0
+ y: 0.05,
+ z: -0.08
},
- relativeRotation: Quat.fromPitchYawRollDegrees(45, 90, 0)
+ relativeRotation: Quat.fromPitchYawRollDegrees(90, 90, 0)
},
invertSolidWhileHeld: true
}
diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp
index 6637331b64..34821e6737 100644
--- a/interface/src/avatar/MyAvatar.cpp
+++ b/interface/src/avatar/MyAvatar.cpp
@@ -1058,7 +1058,7 @@ void MyAvatar::rebuildSkeletonBody() {
void MyAvatar::prepareForPhysicsSimulation() {
relayDriveKeysToCharacterController();
_characterController.setTargetVelocity(getTargetVelocity());
- _characterController.setAvatarPositionAndOrientation(getPosition(), getOrientation());
+ _characterController.setPositionAndOrientation(getPosition(), getOrientation());
if (qApp->isHMDMode()) {
updateHMDFollowVelocity();
} else if (_followSpeed > 0.0f) {
@@ -1071,7 +1071,7 @@ void MyAvatar::prepareForPhysicsSimulation() {
void MyAvatar::harvestResultsFromPhysicsSimulation() {
glm::vec3 position = getPosition();
glm::quat orientation = getOrientation();
- _characterController.getAvatarPositionAndOrientation(position, orientation);
+ _characterController.getPositionAndOrientation(position, orientation);
nextAttitude(position, orientation);
if (_followSpeed > 0.0f) {
adjustSensorTransform();
diff --git a/interface/src/avatar/MyCharacterController.cpp b/interface/src/avatar/MyCharacterController.cpp
index e8f686da6f..23d601e58e 100644
--- a/interface/src/avatar/MyCharacterController.cpp
+++ b/interface/src/avatar/MyCharacterController.cpp
@@ -11,255 +11,25 @@
#include "MyCharacterController.h"
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
+#include
#include "MyAvatar.h"
-const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f);
-const float DEFAULT_GRAVITY = -5.0f;
-const float JUMP_SPEED = 3.5f;
-
-const float MAX_FALL_HEIGHT = 20.0f;
-
// TODO: improve walking up steps
// TODO: make avatars able to walk up and down steps/slopes
// TODO: make avatars stand on steep slope
// TODO: make avatars not snag on low ceilings
-// helper class for simple ray-traces from character
-class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback {
-public:
- ClosestNotMe(btRigidBody* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0f, 0.0f, 0.0f), btVector3(0.0f, 0.0f, 0.0f)) {
- _me = me;
- }
- virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) {
- if (rayResult.m_collisionObject == _me) {
- return 1.0f;
- }
- return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
- }
-protected:
- btRigidBody* _me;
-};
-
MyCharacterController::MyCharacterController(MyAvatar* avatar) {
- _halfHeight = 1.0f;
assert(avatar);
_avatar = avatar;
-
- _enabled = false;
-
- _floorDistance = MAX_FALL_HEIGHT;
-
- _walkVelocity.setValue(0.0f, 0.0f, 0.0f);
- _followVelocity.setValue(0.0f, 0.0f, 0.0f);
- _jumpSpeed = JUMP_SPEED;
- _isOnGround = false;
- _isJumping = false;
- _isFalling = false;
- _isHovering = true;
- _isPushingUp = false;
- _jumpToHoverStart = 0;
- _followTime = 0.0f;
-
- _pendingFlags = PENDING_FLAG_UPDATE_SHAPE;
updateShapeIfNecessary();
}
MyCharacterController::~MyCharacterController() {
}
-void MyCharacterController::preStep(btCollisionWorld* collisionWorld) {
- // trace a ray straight down to see if we're standing on the ground
- const btTransform& xform = _rigidBody->getWorldTransform();
-
- // rayStart is at center of bottom sphere
- btVector3 rayStart = xform.getOrigin() - _halfHeight * _currentUp;
-
- // rayEnd is some short distance outside bottom sphere
- const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius;
- btScalar rayLength = _radius + FLOOR_PROXIMITY_THRESHOLD;
- btVector3 rayEnd = rayStart - rayLength * _currentUp;
-
- // scan down for nearby floor
- ClosestNotMe rayCallback(_rigidBody);
- rayCallback.m_closestHitFraction = 1.0f;
- collisionWorld->rayTest(rayStart, rayEnd, rayCallback);
- if (rayCallback.hasHit()) {
- _floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius;
- }
-}
-
-void MyCharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) {
- btVector3 actualVelocity = _rigidBody->getLinearVelocity();
- btScalar actualSpeed = actualVelocity.length();
-
- btVector3 desiredVelocity = _walkVelocity;
- btScalar desiredSpeed = desiredVelocity.length();
-
- const btScalar MIN_UP_PUSH = 0.1f;
- if (desiredVelocity.dot(_currentUp) < MIN_UP_PUSH) {
- _isPushingUp = false;
- }
-
- const btScalar MIN_SPEED = 0.001f;
- if (_isHovering) {
- if (desiredSpeed < MIN_SPEED) {
- if (actualSpeed < MIN_SPEED) {
- _rigidBody->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f));
- } else {
- const btScalar HOVER_BRAKING_TIMESCALE = 0.1f;
- btScalar tau = glm::max(dt / HOVER_BRAKING_TIMESCALE, 1.0f);
- _rigidBody->setLinearVelocity((1.0f - tau) * actualVelocity);
- }
- } else {
- const btScalar HOVER_ACCELERATION_TIMESCALE = 0.1f;
- btScalar tau = dt / HOVER_ACCELERATION_TIMESCALE;
- _rigidBody->setLinearVelocity(actualVelocity - tau * (actualVelocity - desiredVelocity));
- }
- } else {
- if (onGround()) {
- // walking on ground
- if (desiredSpeed < MIN_SPEED) {
- if (actualSpeed < MIN_SPEED) {
- _rigidBody->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f));
- } else {
- const btScalar HOVER_BRAKING_TIMESCALE = 0.1f;
- btScalar tau = dt / HOVER_BRAKING_TIMESCALE;
- _rigidBody->setLinearVelocity((1.0f - tau) * actualVelocity);
- }
- } else {
- // TODO: modify desiredVelocity using floor normal
- const btScalar WALK_ACCELERATION_TIMESCALE = 0.1f;
- btScalar tau = dt / WALK_ACCELERATION_TIMESCALE;
- btVector3 velocityCorrection = tau * (desiredVelocity - actualVelocity);
- // subtract vertical component
- velocityCorrection -= velocityCorrection.dot(_currentUp) * _currentUp;
- _rigidBody->setLinearVelocity(actualVelocity + velocityCorrection);
- }
- } else {
- // transitioning to flying
- btVector3 velocityCorrection = desiredVelocity - actualVelocity;
- const btScalar FLY_ACCELERATION_TIMESCALE = 0.2f;
- btScalar tau = dt / FLY_ACCELERATION_TIMESCALE;
- if (!_isPushingUp) {
- // actually falling --> compute a different velocity attenuation factor
- const btScalar FALL_ACCELERATION_TIMESCALE = 2.0f;
- tau = dt / FALL_ACCELERATION_TIMESCALE;
- // zero vertical component
- velocityCorrection -= velocityCorrection.dot(_currentUp) * _currentUp;
- }
- _rigidBody->setLinearVelocity(actualVelocity + tau * velocityCorrection);
- }
- }
-
- // Rather than add _followVelocity to the velocity of the RigidBody, we explicitly teleport
- // the RigidBody forward according to the formula: distance = rate * time
- if (_followVelocity.length2() > 0.0f) {
- btTransform bodyTransform = _rigidBody->getWorldTransform();
- bodyTransform.setOrigin(bodyTransform.getOrigin() + dt * _followVelocity);
- _rigidBody->setWorldTransform(bodyTransform);
- }
- _followTime += dt;
-}
-
-void MyCharacterController::jump() {
- // check for case where user is holding down "jump" key...
- // we'll eventually tansition to "hover"
- if (!_isJumping) {
- if (!_isHovering) {
- _jumpToHoverStart = usecTimestampNow();
- _pendingFlags |= PENDING_FLAG_JUMP;
- }
- } else {
- quint64 now = usecTimestampNow();
- const quint64 JUMP_TO_HOVER_PERIOD = 75 * (USECS_PER_SECOND / 100);
- if (now - _jumpToHoverStart > JUMP_TO_HOVER_PERIOD) {
- _isPushingUp = true;
- setHovering(true);
- }
- }
-}
-
-bool MyCharacterController::onGround() const {
- const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius;
- return _floorDistance < FLOOR_PROXIMITY_THRESHOLD;
-}
-
-void MyCharacterController::setHovering(bool hover) {
- if (hover != _isHovering) {
- _isHovering = hover;
- _isJumping = false;
-
- if (_rigidBody) {
- if (hover) {
- _rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f));
- } else {
- _rigidBody->setGravity(DEFAULT_GRAVITY * _currentUp);
- }
- }
- }
-}
-
-void MyCharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) {
- _boxScale = scale;
-
- float x = _boxScale.x;
- float z = _boxScale.z;
- float radius = 0.5f * sqrtf(0.5f * (x * x + z * z));
- float halfHeight = 0.5f * _boxScale.y - radius;
- float MIN_HALF_HEIGHT = 0.1f;
- if (halfHeight < MIN_HALF_HEIGHT) {
- halfHeight = MIN_HALF_HEIGHT;
- }
-
- // compare dimensions
- float radiusDelta = glm::abs(radius - _radius);
- float heightDelta = glm::abs(halfHeight - _halfHeight);
- if (radiusDelta < FLT_EPSILON && heightDelta < FLT_EPSILON) {
- // shape hasn't changed --> nothing to do
- } else {
- if (_dynamicsWorld) {
- // must REMOVE from world prior to shape update
- _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION;
- }
- _pendingFlags |= PENDING_FLAG_UPDATE_SHAPE;
- // only need to ADD back when we happen to be enabled
- if (_enabled) {
- _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION;
- }
- }
-
- // it's ok to change offset immediately -- there are no thread safety issues here
- _shapeLocalOffset = corner + 0.5f * _boxScale;
-}
-
-void MyCharacterController::setEnabled(bool enabled) {
- if (enabled != _enabled) {
- if (enabled) {
- // Don't bother clearing REMOVE bit since it might be paired with an UPDATE_SHAPE bit.
- // Setting the ADD bit here works for all cases so we don't even bother checking other bits.
- _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION;
- } else {
- if (_dynamicsWorld) {
- _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION;
- }
- _pendingFlags &= ~ PENDING_FLAG_ADD_TO_SIMULATION;
- _isOnGround = false;
- }
- setHovering(true);
- _enabled = enabled;
- }
-}
-
void MyCharacterController::updateShapeIfNecessary() {
if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) {
_pendingFlags &= ~ PENDING_FLAG_UPDATE_SHAPE;
@@ -300,7 +70,7 @@ void MyCharacterController::updateShapeIfNecessary() {
if (_isHovering) {
_rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f));
} else {
- _rigidBody->setGravity(DEFAULT_GRAVITY * _currentUp);
+ _rigidBody->setGravity(DEFAULT_CHARACTER_GRAVITY * _currentUp);
}
//_rigidBody->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
} else {
@@ -309,98 +79,3 @@ void MyCharacterController::updateShapeIfNecessary() {
}
}
-void MyCharacterController::updateUpAxis(const glm::quat& rotation) {
- btVector3 oldUp = _currentUp;
- _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS);
- if (!_isHovering) {
- const btScalar MIN_UP_ERROR = 0.01f;
- if (oldUp.distance(_currentUp) > MIN_UP_ERROR) {
- _rigidBody->setGravity(DEFAULT_GRAVITY * _currentUp);
- }
- }
-}
-
-void MyCharacterController::setAvatarPositionAndOrientation(
- const glm::vec3& position,
- const glm::quat& orientation) {
- // TODO: update gravity if up has changed
- updateUpAxis(orientation);
-
- btQuaternion bodyOrientation = glmToBullet(orientation);
- btVector3 bodyPosition = glmToBullet(position + orientation * _shapeLocalOffset);
- _avatarBodyTransform = btTransform(bodyOrientation, bodyPosition);
-}
-
-void MyCharacterController::getAvatarPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const {
- if (_enabled && _rigidBody) {
- const btTransform& avatarTransform = _rigidBody->getWorldTransform();
- rotation = bulletToGLM(avatarTransform.getRotation());
- position = bulletToGLM(avatarTransform.getOrigin()) - rotation * _shapeLocalOffset;
- }
-}
-
-void MyCharacterController::setTargetVelocity(const glm::vec3& velocity) {
- //_walkVelocity = glmToBullet(_avatarData->getTargetVelocity());
- _walkVelocity = glmToBullet(velocity);
-}
-
-void MyCharacterController::setFollowVelocity(const glm::vec3& velocity) {
- _followVelocity = glmToBullet(velocity);
-}
-
-glm::vec3 MyCharacterController::getLinearVelocity() const {
- glm::vec3 velocity(0.0f);
- if (_rigidBody) {
- velocity = bulletToGLM(_rigidBody->getLinearVelocity());
- }
- return velocity;
-}
-
-void MyCharacterController::preSimulation() {
- if (_enabled && _dynamicsWorld) {
- // slam body to where it is supposed to be
- _rigidBody->setWorldTransform(_avatarBodyTransform);
-
- // scan for distant floor
- // rayStart is at center of bottom sphere
- btVector3 rayStart = _avatarBodyTransform.getOrigin() - _halfHeight * _currentUp;
-
- // rayEnd is straight down MAX_FALL_HEIGHT
- btScalar rayLength = _radius + MAX_FALL_HEIGHT;
- btVector3 rayEnd = rayStart - rayLength * _currentUp;
-
- ClosestNotMe rayCallback(_rigidBody);
- rayCallback.m_closestHitFraction = 1.0f;
- _dynamicsWorld->rayTest(rayStart, rayEnd, rayCallback);
- if (rayCallback.hasHit()) {
- _floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius;
- const btScalar MIN_HOVER_HEIGHT = 3.0f;
- if (_isHovering && _floorDistance < MIN_HOVER_HEIGHT && !_isPushingUp) {
- setHovering(false);
- }
- // TODO: use collision events rather than ray-trace test to disable jumping
- const btScalar JUMP_PROXIMITY_THRESHOLD = 0.1f * _radius;
- if (_floorDistance < JUMP_PROXIMITY_THRESHOLD) {
- _isJumping = false;
- }
- } else {
- _floorDistance = FLT_MAX;
- setHovering(true);
- }
-
- if (_pendingFlags & PENDING_FLAG_JUMP) {
- _pendingFlags &= ~ PENDING_FLAG_JUMP;
- if (onGround()) {
- _isJumping = true;
- btVector3 velocity = _rigidBody->getLinearVelocity();
- velocity += _jumpSpeed * _currentUp;
- _rigidBody->setLinearVelocity(velocity);
- }
- }
- }
- _followTime = 0.0f;
-}
-
-void MyCharacterController::postSimulation() {
- // postSimulation() exists for symmetry and just in case we need to do something here later
-}
diff --git a/interface/src/avatar/MyCharacterController.h b/interface/src/avatar/MyCharacterController.h
index 82aa958309..39f0f99917 100644
--- a/interface/src/avatar/MyCharacterController.h
+++ b/interface/src/avatar/MyCharacterController.h
@@ -13,12 +13,8 @@
#ifndef hifi_MyCharacterController_h
#define hifi_MyCharacterController_h
-#include
-#include
-
-#include
#include
-#include
+//#include
class btCollisionShape;
class MyAvatar;
@@ -28,79 +24,10 @@ public:
MyCharacterController(MyAvatar* avatar);
~MyCharacterController ();
- // TODO: implement these when needed
- virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) override { assert(false); }
- virtual void reset(btCollisionWorld* collisionWorld) override { }
- virtual void warp(const btVector3& origin) override { }
- virtual void debugDraw(btIDebugDraw* debugDrawer) override { }
- virtual void setUpInterpolate(bool value) override { }
-
- // overrides from btCharacterControllerInterface
- virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTime) override {
- preStep(collisionWorld);
- playerStep(collisionWorld, deltaTime);
- }
- virtual void preStep(btCollisionWorld* collisionWorld) override;
- virtual void playerStep(btCollisionWorld* collisionWorld, btScalar dt) override;
- virtual bool canJump() const override { assert(false); return false; } // never call this
- virtual void jump() override; // call this every frame the jump button is pressed
- virtual bool onGround() const override;
-
- // overrides from CharacterController
- virtual void preSimulation() override;
- virtual void postSimulation() override;
-
- bool isHovering() const { return _isHovering; }
- void setHovering(bool enabled);
-
- void setEnabled(bool enabled);
- bool isEnabled() const { return _enabled && _dynamicsWorld; }
-
- void setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale);
-
virtual void updateShapeIfNecessary() override;
- void setAvatarPositionAndOrientation( const glm::vec3& position, const glm::quat& orientation);
- void getAvatarPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const;
-
- void setTargetVelocity(const glm::vec3& velocity);
- void setFollowVelocity(const glm::vec3& velocity);
- float getFollowTime() const { return _followTime; }
-
- glm::vec3 getLinearVelocity() const;
-
protected:
- void updateUpAxis(const glm::quat& rotation);
-
-protected:
- btVector3 _currentUp;
- btVector3 _walkVelocity;
- btVector3 _followVelocity;
- btTransform _avatarBodyTransform;
-
- glm::vec3 _shapeLocalOffset;
- glm::vec3 _boxScale; // used to compute capsule shape
-
- quint64 _jumpToHoverStart;
-
MyAvatar* _avatar { nullptr };
-
- btScalar _halfHeight;
- btScalar _radius;
-
- btScalar _floorDistance;
-
- btScalar _gravity;
-
- btScalar _jumpSpeed;
- btScalar _followTime;
-
- bool _enabled;
- bool _isOnGround;
- bool _isJumping;
- bool _isFalling;
- bool _isHovering;
- bool _isPushingUp;
};
#endif // hifi_MyCharacterController_h
diff --git a/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp
index 6c34612e8c..08368597d0 100644
--- a/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp
+++ b/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp
@@ -14,8 +14,6 @@
#include "stereo/InterleavedStereoDisplayPlugin.h"
#include "Basic2DWindowOpenGLDisplayPlugin.h"
-#include "openvr/OpenVrDisplayPlugin.h"
-
const QString& DisplayPlugin::MENU_PATH() {
static const QString value = "Display";
return value;
@@ -25,22 +23,14 @@ const QString& DisplayPlugin::MENU_PATH() {
DisplayPluginList getDisplayPlugins() {
DisplayPlugin* PLUGIN_POOL[] = {
new Basic2DWindowOpenGLDisplayPlugin(),
- new NullDisplayPlugin(),
#ifdef DEBUG
+ new NullDisplayPlugin(),
#endif
-
// Stereo modes
-
// SBS left/right
new SideBySideStereoDisplayPlugin(),
// Interleaved left/right
new InterleavedStereoDisplayPlugin(),
-
- // HMDs
-//#ifdef Q_OS_WIN
-// // SteamVR SDK
-// new OpenVrDisplayPlugin(),
-//#endif
nullptr
};
diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp
index 80710e9b96..880e4a16b3 100644
--- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp
+++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp
@@ -15,6 +15,7 @@
#include
#include
+#include
#include
#include
@@ -103,8 +104,12 @@ public:
// take the latest texture and present it
_context->makeCurrent();
- currentPlugin->present();
- _context->doneCurrent();
+ if (QOpenGLContext::currentContext() == _context->contextHandle()) {
+ currentPlugin->present();
+ _context->doneCurrent();
+ } else {
+ qWarning() << "Makecurrent failed";
+ }
}
_context->makeCurrent();
diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h
index 88ccddc125..72211056d9 100644
--- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h
+++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h
@@ -74,7 +74,7 @@ protected:
ProgramPtr _program;
ShapeWrapperPtr _plane;
- Mutex _mutex;
+ mutable Mutex _mutex;
SimpleMovingAverage _usecsPerFrame { 10 };
QMap _sceneTextureToFrameIndexMap;
diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp
index 43c6373147..edbfb6158c 100644
--- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp
+++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp
@@ -60,9 +60,6 @@ public:
void setTexture(gpu::TexturePointer texture) { _texture = texture; }
const gpu::TexturePointer& getTexture() const { return _texture; }
- bool getVisibleFlag() const { return _visibleFlag; }
- void setVisibleFlag(bool visibleFlag) { _visibleFlag = visibleFlag; }
-
void render(RenderArgs* args) const {
assert(_pipeline);
@@ -81,23 +78,23 @@ public:
auto numIndices = _indexBuffer->getSize() / sizeof(uint16_t);
batch.drawIndexed(gpu::TRIANGLES, numIndices);
}
+
+ EntityItemPointer _entity;
protected:
- EntityItemPointer _entity;
Transform _modelTransform;
AABox _bound;
gpu::PipelinePointer _pipeline;
gpu::Stream::FormatPointer _vertexFormat;
gpu::BufferPointer _vertexBuffer;
gpu::BufferPointer _indexBuffer;
- gpu::TexturePointer _texture;
- bool _visibleFlag = true;
+ gpu::TexturePointer _texture;
};
namespace render {
template <>
const ItemKey payloadGetKey(const ParticlePayload::Pointer& payload) {
- if (payload->getVisibleFlag()) {
+ if (payload->_entity->getVisible()) {
return ItemKey::Builder::transparentShape();
} else {
return ItemKey::Builder().withInvisible().build();
@@ -111,7 +108,10 @@ namespace render {
template <>
void payloadRender(const ParticlePayload::Pointer& payload, RenderArgs* args) {
- payload->render(args);
+ if (payload->_entity->getVisible()) {
+ payload->render(args);
+ }
+
}
}
diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp
index f9d8c07443..ef89128e30 100644
--- a/libraries/entities/src/AnimationPropertyGroup.cpp
+++ b/libraries/entities/src/AnimationPropertyGroup.cpp
@@ -29,7 +29,6 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame, _animationLoop->getFirstFrame);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame, _animationLoop->getLastFrame);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold, _animationLoop->getHold);
- COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically, _animationLoop->getStartAutomatically);
} else {
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, Animation, animation, FPS, fps);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, CurrentFrame, currentFrame);
@@ -38,7 +37,6 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold);
- COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically);
}
}
@@ -58,7 +56,6 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, _animationLoop->setFirstFrame);
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, _animationLoop->setLastFrame);
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, _animationLoop->setHold);
- COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, _animationLoop->setStartAutomatically);
// legacy property support
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, _animationLoop->setFPS, _animationLoop->getFPS);
@@ -73,7 +70,6 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, setFirstFrame);
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, setLastFrame);
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, setHold);
- COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, setStartAutomatically);
// legacy property support
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, setFPS, getFPS);
@@ -95,7 +91,6 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) {
float lastFrame = _animationLoop ? _animationLoop->getLastFrame() : getLastFrame();
bool loop = _animationLoop ? _animationLoop->getLoop() : getLoop();
bool hold = _animationLoop ? _animationLoop->getHold() : getHold();
- bool startAutomatically = _animationLoop ? _animationLoop->getStartAutomatically() : getStartAutomatically();
QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8());
QJsonObject settingsAsJsonObject = settingsAsJson.object();
@@ -130,10 +125,6 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) {
running = settingsMap["hold"].toBool();
}
- if (settingsMap.contains("startAutomatically")) {
- running = settingsMap["startAutomatically"].toBool();
- }
-
if (_animationLoop) {
_animationLoop->setFPS(fps);
_animationLoop->setCurrentFrame(currentFrame);
@@ -142,7 +133,6 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) {
_animationLoop->setLastFrame(lastFrame);
_animationLoop->setLoop(loop);
_animationLoop->setHold(hold);
- _animationLoop->setStartAutomatically(startAutomatically);
} else {
setFPS(fps);
setCurrentFrame(currentFrame);
@@ -151,7 +141,6 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) {
setLastFrame(lastFrame);
setLoop(loop);
setHold(hold);
- setStartAutomatically(startAutomatically);
}
}
@@ -194,7 +183,6 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData,
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold());
- APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically());
} else {
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame());
@@ -203,7 +191,6 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData,
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold());
- APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically());
}
return true;
@@ -226,7 +213,6 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF
READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, _animationLoop->setFirstFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold);
- READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically);
} else {
READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS);
READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame);
@@ -235,7 +221,6 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF
READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold);
- READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically);
}
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_URL, URL);
@@ -246,7 +231,6 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FIRST_FRAME, FirstFrame);
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LAST_FRAME, LastFrame);
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_HOLD, Hold);
- DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically);
processedBytes += bytesRead;
@@ -273,7 +257,6 @@ EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const {
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FIRST_FRAME, firstFrame);
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LAST_FRAME, lastFrame);
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_HOLD, hold);
- CHECK_PROPERTY_CHANGE(PROP_ANIMATION_START_AUTOMATICALLY, startAutomatically);
return changedProperties;
}
@@ -288,7 +271,6 @@ void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) con
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, _animationLoop->getFirstFrame);
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, _animationLoop->getLastFrame);
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, _animationLoop->getHold);
- COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, _animationLoop->getStartAutomatically);
} else {
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, getFPS);
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, CurrentFrame, getCurrentFrame);
@@ -297,7 +279,6 @@ void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) con
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, getFirstFrame);
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, getLastFrame);
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, getHold);
- COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, getStartAutomatically);
}
}
@@ -313,7 +294,6 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, _animationLoop->setFirstFrame);
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, _animationLoop->setLastFrame);
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, _animationLoop->setHold);
- SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, _animationLoop->setStartAutomatically);
} else {
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, setFPS);
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, CurrentFrame, currentFrame, setCurrentFrame);
@@ -322,7 +302,6 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, setFirstFrame);
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, setLastFrame);
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, setHold);
- SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, setStartAutomatically);
}
return somethingChanged;
@@ -339,7 +318,6 @@ EntityPropertyFlags AnimationPropertyGroup::getEntityProperties(EncodeBitstreamP
requestedProperties += PROP_ANIMATION_FIRST_FRAME;
requestedProperties += PROP_ANIMATION_LAST_FRAME;
requestedProperties += PROP_ANIMATION_HOLD;
- requestedProperties += PROP_ANIMATION_START_AUTOMATICALLY;
return requestedProperties;
}
@@ -363,7 +341,6 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold());
- APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically());
} else {
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame());
@@ -372,7 +349,6 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold());
- APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically());
}
}
@@ -395,7 +371,6 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char
READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, _animationLoop->setFirstFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold);
- READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically);
} else {
READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS);
READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame);
@@ -404,7 +379,6 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char
READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold);
- READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically);
}
return bytesRead;
diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h
index 8c40b0c036..8e85d8bc99 100644
--- a/libraries/entities/src/AnimationPropertyGroup.h
+++ b/libraries/entities/src/AnimationPropertyGroup.h
@@ -80,7 +80,6 @@ public:
DEFINE_PROPERTY(PROP_ANIMATION_FIRST_FRAME, FirstFrame, firstFrame, float, 0.0f); // was animationSettings.firstFrame
DEFINE_PROPERTY(PROP_ANIMATION_LAST_FRAME, LastFrame, lastFrame, float, AnimationLoop::MAXIMUM_POSSIBLE_FRAME); // was animationSettings.lastFrame
DEFINE_PROPERTY(PROP_ANIMATION_HOLD, Hold, hold, bool, false); // was animationSettings.hold
- DEFINE_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically, startAutomatically, bool, false); // was animationSettings.startAutomatically
protected:
void setFromOldAnimationSettings(const QString& value);
diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp
index d040f785da..2e785519da 100644
--- a/libraries/entities/src/EntityItemProperties.cpp
+++ b/libraries/entities/src/EntityItemProperties.cpp
@@ -747,7 +747,6 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame);
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame);
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold);
- ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically);
ADD_GROUP_PROPERTY_TO_MAP(PROP_ATMOSPHERE_CENTER, Atmosphere, atmosphere, Center, center);
ADD_GROUP_PROPERTY_TO_MAP(PROP_ATMOSPHERE_INNER_RADIUS, Atmosphere, atmosphere, InnerRadius, innerRadius);
diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp
index b0b0e7c76a..d96814ff04 100644
--- a/libraries/entities/src/ModelEntityItem.cpp
+++ b/libraries/entities/src/ModelEntityItem.cpp
@@ -384,11 +384,6 @@ void ModelEntityItem::setAnimationSettings(const QString& value) {
setAnimationHold(hold);
}
- if (settingsMap.contains("startAutomatically")) {
- bool startAutomatically = settingsMap["startAutomatically"].toBool();
- setAnimationStartAutomatically(startAutomatically);
- }
-
_dirtyFlags |= Simulation::DIRTY_UPDATEABLE;
}
diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h
index cbd54f7168..2b8121c2f6 100644
--- a/libraries/entities/src/ModelEntityItem.h
+++ b/libraries/entities/src/ModelEntityItem.h
@@ -97,9 +97,6 @@ public:
void setAnimationHold(bool hold) { _animationLoop.setHold(hold); }
bool getAnimationHold() const { return _animationLoop.getHold(); }
- void setAnimationStartAutomatically(bool startAutomatically) { _animationLoop.setStartAutomatically(startAutomatically); }
- bool getAnimationStartAutomatically() const { return _animationLoop.getStartAutomatically(); }
-
void setAnimationFirstFrame(float firstFrame) { _animationLoop.setFirstFrame(firstFrame); }
float getAnimationFirstFrame() const { return _animationLoop.getFirstFrame(); }
diff --git a/libraries/input-plugins/CMakeLists.txt b/libraries/input-plugins/CMakeLists.txt
index 0e21d4a40c..b81554511d 100644
--- a/libraries/input-plugins/CMakeLists.txt
+++ b/libraries/input-plugins/CMakeLists.txt
@@ -1,15 +1,5 @@
set(TARGET_NAME input-plugins)
setup_hifi_library()
-link_hifi_libraries(shared plugins controllers script-engine render-utils)
+link_hifi_libraries(shared plugins controllers)
GroupSources("src/input-plugins")
-
-if (WIN32)
- add_dependency_external_projects(OpenVR)
- find_package(OpenVR REQUIRED)
- target_include_directories(${TARGET_NAME} PRIVATE ${OPENVR_INCLUDE_DIRS})
- target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES})
-endif()
-
-target_sdl2()
-target_sixense()
diff --git a/libraries/input-plugins/src/input-plugins/InputPlugin.cpp b/libraries/input-plugins/src/input-plugins/InputPlugin.cpp
index 6db35572b5..4b79572a07 100644
--- a/libraries/input-plugins/src/input-plugins/InputPlugin.cpp
+++ b/libraries/input-plugins/src/input-plugins/InputPlugin.cpp
@@ -15,7 +15,6 @@
#include "KeyboardMouseDevice.h"
#include "SDL2Manager.h"
#include "SixenseManager.h"
-#include "ViveControllerManager.h"
// TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class
InputPluginList getInputPlugins() {
@@ -23,7 +22,6 @@ InputPluginList getInputPlugins() {
new KeyboardMouseDevice(),
new SDL2Manager(),
new SixenseManager(),
- new ViveControllerManager(),
nullptr
};
diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp
index 5dd0248224..3b08c218a2 100644
--- a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp
+++ b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp
@@ -21,6 +21,7 @@
#include
#include
+#include
#include
#include
#include
@@ -48,6 +49,8 @@ const QString MENU_PARENT = "Avatar";
const QString MENU_NAME = "Sixense";
const QString MENU_PATH = MENU_PARENT + ">" + MENU_NAME;
const QString TOGGLE_SMOOTH = "Smooth Sixense Movement";
+const QString SHOW_DEBUG_RAW = "Debug Draw Raw Data";
+const QString SHOW_DEBUG_CALIBRATED = "Debug Draw Calibrated Data";
bool SixenseManager::isSupported() const {
#ifdef HAVE_SIXENSE
@@ -72,6 +75,14 @@ void SixenseManager::activate() {
[this] (bool clicked) { setSixenseFilter(clicked); },
true, true);
+ _container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, SHOW_DEBUG_RAW,
+ [this] (bool clicked) { _inputDevice->setDebugDrawRaw(clicked); },
+ true, false);
+
+ _container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, SHOW_DEBUG_CALIBRATED,
+ [this] (bool clicked) { _inputDevice->setDebugDrawCalibrated(clicked); },
+ true, false);
+
auto userInputMapper = DependencyManager::get();
userInputMapper->registerDevice(_inputDevice);
@@ -149,6 +160,9 @@ void SixenseManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
// we only support two controllers
SixenseControllerData controllers[2];
+ // store the raw controller data for debug rendering
+ controller::Pose rawPoses[2];
+
int numActiveControllers = 0;
for (int i = 0; i < maxControllers && numActiveControllers < 2; i++) {
if (!sixenseIsControllerEnabled(i)) {
@@ -175,7 +189,7 @@ void SixenseManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
// Rotation of Palm
glm::quat rotation(data->rot_quat[3], data->rot_quat[0], data->rot_quat[1], data->rot_quat[2]);
handlePoseEvent(deltaTime, position, rotation, left);
-
+ rawPoses[i] = controller::Pose(position, rotation, glm::vec3(0), glm::quat());
} else {
_poseStateMap.clear();
_collectedSamples.clear();
@@ -197,9 +211,54 @@ void SixenseManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
_axisStateMap[axisState.first] = 0.0f;
}
}
+
+ if (_debugDrawCalibrated) {
+ auto poseIter = _poseStateMap.find(controller::StandardPoseChannel::LEFT_HAND);
+ if (poseIter != _poseStateMap.end() && poseIter->second.isValid()) {
+ DebugDraw::getInstance().addMyAvatarMarker("SIXENSE_CALIBRATED_LEFT", poseIter->second.rotation, poseIter->second.translation, glm::vec4(1));
+ } else {
+ DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_CALIBRATED_LEFT");
+ }
+ poseIter = _poseStateMap.find(controller::StandardPoseChannel::RIGHT_HAND);
+ if (poseIter != _poseStateMap.end() && poseIter->second.isValid()) {
+ DebugDraw::getInstance().addMyAvatarMarker("SIXENSE_CALIBRATED_RIGHT", poseIter->second.rotation, poseIter->second.translation, glm::vec4(1));
+ } else {
+ DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_CALIBRATED_RIGHT");
+ }
+ }
+
+ if (_debugDrawRaw) {
+ if (rawPoses[0].isValid()) {
+ DebugDraw::getInstance().addMyAvatarMarker("SIXENSE_RAW_LEFT", rawPoses[0].rotation, rawPoses[0].translation, glm::vec4(1));
+ } else {
+ DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_RAW_LEFT");
+ }
+ if (rawPoses[1].isValid()) {
+ DebugDraw::getInstance().addMyAvatarMarker("SIXENSE_RAW_RIGHT", rawPoses[1].rotation, rawPoses[1].translation, glm::vec4(1));
+ } else {
+ DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_RAW_RIGHT");
+ }
+ }
+
#endif // HAVE_SIXENSE
}
+void SixenseManager::InputDevice::setDebugDrawRaw(bool flag) {
+ _debugDrawRaw = flag;
+ if (!flag) {
+ DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_RAW_LEFT");
+ DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_RAW_RIGHT");
+ }
+}
+
+void SixenseManager::InputDevice::setDebugDrawCalibrated(bool flag) {
+ _debugDrawCalibrated = flag;
+ if (!flag) {
+ DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_CALIBRATED_LEFT");
+ DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_CALIBRATED_RIGHT");
+ }
+}
+
#ifdef HAVE_SIXENSE
// the calibration sequence is:
diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.h b/libraries/input-plugins/src/input-plugins/SixenseManager.h
index 348a7a4590..b6bf4b24c0 100644
--- a/libraries/input-plugins/src/input-plugins/SixenseManager.h
+++ b/libraries/input-plugins/src/input-plugins/SixenseManager.h
@@ -60,6 +60,8 @@ private:
class InputDevice : public controller::InputDevice {
public:
InputDevice() : controller::InputDevice("Hydra") {}
+ void setDebugDrawRaw(bool flag);
+ void setDebugDrawCalibrated(bool flag);
private:
// Device functions
virtual controller::Input::NamedVector getAvailableInputs() const override;
@@ -82,6 +84,8 @@ private:
float _lastDistance;
bool _requestReset { false };
+ bool _debugDrawRaw { false };
+ bool _debugDrawCalibrated { false };
// these are measured values used to compute the calibration results
quint64 _lockExpiry;
glm::vec3 _averageLeft;
diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp
index 93fbe7acdc..81aae796c1 100644
--- a/libraries/networking/src/udt/PacketHeaders.cpp
+++ b/libraries/networking/src/udt/PacketHeaders.cpp
@@ -41,7 +41,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
case PacketType::EntityAdd:
case PacketType::EntityEdit:
case PacketType::EntityData:
- return VERSION_ENTITIES_HAVE_PARENTS;
+ return VERSION_ENTITITES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP;
case PacketType::AvatarData:
case PacketType::BulkAvatarData:
return 17;
diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h
index cd7b9a113c..ba48c4ccf1 100644
--- a/libraries/networking/src/udt/PacketHeaders.h
+++ b/libraries/networking/src/udt/PacketHeaders.h
@@ -161,5 +161,6 @@ const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP_BIS = 48;
const PacketVersion VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING = 49;
const PacketVersion VERSION_ENTITIES_POLYLINE_TEXTURE = 50;
const PacketVersion VERSION_ENTITIES_HAVE_PARENTS = 51;
+const PacketVersion VERSION_ENTITITES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP = 52;
#endif // hifi_PacketHeaders_h
diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp
index 8da9541387..44d4269e0e 100644
--- a/libraries/physics/src/CharacterController.cpp
+++ b/libraries/physics/src/CharacterController.cpp
@@ -11,8 +11,55 @@
#include "CharacterController.h"
+#include
+
+#include "BulletUtil.h"
#include "PhysicsCollisionGroups.h"
+const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f);
+const float JUMP_SPEED = 3.5f;
+const float MAX_FALL_HEIGHT = 20.0f;
+
+
+// helper class for simple ray-traces from character
+class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback {
+public:
+ ClosestNotMe(btRigidBody* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0f, 0.0f, 0.0f), btVector3(0.0f, 0.0f, 0.0f)) {
+ _me = me;
+ }
+ virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) {
+ if (rayResult.m_collisionObject == _me) {
+ return 1.0f;
+ }
+ return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
+ }
+protected:
+ btRigidBody* _me;
+};
+
+
+CharacterController::CharacterController() {
+ _halfHeight = 1.0f;
+
+ _enabled = false;
+
+ _floorDistance = MAX_FALL_HEIGHT;
+
+ _walkVelocity.setValue(0.0f, 0.0f, 0.0f);
+ _followVelocity.setValue(0.0f, 0.0f, 0.0f);
+ _jumpSpeed = JUMP_SPEED;
+ _isOnGround = false;
+ _isJumping = false;
+ _isFalling = false;
+ _isHovering = true;
+ _isPushingUp = false;
+ _jumpToHoverStart = 0;
+ _followTime = 0.0f;
+
+ _pendingFlags = PENDING_FLAG_UPDATE_SHAPE;
+
+}
+
bool CharacterController::needsRemoval() const {
return ((_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION) == PENDING_FLAG_REMOVE_FROM_SIMULATION);
}
@@ -23,7 +70,7 @@ bool CharacterController::needsAddition() const {
void CharacterController::setDynamicsWorld(btDynamicsWorld* world) {
if (_dynamicsWorld != world) {
- if (_dynamicsWorld) {
+ if (_dynamicsWorld) {
if (_rigidBody) {
_dynamicsWorld->removeRigidBody(_rigidBody);
_dynamicsWorld->removeAction(this);
@@ -33,9 +80,13 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) {
if (world && _rigidBody) {
_dynamicsWorld = world;
_pendingFlags &= ~PENDING_FLAG_JUMP;
+ // Before adding the RigidBody to the world we must save its oldGravity to the side
+ // because adding an object to the world will overwrite it with the default gravity.
+ btVector3 oldGravity = _rigidBody->getGravity();
_dynamicsWorld->addRigidBody(_rigidBody, COLLISION_GROUP_MY_AVATAR, COLLISION_MASK_MY_AVATAR);
_dynamicsWorld->addAction(this);
- //reset(_dynamicsWorld);
+ // restore gravity settings
+ _rigidBody->setGravity(oldGravity);
}
}
if (_dynamicsWorld) {
@@ -48,5 +99,283 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) {
} else {
_pendingFlags &= ~PENDING_FLAG_REMOVE_FROM_SIMULATION;
}
-}
+}
+void CharacterController::preStep(btCollisionWorld* collisionWorld) {
+ // trace a ray straight down to see if we're standing on the ground
+ const btTransform& xform = _rigidBody->getWorldTransform();
+
+ // rayStart is at center of bottom sphere
+ btVector3 rayStart = xform.getOrigin() - _halfHeight * _currentUp;
+
+ // rayEnd is some short distance outside bottom sphere
+ const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius;
+ btScalar rayLength = _radius + FLOOR_PROXIMITY_THRESHOLD;
+ btVector3 rayEnd = rayStart - rayLength * _currentUp;
+
+ // scan down for nearby floor
+ ClosestNotMe rayCallback(_rigidBody);
+ rayCallback.m_closestHitFraction = 1.0f;
+ collisionWorld->rayTest(rayStart, rayEnd, rayCallback);
+ if (rayCallback.hasHit()) {
+ _floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius;
+ }
+}
+
+void CharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) {
+ btVector3 actualVelocity = _rigidBody->getLinearVelocity();
+ btScalar actualSpeed = actualVelocity.length();
+
+ btVector3 desiredVelocity = _walkVelocity;
+ btScalar desiredSpeed = desiredVelocity.length();
+
+ const btScalar MIN_UP_PUSH = 0.1f;
+ if (desiredVelocity.dot(_currentUp) < MIN_UP_PUSH) {
+ _isPushingUp = false;
+ }
+
+ const btScalar MIN_SPEED = 0.001f;
+ if (_isHovering) {
+ if (desiredSpeed < MIN_SPEED) {
+ if (actualSpeed < MIN_SPEED) {
+ _rigidBody->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f));
+ } else {
+ const btScalar HOVER_BRAKING_TIMESCALE = 0.1f;
+ btScalar tau = glm::max(dt / HOVER_BRAKING_TIMESCALE, 1.0f);
+ _rigidBody->setLinearVelocity((1.0f - tau) * actualVelocity);
+ }
+ } else {
+ const btScalar HOVER_ACCELERATION_TIMESCALE = 0.1f;
+ btScalar tau = dt / HOVER_ACCELERATION_TIMESCALE;
+ _rigidBody->setLinearVelocity(actualVelocity - tau * (actualVelocity - desiredVelocity));
+ }
+ } else {
+ if (onGround()) {
+ // walking on ground
+ if (desiredSpeed < MIN_SPEED) {
+ if (actualSpeed < MIN_SPEED) {
+ _rigidBody->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f));
+ } else {
+ const btScalar HOVER_BRAKING_TIMESCALE = 0.1f;
+ btScalar tau = dt / HOVER_BRAKING_TIMESCALE;
+ _rigidBody->setLinearVelocity((1.0f - tau) * actualVelocity);
+ }
+ } else {
+ // TODO: modify desiredVelocity using floor normal
+ const btScalar WALK_ACCELERATION_TIMESCALE = 0.1f;
+ btScalar tau = dt / WALK_ACCELERATION_TIMESCALE;
+ btVector3 velocityCorrection = tau * (desiredVelocity - actualVelocity);
+ // subtract vertical component
+ velocityCorrection -= velocityCorrection.dot(_currentUp) * _currentUp;
+ _rigidBody->setLinearVelocity(actualVelocity + velocityCorrection);
+ }
+ } else {
+ // transitioning to flying
+ btVector3 velocityCorrection = desiredVelocity - actualVelocity;
+ const btScalar FLY_ACCELERATION_TIMESCALE = 0.2f;
+ btScalar tau = dt / FLY_ACCELERATION_TIMESCALE;
+ if (!_isPushingUp) {
+ // actually falling --> compute a different velocity attenuation factor
+ const btScalar FALL_ACCELERATION_TIMESCALE = 2.0f;
+ tau = dt / FALL_ACCELERATION_TIMESCALE;
+ // zero vertical component
+ velocityCorrection -= velocityCorrection.dot(_currentUp) * _currentUp;
+ }
+ _rigidBody->setLinearVelocity(actualVelocity + tau * velocityCorrection);
+ }
+ }
+
+ // Rather than add _followVelocity to the velocity of the RigidBody, we explicitly teleport
+ // the RigidBody forward according to the formula: distance = rate * time
+ if (_followVelocity.length2() > 0.0f) {
+ btTransform bodyTransform = _rigidBody->getWorldTransform();
+ bodyTransform.setOrigin(bodyTransform.getOrigin() + dt * _followVelocity);
+ _rigidBody->setWorldTransform(bodyTransform);
+ }
+ _followTime += dt;
+}
+
+void CharacterController::jump() {
+ // check for case where user is holding down "jump" key...
+ // we'll eventually tansition to "hover"
+ if (!_isJumping) {
+ if (!_isHovering) {
+ _jumpToHoverStart = usecTimestampNow();
+ _pendingFlags |= PENDING_FLAG_JUMP;
+ }
+ } else {
+ quint64 now = usecTimestampNow();
+ const quint64 JUMP_TO_HOVER_PERIOD = 75 * (USECS_PER_SECOND / 100);
+ if (now - _jumpToHoverStart > JUMP_TO_HOVER_PERIOD) {
+ _isPushingUp = true;
+ setHovering(true);
+ }
+ }
+}
+
+bool CharacterController::onGround() const {
+ const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius;
+ return _floorDistance < FLOOR_PROXIMITY_THRESHOLD;
+}
+
+void CharacterController::setHovering(bool hover) {
+ if (hover != _isHovering) {
+ _isHovering = hover;
+ _isJumping = false;
+
+ if (_rigidBody) {
+ if (hover) {
+ _rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f));
+ } else {
+ _rigidBody->setGravity(DEFAULT_CHARACTER_GRAVITY * _currentUp);
+ }
+ }
+ }
+}
+
+void CharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) {
+ _boxScale = scale;
+
+ float x = _boxScale.x;
+ float z = _boxScale.z;
+ float radius = 0.5f * sqrtf(0.5f * (x * x + z * z));
+ float halfHeight = 0.5f * _boxScale.y - radius;
+ float MIN_HALF_HEIGHT = 0.1f;
+ if (halfHeight < MIN_HALF_HEIGHT) {
+ halfHeight = MIN_HALF_HEIGHT;
+ }
+
+ // compare dimensions
+ float radiusDelta = glm::abs(radius - _radius);
+ float heightDelta = glm::abs(halfHeight - _halfHeight);
+ if (radiusDelta < FLT_EPSILON && heightDelta < FLT_EPSILON) {
+ // shape hasn't changed --> nothing to do
+ } else {
+ if (_dynamicsWorld) {
+ // must REMOVE from world prior to shape update
+ _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION;
+ }
+ _pendingFlags |= PENDING_FLAG_UPDATE_SHAPE;
+ // only need to ADD back when we happen to be enabled
+ if (_enabled) {
+ _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION;
+ }
+ }
+
+ // it's ok to change offset immediately -- there are no thread safety issues here
+ _shapeLocalOffset = corner + 0.5f * _boxScale;
+}
+
+void CharacterController::setEnabled(bool enabled) {
+ if (enabled != _enabled) {
+ if (enabled) {
+ // Don't bother clearing REMOVE bit since it might be paired with an UPDATE_SHAPE bit.
+ // Setting the ADD bit here works for all cases so we don't even bother checking other bits.
+ _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION;
+ } else {
+ if (_dynamicsWorld) {
+ _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION;
+ }
+ _pendingFlags &= ~ PENDING_FLAG_ADD_TO_SIMULATION;
+ _isOnGround = false;
+ }
+ setHovering(true);
+ _enabled = enabled;
+ }
+}
+
+void CharacterController::updateUpAxis(const glm::quat& rotation) {
+ btVector3 oldUp = _currentUp;
+ _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS);
+ if (!_isHovering) {
+ const btScalar MIN_UP_ERROR = 0.01f;
+ if (oldUp.distance(_currentUp) > MIN_UP_ERROR) {
+ _rigidBody->setGravity(DEFAULT_CHARACTER_GRAVITY * _currentUp);
+ }
+ }
+}
+
+void CharacterController::setPositionAndOrientation(
+ const glm::vec3& position,
+ const glm::quat& orientation) {
+ // TODO: update gravity if up has changed
+ updateUpAxis(orientation);
+
+ btQuaternion bodyOrientation = glmToBullet(orientation);
+ btVector3 bodyPosition = glmToBullet(position + orientation * _shapeLocalOffset);
+ _characterBodyTransform = btTransform(bodyOrientation, bodyPosition);
+}
+
+void CharacterController::getPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const {
+ if (_enabled && _rigidBody) {
+ const btTransform& avatarTransform = _rigidBody->getWorldTransform();
+ rotation = bulletToGLM(avatarTransform.getRotation());
+ position = bulletToGLM(avatarTransform.getOrigin()) - rotation * _shapeLocalOffset;
+ }
+}
+
+void CharacterController::setTargetVelocity(const glm::vec3& velocity) {
+ //_walkVelocity = glmToBullet(_avatarData->getTargetVelocity());
+ _walkVelocity = glmToBullet(velocity);
+}
+
+void CharacterController::setFollowVelocity(const glm::vec3& velocity) {
+ _followVelocity = glmToBullet(velocity);
+}
+
+glm::vec3 CharacterController::getLinearVelocity() const {
+ glm::vec3 velocity(0.0f);
+ if (_rigidBody) {
+ velocity = bulletToGLM(_rigidBody->getLinearVelocity());
+ }
+ return velocity;
+}
+
+void CharacterController::preSimulation() {
+ if (_enabled && _dynamicsWorld) {
+ // slam body to where it is supposed to be
+ _rigidBody->setWorldTransform(_characterBodyTransform);
+
+ // scan for distant floor
+ // rayStart is at center of bottom sphere
+ btVector3 rayStart = _characterBodyTransform.getOrigin() - _halfHeight * _currentUp;
+
+ // rayEnd is straight down MAX_FALL_HEIGHT
+ btScalar rayLength = _radius + MAX_FALL_HEIGHT;
+ btVector3 rayEnd = rayStart - rayLength * _currentUp;
+
+ ClosestNotMe rayCallback(_rigidBody);
+ rayCallback.m_closestHitFraction = 1.0f;
+ _dynamicsWorld->rayTest(rayStart, rayEnd, rayCallback);
+ if (rayCallback.hasHit()) {
+ _floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius;
+ const btScalar MIN_HOVER_HEIGHT = 3.0f;
+ if (_isHovering && _floorDistance < MIN_HOVER_HEIGHT && !_isPushingUp) {
+ setHovering(false);
+ }
+ // TODO: use collision events rather than ray-trace test to disable jumping
+ const btScalar JUMP_PROXIMITY_THRESHOLD = 0.1f * _radius;
+ if (_floorDistance < JUMP_PROXIMITY_THRESHOLD) {
+ _isJumping = false;
+ }
+ } else {
+ _floorDistance = FLT_MAX;
+ setHovering(true);
+ }
+
+ if (_pendingFlags & PENDING_FLAG_JUMP) {
+ _pendingFlags &= ~ PENDING_FLAG_JUMP;
+ if (onGround()) {
+ _isJumping = true;
+ btVector3 velocity = _rigidBody->getLinearVelocity();
+ velocity += _jumpSpeed * _currentUp;
+ _rigidBody->setLinearVelocity(velocity);
+ }
+ }
+ }
+ _followTime = 0.0f;
+}
+
+void CharacterController::postSimulation() {
+ // postSimulation() exists for symmetry and just in case we need to do something here later
+}
diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h
index e9e6f1328e..6edbabdab8 100644
--- a/libraries/physics/src/CharacterController.h
+++ b/libraries/physics/src/CharacterController.h
@@ -17,11 +17,14 @@
#include
#include
+#include
+
const uint32_t PENDING_FLAG_ADD_TO_SIMULATION = 1U << 0;
const uint32_t PENDING_FLAG_REMOVE_FROM_SIMULATION = 1U << 1;
const uint32_t PENDING_FLAG_UPDATE_SHAPE = 1U << 2;
const uint32_t PENDING_FLAG_JUMP = 1U << 3;
+const float DEFAULT_CHARACTER_GRAVITY = -5.0f;
class btRigidBody;
class btCollisionWorld;
@@ -29,31 +32,89 @@ class btDynamicsWorld;
class CharacterController : public btCharacterControllerInterface {
public:
+ CharacterController();
+ virtual ~CharacterController() {}
+
bool needsRemoval() const;
bool needsAddition() const;
void setDynamicsWorld(btDynamicsWorld* world);
btCollisionObject* getCollisionObject() { return _rigidBody; }
virtual void updateShapeIfNecessary() = 0;
- virtual void preSimulation() = 0;
- virtual void postSimulation() = 0;
+ // overrides from btCharacterControllerInterface
virtual void setWalkDirection(const btVector3 &walkDirection) { assert(false); }
+ virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) override { assert(false); }
+ virtual void reset(btCollisionWorld* collisionWorld) override { }
+ virtual void warp(const btVector3& origin) override { }
+ virtual void debugDraw(btIDebugDraw* debugDrawer) override { }
+ virtual void setUpInterpolate(bool value) override { }
+ virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTime) override {
+ preStep(collisionWorld);
+ playerStep(collisionWorld, deltaTime);
+ }
+ virtual void preStep(btCollisionWorld *collisionWorld) override;
+ virtual void playerStep(btCollisionWorld *collisionWorld, btScalar dt) override;
+ virtual bool canJump() const override { assert(false); return false; } // never call this
+ virtual void jump() override;
+ virtual bool onGround() const;
+
+ void preSimulation();
+ void postSimulation();
+
+ void setPositionAndOrientation( const glm::vec3& position, const glm::quat& orientation);
+ void getPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const;
+
+ void setTargetVelocity(const glm::vec3& velocity);
+ void setFollowVelocity(const glm::vec3& velocity);
+ float getFollowTime() const { return _followTime; }
+
+ glm::vec3 getLinearVelocity() const;
+
+ bool isHovering() const { return _isHovering; }
+ void setHovering(bool enabled);
+
+ void setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale);
+
+ void setEnabled(bool enabled);
+ bool isEnabled() const { return _enabled && _dynamicsWorld; }
- /* these from btCharacterControllerInterface remain to be overridden
- virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) = 0;
- virtual void reset() = 0;
- virtual void warp(const btVector3 &origin) = 0;
- virtual void preStep(btCollisionWorld *collisionWorld) = 0;
- virtual void playerStep(btCollisionWorld *collisionWorld, btScalar dt) = 0;
- virtual bool canJump() const = 0;
- virtual void jump() = 0;
- virtual bool onGround() const = 0;
- */
protected:
+ void updateUpAxis(const glm::quat& rotation);
+
+protected:
+ btVector3 _currentUp;
+ btVector3 _walkVelocity;
+ btVector3 _followVelocity;
+ btTransform _characterBodyTransform;
+
+ glm::vec3 _shapeLocalOffset;
+
+ glm::vec3 _boxScale; // used to compute capsule shape
+
+ quint64 _jumpToHoverStart;
+
+ btScalar _halfHeight;
+ btScalar _radius;
+
+ btScalar _floorDistance;
+
+ btScalar _gravity;
+
+ btScalar _jumpSpeed;
+ btScalar _followTime;
+
+ bool _enabled;
+ bool _isOnGround;
+ bool _isJumping;
+ bool _isFalling;
+ bool _isHovering;
+ bool _isPushingUp;
+
btDynamicsWorld* _dynamicsWorld { nullptr };
btRigidBody* _rigidBody { nullptr };
uint32_t _pendingFlags { 0 };
+
};
#endif // hifi_CharacterControllerInterface_h
diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp
index 3306659c80..a075b0a91d 100644
--- a/libraries/script-engine/src/ScriptEngine.cpp
+++ b/libraries/script-engine/src/ScriptEngine.cpp
@@ -82,7 +82,7 @@ void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) {
}
Q_DECLARE_METATYPE(controller::InputController*)
-static int inputControllerPointerId = qRegisterMetaType();
+//static int inputControllerPointerId = qRegisterMetaType();
QScriptValue inputControllerToScriptValue(QScriptEngine *engine, controller::InputController* const &in) {
return engine->newQObject(in);
diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp
index 7c057c7152..d6811c3529 100644
--- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp
+++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp
@@ -20,9 +20,7 @@ glm::mat4 OculusBaseDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseP
}
void OculusBaseDisplayPlugin::resetSensors() {
-#if (OVR_MAJOR_VERSION >= 6)
- ovr_RecenterPose(_hmd);
-#endif
+ ovr_RecenterPose(_session);
}
glm::mat4 OculusBaseDisplayPlugin::getEyeToHeadTransform(Eye eye) const {
@@ -30,27 +28,39 @@ glm::mat4 OculusBaseDisplayPlugin::getEyeToHeadTransform(Eye eye) const {
}
glm::mat4 OculusBaseDisplayPlugin::getHeadPose(uint32_t frameIndex) const {
-#if (OVR_MAJOR_VERSION >= 6)
- auto frameTiming = ovr_GetFrameTiming(_hmd, frameIndex);
- auto trackingState = ovr_GetTrackingState(_hmd, frameTiming.DisplayMidpointSeconds);
+ static uint32_t lastFrameSeen = 0;
+ auto displayTime = ovr_GetPredictedDisplayTime(_session, frameIndex);
+ auto trackingState = ovr_GetTrackingState(_session, displayTime, frameIndex > lastFrameSeen);
+ if (frameIndex > lastFrameSeen) {
+ lastFrameSeen = frameIndex;
+ }
return toGlm(trackingState.HeadPose.ThePose);
-#endif
}
bool OculusBaseDisplayPlugin::isSupported() const {
-#if (OVR_MAJOR_VERSION >= 6)
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
return false;
}
- bool result = false;
- if (ovrHmd_Detect() > 0) {
- result = true;
+
+ ovrSession session { nullptr };
+ ovrGraphicsLuid luid;
+ auto result = ovr_Create(&session, &luid);
+ if (!OVR_SUCCESS(result)) {
+ ovrErrorInfo error;
+ ovr_GetLastErrorInfo(&error);
+ ovr_Shutdown();
+ return false;
}
+
+ auto hmdDesc = ovr_GetHmdDesc(session);
+ if (hmdDesc.Type == ovrHmd_None) {
+ ovr_Destroy(session);
+ ovr_Shutdown();
+ return false;
+ }
+
ovr_Shutdown();
- return result;
-#else
- return false;
-#endif
+ return true;
}
// DLL based display plugins MUST initialize GLEW inside the DLL code.
@@ -69,28 +79,22 @@ void OculusBaseDisplayPlugin::deinit() {
void OculusBaseDisplayPlugin::activate() {
WindowOpenGLDisplayPlugin::activate();
-#if (OVR_MAJOR_VERSION >= 6)
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
qFatal("Could not init OVR");
}
-#if (OVR_MAJOR_VERSION == 6)
- if (!OVR_SUCCESS(ovr_Create(0, &_hmd))) {
-#elif (OVR_MAJOR_VERSION == 7)
- if (!OVR_SUCCESS(ovr_Create(&_hmd, &_luid))) {
-#endif
- Q_ASSERT(false);
+ if (!OVR_SUCCESS(ovr_Create(&_session, &_luid))) {
qFatal("Failed to acquire HMD");
}
- _hmdDesc = ovr_GetHmdDesc(_hmd);
+ _hmdDesc = ovr_GetHmdDesc(_session);
- _ipd = ovr_GetFloat(_hmd, OVR_KEY_IPD, _ipd);
+ _ipd = ovr_GetFloat(_session, OVR_KEY_IPD, _ipd);
glm::uvec2 eyeSizes[2];
ovr_for_each_eye([&](ovrEyeType eye) {
_eyeFovs[eye] = _hmdDesc.DefaultEyeFov[eye];
- ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovr_GetRenderDesc(_hmd, eye, _eyeFovs[eye]);
+ ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovr_GetRenderDesc(_session, eye, _eyeFovs[eye]);
ovrMatrix4f ovrPerspectiveProjection =
ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
_eyeProjections[eye] = toGlm(ovrPerspectiveProjection);
@@ -100,7 +104,7 @@ void OculusBaseDisplayPlugin::activate() {
_compositeEyeProjections[eye] = toGlm(ovrPerspectiveProjection);
_eyeOffsets[eye] = erd.HmdToEyeViewOffset;
- eyeSizes[eye] = toGlm(ovr_GetFovTextureSize(_hmd, eye, erd.Fov, 1.0f));
+ eyeSizes[eye] = toGlm(ovr_GetFovTextureSize(_session, eye, erd.Fov, 1.0f));
});
ovrFovPort combined = _eyeFovs[Left];
combined.LeftTan = std::max(_eyeFovs[Left].LeftTan, _eyeFovs[Right].LeftTan);
@@ -115,34 +119,33 @@ void OculusBaseDisplayPlugin::activate() {
eyeSizes[0].x + eyeSizes[1].x,
std::max(eyeSizes[0].y, eyeSizes[1].y));
- if (!OVR_SUCCESS(ovr_ConfigureTracking(_hmd,
+ if (!OVR_SUCCESS(ovr_ConfigureTracking(_session,
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) {
qFatal("Could not attach to sensor device");
}
- // Parent class relies on our _hmd intialization, so it must come after that.
+ // Parent class relies on our _session intialization, so it must come after that.
memset(&_sceneLayer, 0, sizeof(ovrLayerEyeFov));
_sceneLayer.Header.Type = ovrLayerType_EyeFov;
_sceneLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft;
ovr_for_each_eye([&](ovrEyeType eye) {
ovrFovPort & fov = _sceneLayer.Fov[eye] = _eyeRenderDescs[eye].Fov;
- ovrSizei & size = _sceneLayer.Viewport[eye].Size = ovr_GetFovTextureSize(_hmd, eye, fov, 1.0f);
+ ovrSizei & size = _sceneLayer.Viewport[eye].Size = ovr_GetFovTextureSize(_session, eye, fov, 1.0f);
_sceneLayer.Viewport[eye].Pos = { eye == ovrEye_Left ? 0 : size.w, 0 };
});
- if (!OVR_SUCCESS(ovr_ConfigureTracking(_hmd,
+ if (!OVR_SUCCESS(ovr_ConfigureTracking(_session,
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) {
qFatal("Could not attach to sensor device");
}
-#endif
}
void OculusBaseDisplayPlugin::deactivate() {
WindowOpenGLDisplayPlugin::deactivate();
#if (OVR_MAJOR_VERSION >= 6)
- ovr_Destroy(_hmd);
- _hmd = nullptr;
+ ovr_Destroy(_session);
+ _session = nullptr;
ovr_Shutdown();
#endif
}
@@ -151,7 +154,7 @@ void OculusBaseDisplayPlugin::deactivate() {
float OculusBaseDisplayPlugin::getIPD() const {
float result = OVR_DEFAULT_IPD;
#if (OVR_MAJOR_VERSION >= 6)
- result = ovr_GetFloat(_hmd, OVR_KEY_IPD, result);
+ result = ovr_GetFloat(_session, OVR_KEY_IPD, result);
#endif
return result;
}
diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h
index 711be6aa5e..1a26c6958b 100644
--- a/plugins/oculus/src/OculusBaseDisplayPlugin.h
+++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h
@@ -43,17 +43,13 @@ protected:
mat4 _compositeEyeProjections[2];
uvec2 _desiredFramebufferSize;
-#if (OVR_MAJOR_VERSION >= 6)
- ovrHmd _hmd;
+ ovrSession _session;
+ ovrGraphicsLuid _luid;
float _ipd{ OVR_DEFAULT_IPD };
ovrEyeRenderDesc _eyeRenderDescs[2];
ovrFovPort _eyeFovs[2];
ovrHmdDesc _hmdDesc;
ovrLayerEyeFov _sceneLayer;
-#endif
-#if (OVR_MAJOR_VERSION == 7)
- ovrGraphicsLuid _luid;
-#endif
};
#if (OVR_MAJOR_VERSION == 6)
diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp
index e6eae2cf02..c8fb0ba080 100644
--- a/plugins/oculus/src/OculusDisplayPlugin.cpp
+++ b/plugins/oculus/src/OculusDisplayPlugin.cpp
@@ -23,12 +23,16 @@
// ovr_CreateMirrorTextureGL, etc
template
struct RiftFramebufferWrapper : public FramebufferWrapper {
- ovrHmd hmd;
- RiftFramebufferWrapper(const ovrHmd & hmd) : hmd(hmd) {
+ ovrSession session;
+ RiftFramebufferWrapper(const ovrSession& session) : session(session) {
color = 0;
depth = 0;
};
+ ~RiftFramebufferWrapper() {
+ destroyColor();
+ }
+
void Resize(const uvec2 & size) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oglplus::GetName(fbo));
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
@@ -39,6 +43,9 @@ struct RiftFramebufferWrapper : public FramebufferWrapper {
}
protected:
+ virtual void destroyColor() {
+ }
+
virtual void initDepth() override final {
}
};
@@ -53,12 +60,6 @@ struct SwapFramebufferWrapper : public RiftFramebufferWrapperCurrentIndex;
@@ -66,13 +67,17 @@ struct SwapFramebufferWrapper : public RiftFramebufferWrapper {
MirrorFramebufferWrapper(const ovrHmd & hmd)
: RiftFramebufferWrapper(hmd) { }
- virtual ~MirrorFramebufferWrapper() {
+private:
+ virtual void destroyColor() override {
if (color) {
- ovr_DestroyMirrorTexture(hmd, (ovrTexture*)color);
+ ovr_DestroyMirrorTexture(session, (ovrTexture*)color);
color = nullptr;
}
}
-private:
void initColor() override {
- if (color) {
- ovr_DestroyMirrorTexture(hmd, (ovrTexture*)color);
- color = nullptr;
- }
- ovrResult result = ovr_CreateMirrorTextureGL(hmd, GL_RGBA, size.x, size.y, (ovrTexture**)&color);
+ destroyColor();
+ ovrResult result = ovr_CreateMirrorTextureGL(session, GL_SRGB8_ALPHA8, size.x, size.y, (ovrTexture**)&color);
Q_ASSERT(OVR_SUCCESS(result));
}
@@ -154,8 +156,7 @@ void OculusDisplayPlugin::activate() {
void OculusDisplayPlugin::customizeContext() {
OculusBaseDisplayPlugin::customizeContext();
-#if (OVR_MAJOR_VERSION >= 6)
- _sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_hmd));
+ _sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_session));
_sceneFbo->Init(getRecommendedRenderSize());
// We're rendering both eyes to the same texture, so only one of the
@@ -163,7 +164,7 @@ void OculusDisplayPlugin::customizeContext() {
_sceneLayer.ColorTexture[0] = _sceneFbo->color;
// not needed since the structure was zeroed on init, but explicit
_sceneLayer.ColorTexture[1] = nullptr;
-#endif
+
enableVsync(false);
// Only enable mirroring if we know vsync is disabled
_enablePreview = !isVsyncEnabled();
@@ -177,7 +178,6 @@ void OculusDisplayPlugin::uncustomizeContext() {
}
void OculusDisplayPlugin::internalPresent() {
-#if (OVR_MAJOR_VERSION >= 6)
if (!_currentSceneTexture) {
return;
}
@@ -206,8 +206,10 @@ void OculusDisplayPlugin::internalPresent() {
auto size = _sceneFbo->size;
Context::Viewport(size.x, size.y);
glBindTexture(GL_TEXTURE_2D, _currentSceneTexture);
+ //glEnable(GL_FRAMEBUFFER_SRGB);
GLenum err = glGetError();
drawUnitQuad();
+ //glDisable(GL_FRAMEBUFFER_SRGB);
});
uint32_t frameIndex { 0 };
@@ -230,13 +232,12 @@ void OculusDisplayPlugin::internalPresent() {
viewScaleDesc.HmdToEyeViewOffset[1] = _eyeOffsets[1];
ovrLayerHeader* layers = &_sceneLayer.Header;
- ovrResult result = ovr_SubmitFrame(_hmd, frameIndex, &viewScaleDesc, &layers, 1);
+ ovrResult result = ovr_SubmitFrame(_session, frameIndex, &viewScaleDesc, &layers, 1);
if (!OVR_SUCCESS(result)) {
qDebug() << result;
}
}
_sceneFbo->Increment();
-#endif
/*
The swapbuffer call here is only required if we want to mirror the content to the screen.
diff --git a/plugins/openvr/CMakeLists.txt b/plugins/openvr/CMakeLists.txt
new file mode 100644
index 0000000000..c3c4771276
--- /dev/null
+++ b/plugins/openvr/CMakeLists.txt
@@ -0,0 +1,27 @@
+#
+# Created by Bradley Austin Davis on 2015/11/18
+# 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
+#
+
+# OpenVR is disabled until a) it works with threaded present and
+# b) it doesn't interfere with Oculus SDK 0.8
+if (FALSE)
+#if (WIN32)
+ # we're using static GLEW, so define GLEW_STATIC
+ add_definitions(-DGLEW_STATIC)
+ set(TARGET_NAME openvr)
+ setup_hifi_plugin(OpenGL Script Qml Widgets)
+ link_hifi_libraries(shared gl networking controllers
+ plugins display-plugins input-plugins script-engine
+ render-utils model gpu render model-networking fbx)
+
+ include_hifi_library_headers(octree)
+
+ add_dependency_external_projects(OpenVR)
+ find_package(OpenVR REQUIRED)
+ target_include_directories(${TARGET_NAME} PRIVATE ${OPENVR_INCLUDE_DIRS})
+ target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES})
+endif()
diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp
similarity index 65%
rename from libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp
rename to plugins/openvr/src/OpenVrDisplayPlugin.cpp
index 68a711a847..58f7536856 100644
--- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp
+++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp
@@ -7,24 +7,23 @@
//
#include "OpenVrDisplayPlugin.h"
-#if defined(Q_OS_WIN)
-
#include
#include
+#include
#include
-#include
#include
#include
+#include
+#include
+
#include
#include
#include
#include "OpenVrHelpers.h"
-#include "GLMHelpers.h"
-#include
Q_DECLARE_LOGGING_CATEGORY(displayplugins)
Q_LOGGING_CATEGORY(displayplugins, "hifi.displayplugins")
@@ -41,12 +40,11 @@ vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
static mat4 _sensorResetMat;
static uvec2 _windowSize;
-static ivec2 _windowPosition;
static uvec2 _renderTargetSize;
struct PerEyeData {
- uvec2 _viewportOrigin;
- uvec2 _viewportSize;
+ //uvec2 _viewportOrigin;
+ //uvec2 _viewportSize;
mat4 _projectionMatrix;
mat4 _eyeOffset;
mat4 _pose;
@@ -89,36 +87,17 @@ void OpenVrDisplayPlugin::activate() {
}
Q_ASSERT(_hmd);
- _hmd->GetWindowBounds(&_windowPosition.x, &_windowPosition.y, &_windowSize.x, &_windowSize.y);
_hmd->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y);
// Recommended render target size is per-eye, so double the X size for
// left + right eyes
_renderTargetSize.x *= 2;
openvr_for_each_eye([&](vr::Hmd_Eye eye) {
PerEyeData& eyeData = _eyesData[eye];
- _hmd->GetEyeOutputViewport(eye,
- &eyeData._viewportOrigin.x, &eyeData._viewportOrigin.y,
- &eyeData._viewportSize.x, &eyeData._viewportSize.y);
eyeData._projectionMatrix = toGlm(_hmd->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, vr::API_OpenGL));
eyeData._eyeOffset = toGlm(_hmd->GetEyeToHeadTransform(eye));
});
-
-
- vr::HmdError eError = vr::HmdError_None;
- _compositor = (vr::IVRCompositor*)vr::VR_GetGenericInterface(vr::IVRCompositor_Version, &eError);
- Q_ASSERT(eError == vr::HmdError_None);
+ _compositor = vr::VRCompositor();
Q_ASSERT(_compositor);
-
- _compositor->SetGraphicsDevice(vr::Compositor_DeviceType_OpenGL, NULL);
-
- uint32_t unSize = _compositor->GetLastError(NULL, 0);
- if (unSize > 1) {
- char* buffer = new char[unSize];
- _compositor->GetLastError(buffer, unSize);
- printf("Compositor - %s\n", buffer);
- delete[] buffer;
- }
- Q_ASSERT(unSize <= 1);
WindowOpenGLDisplayPlugin::activate();
}
@@ -132,6 +111,16 @@ void OpenVrDisplayPlugin::deactivate() {
WindowOpenGLDisplayPlugin::deactivate();
}
+void OpenVrDisplayPlugin::customizeContext() {
+ static std::once_flag once;
+ std::call_once(once, []{
+ glewExperimental = true;
+ GLenum err = glewInit();
+ glGetError();
+ });
+ WindowOpenGLDisplayPlugin::customizeContext();
+}
+
uvec2 OpenVrDisplayPlugin::getRecommendedRenderSize() const {
return _renderTargetSize;
}
@@ -153,33 +142,41 @@ glm::mat4 OpenVrDisplayPlugin::getEyeToHeadTransform(Eye eye) const {
}
glm::mat4 OpenVrDisplayPlugin::getHeadPose(uint32_t frameIndex) const {
- return _trackedDevicePoseMat4[0];
+ glm::mat4 result;
+ {
+ Lock lock(_mutex);
+ result = _trackedDevicePoseMat4[0];
+
+ }
+ return result;
}
-void OpenVrDisplayPlugin::customizeContext() {
- WindowOpenGLDisplayPlugin::customizeContext();
+
+void OpenVrDisplayPlugin::submitSceneTexture(uint32_t frameIndex, uint32_t sceneTexture, const glm::uvec2& sceneSize) {
+ WindowOpenGLDisplayPlugin::submitSceneTexture(frameIndex, sceneTexture, sceneSize);
}
-//void OpenVrDisplayPlugin::display(uint32_t frameIndex, uint32_t finalTexture, const glm::uvec2& sceneSize) {
-// // Flip y-axis since GL UV coords are backwards.
-// static vr::Compositor_TextureBounds leftBounds{ 0, 1, 0.5f, 0 };
-// static vr::Compositor_TextureBounds rightBounds{ 0.5f, 1, 1, 0 };
-// _compositor->Submit(vr::Eye_Left, (void*)finalTexture, &leftBounds);
-// _compositor->Submit(vr::Eye_Right, (void*)finalTexture, &rightBounds);
-// glFinish();
-//}
-
-//void OpenVrDisplayPlugin::finishFrame() {
-//// swapBuffers();
-// doneCurrent();
-// _compositor->WaitGetPoses(_trackedDevicePose, vr::k_unMaxTrackedDeviceCount);
-// for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
-// _trackedDevicePoseMat4[i] = _sensorResetMat * toGlm(_trackedDevicePose[i].mDeviceToAbsoluteTracking);
-// }
-// openvr_for_each_eye([&](vr::Hmd_Eye eye) {
-// _eyesData[eye]._pose = _trackedDevicePoseMat4[0];
-// });
-//};
-
-#endif
+void OpenVrDisplayPlugin::internalPresent() {
+ // Flip y-axis since GL UV coords are backwards.
+ static vr::VRTextureBounds_t leftBounds{ 0, 0, 0.5f, 1 };
+ static vr::VRTextureBounds_t rightBounds{ 0.5f, 0, 1, 1 };
+ vr::Texture_t texture{ (void*)_currentSceneTexture, vr::API_OpenGL, vr::ColorSpace_Auto };
+ {
+ Lock lock(_mutex);
+ _compositor->Submit(vr::Eye_Left, &texture, &leftBounds);
+ _compositor->Submit(vr::Eye_Right, &texture, &rightBounds);
+ }
+ glFinish();
+ {
+ Lock lock(_mutex);
+ _compositor->WaitGetPoses(_trackedDevicePose, vr::k_unMaxTrackedDeviceCount, nullptr, 0);
+ for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
+ _trackedDevicePoseMat4[i] = _sensorResetMat * toGlm(_trackedDevicePose[i].mDeviceToAbsoluteTracking);
+ }
+ openvr_for_each_eye([&](vr::Hmd_Eye eye) {
+ _eyesData[eye]._pose = _trackedDevicePoseMat4[0];
+ });
+ }
+ //WindowOpenGLDisplayPlugin::internalPresent();
+}
diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h
similarity index 86%
rename from libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h
rename to plugins/openvr/src/OpenVrDisplayPlugin.h
index d07add7ea5..8186e59936 100644
--- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h
+++ b/plugins/openvr/src/OpenVrDisplayPlugin.h
@@ -9,10 +9,9 @@
#include
-#if defined(Q_OS_WIN)
#include
-#include "../WindowOpenGLDisplayPlugin.h"
+#include
const float TARGET_RATE_OpenVr = 90.0f; // FIXME: get from sdk tracked device property? This number is vive-only.
@@ -27,6 +26,8 @@ public:
virtual void activate() override;
virtual void deactivate() override;
+ virtual void customizeContext() override;
+
virtual glm::uvec2 getRecommendedRenderSize() const override;
virtual glm::uvec2 getRecommendedUiSize() const override { return uvec2(1920, 1080); }
@@ -36,15 +37,13 @@ public:
virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override;
virtual glm::mat4 getHeadPose(uint32_t frameIndex) const override;
+ virtual void submitSceneTexture(uint32_t frameIndex, uint32_t sceneTexture, const glm::uvec2& sceneSize) override;
protected:
-// virtual void display(uint32_t frameIndex, uint32_t finalTexture, const glm::uvec2& sceneSize) override;
- virtual void customizeContext() override;
+ virtual void internalPresent() override;
private:
vr::IVRSystem* _hmd { nullptr };
static const QString NAME;
};
-#endif
-
diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.cpp b/plugins/openvr/src/OpenVrHelpers.cpp
similarity index 80%
rename from libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.cpp
rename to plugins/openvr/src/OpenVrHelpers.cpp
index f8e810beaf..7020fcb40d 100644
--- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.cpp
+++ b/plugins/openvr/src/OpenVrHelpers.cpp
@@ -7,14 +7,15 @@
//
#include "OpenVrHelpers.h"
-#if defined(Q_OS_WIN)
-
-#include
-
#include
#include
-#include "../Logging.h"
+#include
+#include
+#include
+
+
+Q_DECLARE_LOGGING_CATEGORY(displayplugins)
using Mutex = std::mutex;
using Lock = std::unique_lock;
@@ -30,13 +31,13 @@ vr::IVRSystem* acquireOpenVrSystem() {
if (hmdPresent) {
Lock lock(mutex);
if (!activeHmd) {
- qCDebug(displayPlugins) << "openvr: No vr::IVRSystem instance active, building";
- vr::HmdError eError = vr::HmdError_None;
+ qCDebug(displayplugins) << "openvr: No vr::IVRSystem instance active, building";
+ vr::EVRInitError eError = vr::VRInitError_None;
activeHmd = vr::VR_Init(&eError);
- qCDebug(displayPlugins) << "openvr display: HMD is " << activeHmd << " error is " << eError;
+ qCDebug(displayplugins) << "openvr display: HMD is " << activeHmd << " error is " << eError;
}
if (activeHmd) {
- qCDebug(displayPlugins) << "openvr: incrementing refcount";
+ qCDebug(displayplugins) << "openvr: incrementing refcount";
++refCount;
}
}
@@ -46,10 +47,10 @@ vr::IVRSystem* acquireOpenVrSystem() {
void releaseOpenVrSystem() {
if (activeHmd) {
Lock lock(mutex);
- qDebug() << "openvr: decrementing refcount";
+ qCDebug(displayplugins) << "openvr: decrementing refcount";
--refCount;
if (0 == refCount) {
- qDebug() << "openvr: zero refcount, deallocate VR system";
+ qCDebug(displayplugins) << "openvr: zero refcount, deallocate VR system";
// Avoid spamming the VR system with activate/deactivate calls at system startup by
// putting in a delay before we destory the shutdown the VR subsystem
@@ -71,5 +72,3 @@ void releaseOpenVrSystem() {
}
}
}
-
-#endif
diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.h b/plugins/openvr/src/OpenVrHelpers.h
similarity index 89%
rename from libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.h
rename to plugins/openvr/src/OpenVrHelpers.h
index 3e445d90ba..513e1702d2 100644
--- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.h
+++ b/plugins/openvr/src/OpenVrHelpers.h
@@ -7,9 +7,6 @@
//
#pragma once
-#include
-
-#if defined(Q_OS_WIN)
#include
#include
#include
@@ -18,5 +15,3 @@
vr::IVRSystem* acquireOpenVrSystem();
void releaseOpenVrSystem();
-#endif
-
diff --git a/plugins/openvr/src/OpenVrProvider.cpp b/plugins/openvr/src/OpenVrProvider.cpp
new file mode 100644
index 0000000000..66227a9543
--- /dev/null
+++ b/plugins/openvr/src/OpenVrProvider.cpp
@@ -0,0 +1,60 @@
+//
+// 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 "OpenVrDisplayPlugin.h"
+#include "ViveControllerManager.h"
+
+class OpenVrProvider : public QObject, public DisplayProvider, InputProvider
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID DisplayProvider_iid FILE "plugin.json")
+ Q_INTERFACES(DisplayProvider)
+ Q_PLUGIN_METADATA(IID InputProvider_iid FILE "plugin.json")
+ Q_INTERFACES(InputProvider)
+
+public:
+ OpenVrProvider(QObject* parent = nullptr) : QObject(parent) {}
+ virtual ~OpenVrProvider() {}
+
+ virtual DisplayPluginList getDisplayPlugins() override {
+ static std::once_flag once;
+ std::call_once(once, [&] {
+ DisplayPluginPointer plugin(new OpenVrDisplayPlugin());
+ if (plugin->isSupported()) {
+ _displayPlugins.push_back(plugin);
+ }
+ });
+ return _displayPlugins;
+ }
+
+ virtual InputPluginList getInputPlugins() override {
+ static std::once_flag once;
+ std::call_once(once, [&] {
+ InputPluginPointer plugin(new ViveControllerManager());
+ if (plugin->isSupported()) {
+ _inputPlugins.push_back(plugin);
+ }
+ });
+ return _inputPlugins;
+ }
+
+
+private:
+ DisplayPluginList _displayPlugins;
+ InputPluginList _inputPlugins;
+};
+
+#include "OpenVrProvider.moc"
diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp
similarity index 97%
rename from libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp
rename to plugins/openvr/src/ViveControllerManager.cpp
index 5315152cea..39056cd46f 100644
--- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp
+++ b/plugins/openvr/src/ViveControllerManager.cpp
@@ -17,7 +17,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -26,10 +25,10 @@
#include
-#ifdef Q_OS_WIN
+#include "OpenVrHelpers.h"
+
extern vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
extern mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
-#endif
vr::IVRSystem* acquireOpenVrSystem();
void releaseOpenVrSystem();
@@ -39,7 +38,7 @@ static const float CONTROLLER_LENGTH_OFFSET = 0.0762f; // three inches
static const glm::vec3 CONTROLLER_OFFSET = glm::vec3(CONTROLLER_LENGTH_OFFSET / 2.0f,
CONTROLLER_LENGTH_OFFSET / 2.0f,
CONTROLLER_LENGTH_OFFSET * 2.0f);
-static const QString CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b";
+static const char* CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b";
static const QString MENU_PARENT = "Avatar";
static const QString MENU_NAME = "Vive Controllers";
@@ -49,19 +48,14 @@ static const QString RENDER_CONTROLLERS = "Render Hand Controllers";
const QString ViveControllerManager::NAME = "OpenVR";
bool ViveControllerManager::isSupported() const {
-#ifdef Q_OS_WIN
auto hmd = acquireOpenVrSystem();
bool success = hmd != nullptr;
releaseOpenVrSystem();
return success;
-#else
- return false;
-#endif
}
void ViveControllerManager::activate() {
InputPlugin::activate();
-#ifdef Q_OS_WIN
_container->addMenu(MENU_PATH);
_container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, RENDER_CONTROLLERS,
[this] (bool clicked) { this->setRenderControllers(clicked); },
@@ -72,8 +66,11 @@ void ViveControllerManager::activate() {
}
Q_ASSERT(_hmd);
+ auto renderModels = vr::VRRenderModels();
+
vr::RenderModel_t model;
- if (!_hmd->LoadRenderModel(CONTROLLER_MODEL_STRING.toStdString().c_str(), &model)) {
+ /*
+ if (!_hmd->LoadRenderModel(CONTROLLER_MODEL_STRING, &model)) {
qDebug() << QString("Unable to load render model %1\n").arg(CONTROLLER_MODEL_STRING);
} else {
model::Mesh* mesh = new model::Mesh();
@@ -118,7 +115,7 @@ void ViveControllerManager::activate() {
_modelLoaded = true;
_renderControllers = true;
}
-#endif
+ */
// unregister with UserInputMapper
auto userInputMapper = DependencyManager::get();
@@ -129,7 +126,6 @@ void ViveControllerManager::activate() {
void ViveControllerManager::deactivate() {
InputPlugin::deactivate();
-#ifdef Q_OS_WIN
_container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS);
_container->removeMenu(MENU_PATH);
@@ -139,7 +135,6 @@ void ViveControllerManager::deactivate() {
}
_inputDevice->_poseStateMap.clear();
-#endif
// unregister with UserInputMapper
auto userInputMapper = DependencyManager::get();
@@ -225,7 +220,6 @@ void ViveControllerManager::pluginUpdate(float deltaTime, bool jointsCaptured) {
}
void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
-#ifdef Q_OS_WIN
_poseStateMap.clear();
_buttonPressedMap.clear();
@@ -276,7 +270,6 @@ void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCapt
}
_trackedControllers = numTrackedControllers;
-#endif
}
void ViveControllerManager::InputDevice::focusOutEvent() {
@@ -286,7 +279,6 @@ void ViveControllerManager::InputDevice::focusOutEvent() {
// These functions do translation from the Steam IDs to the standard controller IDs
void ViveControllerManager::InputDevice::handleAxisEvent(uint32_t axis, float x, float y, bool left) {
-#ifdef Q_OS_WIN
//FIX ME? It enters here every frame: probably we want to enter only if an event occurs
axis += vr::k_EButton_Axis0;
using namespace controller;
@@ -296,12 +288,10 @@ void ViveControllerManager::InputDevice::handleAxisEvent(uint32_t axis, float x,
} else if (axis == vr::k_EButton_SteamVR_Trigger) {
_axisStateMap[left ? LT : RT] = x;
}
-#endif
}
// These functions do translation from the Steam IDs to the standard controller IDs
void ViveControllerManager::InputDevice::handleButtonEvent(uint32_t button, bool pressed, bool left) {
-#ifdef Q_OS_WIN
if (!pressed) {
return;
}
@@ -319,7 +309,6 @@ void ViveControllerManager::InputDevice::handleButtonEvent(uint32_t button, bool
//FIX ME: not able to ovrewrite the behaviour of this button
_buttonPressedMap.insert(left ? controller::LEFT_SECONDARY_THUMB : controller::RIGHT_SECONDARY_THUMB);
}
-#endif
}
void ViveControllerManager::InputDevice::handlePoseEvent(const mat4& mat, bool left) {
diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h
similarity index 98%
rename from libraries/input-plugins/src/input-plugins/ViveControllerManager.h
rename to plugins/openvr/src/ViveControllerManager.h
index 02bdecb10a..077aec7fc3 100644
--- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.h
+++ b/plugins/openvr/src/ViveControllerManager.h
@@ -20,7 +20,7 @@
#include
#include
#include
-#include "InputPlugin.h"
+#include
#include
#include
diff --git a/plugins/openvr/src/plugin.json b/plugins/openvr/src/plugin.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/plugins/openvr/src/plugin.json
@@ -0,0 +1 @@
+{}