Merge branch 'master' of https://github.com/highfidelity/hifi into correct-target-frame-rate

This commit is contained in:
Howard Stearns 2015-12-10 08:44:08 -08:00
commit 83078b9d8c
43 changed files with 806 additions and 750 deletions

View file

@ -15,17 +15,16 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
# 0.6 public # 0.6 public
# URL http://static.oculus.com/sdk-downloads/0.6.0.1/Public/1435190862/ovr_sdk_win_0.6.0.1.zip # URL http://static.oculus.com/sdk-downloads/0.6.0.1/Public/1435190862/ovr_sdk_win_0.6.0.1.zip
# URL_MD5 4b3ef825f9a1d6d3035c9f6820687da9 # URL_MD5 4b3ef825f9a1d6d3035c9f6820687da9
# 0.7 alpha # 0.8 public
# URL https://s3.amazonaws.com/static.oculus.com/sdk-downloads/0.7.0.0/Public/Alpha/ovr_sdk_win_0.7.0.0_RC1.zip # URL http://static.oculus.com/sdk-downloads/0.8.0.0/Public/1445451746/ovr_sdk_win_0.8.0.0.zip
# URL_MD5 a562bb9d117087b2cf9d86653ea70fd8 # URL_MD5 54944b03b95149d6010f84eb701b9647
if (WIN32) if (WIN32)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://static.oculus.com/sdk-downloads/0.6.0.1/Public/1435190862/ovr_sdk_win_0.6.0.1.zip URL http://static.oculus.com/sdk-downloads/0.8.0.0/Public/1445451746/ovr_sdk_win_0.8.0.0.zip
URL_MD5 4b3ef825f9a1d6d3035c9f6820687da9 URL_MD5 54944b03b95149d6010f84eb701b9647
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""
INSTALL_COMMAND "" INSTALL_COMMAND ""

View file

@ -7,9 +7,8 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
#URL https://github.com/ValveSoftware/openvr/archive/0.9.1.zip URL https://github.com/ValveSoftware/openvr/archive/v0.9.12.zip
URL http://hifi-public.s3.amazonaws.com/dependencies/openvr-0.9.1.zip URL_MD5 c08dced68ce4e341e1467e6814ae419d
URL_MD5 f986f5a6815e9454c53c5bf58ce02fdc
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""
INSTALL_COMMAND "" INSTALL_COMMAND ""

View file

@ -202,31 +202,41 @@ function entityIsGrabbedByOther(entityID) {
} }
function getSpatialOffsetPosition(hand, spatialKey) { function getSpatialOffsetPosition(hand, spatialKey) {
var position = Vec3.ZERO;
if (hand !== RIGHT_HAND && spatialKey.leftRelativePosition) { if (hand !== RIGHT_HAND && spatialKey.leftRelativePosition) {
return spatialKey.leftRelativePosition; position = spatialKey.leftRelativePosition;
} }
if (hand === RIGHT_HAND && spatialKey.rightRelativePosition) { if (hand === RIGHT_HAND && spatialKey.rightRelativePosition) {
return spatialKey.rightRelativePosition; position = spatialKey.rightRelativePosition;
} }
if (spatialKey.relativePosition) { if (spatialKey.relativePosition) {
return spatialKey.relativePosition; position = spatialKey.relativePosition;
} }
return Vec3.ZERO; return position;
} }
var yFlip = Quat.angleAxis(180, Vec3.UNIT_Y);
function getSpatialOffsetRotation(hand, spatialKey) { function getSpatialOffsetRotation(hand, spatialKey) {
var rotation = Quat.IDENTITY;
if (hand !== RIGHT_HAND && spatialKey.leftRelativeRotation) { if (hand !== RIGHT_HAND && spatialKey.leftRelativeRotation) {
return spatialKey.leftRelativeRotation; rotation = spatialKey.leftRelativeRotation;
} }
if (hand === RIGHT_HAND && spatialKey.rightRelativeRotation) { if (hand === RIGHT_HAND && spatialKey.rightRelativeRotation) {
return spatialKey.rightRelativeRotation; rotation = spatialKey.rightRelativeRotation;
} }
if (spatialKey.relativeRotation) { if (spatialKey.relativeRotation) {
return spatialKey.relativeRotation; rotation = spatialKey.relativeRotation;
} }
return Quat.IDENTITY; // Flip left hand
if (hand !== RIGHT_HAND) {
rotation = Quat.multiply(yFlip, rotation);
}
return rotation;
} }
function MyController(hand) { function MyController(hand) {
@ -254,6 +264,7 @@ function MyController(hand) {
this.overlayLine = null; this.overlayLine = null;
this.ignoreIK = false;
this.offsetPosition = Vec3.ZERO; this.offsetPosition = Vec3.ZERO;
this.offsetRotation = Quat.IDENTITY; this.offsetRotation = Quat.IDENTITY;
@ -853,9 +864,12 @@ function MyController(hand) {
if (this.state != STATE_NEAR_GRABBING && grabbableData.spatialKey) { if (this.state != STATE_NEAR_GRABBING && grabbableData.spatialKey) {
// if an object is "equipped" and has a spatialKey, use it. // if an object is "equipped" and has a spatialKey, use it.
this.ignoreIK = grabbableData.spatialKey.ignoreIK ? grabbableData.spatialKey.ignoreIK : false;
this.offsetPosition = getSpatialOffsetPosition(this.hand, grabbableData.spatialKey); this.offsetPosition = getSpatialOffsetPosition(this.hand, grabbableData.spatialKey);
this.offsetRotation = getSpatialOffsetRotation(this.hand, grabbableData.spatialKey); this.offsetRotation = getSpatialOffsetRotation(this.hand, grabbableData.spatialKey);
} else { } else {
this.ignoreIK = false;
var objectRotation = grabbedProperties.rotation; var objectRotation = grabbedProperties.rotation;
this.offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); this.offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation);
@ -872,7 +886,8 @@ function MyController(hand) {
relativeRotation: this.offsetRotation, relativeRotation: this.offsetRotation,
ttl: ACTION_TTL, ttl: ACTION_TTL,
kinematic: NEAR_GRABBING_KINEMATIC, kinematic: NEAR_GRABBING_KINEMATIC,
kinematicSetVelocity: true kinematicSetVelocity: true,
ignoreIK: this.ignoreIK
}); });
if (this.actionID === NULL_ACTION_ID) { if (this.actionID === NULL_ACTION_ID) {
this.actionID = null; this.actionID = null;
@ -956,7 +971,8 @@ function MyController(hand) {
relativeRotation: this.offsetRotation, relativeRotation: this.offsetRotation,
ttl: ACTION_TTL, ttl: ACTION_TTL,
kinematic: NEAR_GRABBING_KINEMATIC, kinematic: NEAR_GRABBING_KINEMATIC,
kinematicSetVelocity: true kinematicSetVelocity: true,
ignoreIK: this.ignoreIK
}); });
this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC);
} }
@ -982,6 +998,7 @@ function MyController(hand) {
// use a spring to pull the object to where it will be when equipped // use a spring to pull the object to where it will be when equipped
var relativeRotation = getSpatialOffsetRotation(this.hand, grabbableData.spatialKey); var relativeRotation = getSpatialOffsetRotation(this.hand, grabbableData.spatialKey);
var relativePosition = getSpatialOffsetPosition(this.hand, grabbableData.spatialKey); var relativePosition = getSpatialOffsetPosition(this.hand, grabbableData.spatialKey);
var ignoreIK = grabbableData.spatialKey.ignoreIK ? grabbableData.spatialKey.ignoreIK : false;
var handRotation = this.getHandRotation(); var handRotation = this.getHandRotation();
var handPosition = this.getHandPosition(); var handPosition = this.getHandPosition();
var targetRotation = Quat.multiply(handRotation, relativeRotation); var targetRotation = Quat.multiply(handRotation, relativeRotation);
@ -996,7 +1013,8 @@ function MyController(hand) {
linearTimeScale: EQUIP_SPRING_TIMEFRAME, linearTimeScale: EQUIP_SPRING_TIMEFRAME,
targetRotation: targetRotation, targetRotation: targetRotation,
angularTimeScale: EQUIP_SPRING_TIMEFRAME, angularTimeScale: EQUIP_SPRING_TIMEFRAME,
ttl: ACTION_TTL ttl: ACTION_TTL,
ignoreIK: ignoreIK
}); });
if (this.equipSpringID === NULL_ACTION_ID) { if (this.equipSpringID === NULL_ACTION_ID) {
this.equipSpringID = null; this.equipSpringID = null;
@ -1009,7 +1027,8 @@ function MyController(hand) {
linearTimeScale: EQUIP_SPRING_TIMEFRAME, linearTimeScale: EQUIP_SPRING_TIMEFRAME,
targetRotation: targetRotation, targetRotation: targetRotation,
angularTimeScale: EQUIP_SPRING_TIMEFRAME, angularTimeScale: EQUIP_SPRING_TIMEFRAME,
ttl: ACTION_TTL ttl: ACTION_TTL,
ignoreIK: ignoreIK
}); });
} }

View file

@ -298,7 +298,6 @@
var elModelAnimationLastFrame = document.getElementById("property-model-animation-last-frame"); var elModelAnimationLastFrame = document.getElementById("property-model-animation-last-frame");
var elModelAnimationLoop = document.getElementById("property-model-animation-loop"); var elModelAnimationLoop = document.getElementById("property-model-animation-loop");
var elModelAnimationHold = document.getElementById("property-model-animation-hold"); var elModelAnimationHold = document.getElementById("property-model-animation-hold");
var elModelAnimationStartAutomatically = document.getElementById("property-model-animation-start-automatically");
var elModelTextures = document.getElementById("property-model-textures"); var elModelTextures = document.getElementById("property-model-textures");
var elModelOriginalTextures = document.getElementById("property-model-original-textures"); var elModelOriginalTextures = document.getElementById("property-model-original-textures");
@ -532,7 +531,6 @@
elModelAnimationLastFrame.value = properties.animation.lastFrame; elModelAnimationLastFrame.value = properties.animation.lastFrame;
elModelAnimationLoop.checked = properties.animation.loop; elModelAnimationLoop.checked = properties.animation.loop;
elModelAnimationHold.checked = properties.animation.hold; elModelAnimationHold.checked = properties.animation.hold;
elModelAnimationStartAutomatically.checked = properties.animation.startAutomatically;
elModelTextures.value = properties.textures; elModelTextures.value = properties.textures;
elModelOriginalTextures.value = properties.originalTextures; elModelOriginalTextures.value = properties.originalTextures;
} else if (properties.type == "Web") { } else if (properties.type == "Web") {
@ -785,7 +783,6 @@
elModelAnimationLastFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'lastFrame')); elModelAnimationLastFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'lastFrame'));
elModelAnimationLoop.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'loop')); elModelAnimationLoop.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'loop'));
elModelAnimationHold.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'hold')); elModelAnimationHold.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'hold'));
elModelAnimationStartAutomatically.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'startAutomatically'));
elModelTextures.addEventListener('change', createEmitTextPropertyUpdateFunction('textures')); elModelTextures.addEventListener('change', createEmitTextPropertyUpdateFunction('textures'));
@ -1348,12 +1345,6 @@
<input type='checkbox' id="property-model-animation-hold"> <input type='checkbox' id="property-model-animation-hold">
</span> </span>
</div> </div>
<div class="model-section property">
<span class="label">Animation Start Automatically</span>
<span class="value">
<input type='checkbox' id="property-model-animation-start-automatically">
</span>
</div>
<div class="model-section property"> <div class="model-section property">
<div class="label">Textures</div> <div class="label">Textures</div>
<div class="value"> <div class="value">

View file

@ -74,7 +74,9 @@ var keysToIgnore = [
'shapeType', 'shapeType',
'isEmitting', 'isEmitting',
'sittingPoints', 'sittingPoints',
'originalTextures' 'originalTextures',
'parentJointIndex',
'parentID'
]; ];
var individualKeys = []; var individualKeys = [];

View file

@ -66,21 +66,6 @@
max2: 15 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 USE_DEBOUNCE = false;
var TRIGGER_CONTROLS = [ var TRIGGER_CONTROLS = [
@ -168,11 +153,9 @@
var handToDisable = this.initialHand === 'right' ? 'left' : 'right'; var handToDisable = this.initialHand === 'right' ? 'left' : 'right';
Messages.sendMessage('Hifi-Hand-Disabler', handToDisable); Messages.sendMessage('Hifi-Hand-Disabler', handToDisable);
setEntityCustomData('grabbableKey', this.entityID, { var data = getEntityCustomData('grabbableKey', this.entityID, {});
grabbable: false, data.grabbable = false;
invertSolidWhileHeld: true, setEntityCustomData('grabbableKey', this.entityID, data);
spatialKey: BOW_SPATIAL_KEY
});
}, },
continueNearGrab: function() { continueNearGrab: function() {
@ -226,11 +209,10 @@
this.isGrabbed = false; this.isGrabbed = false;
this.stringDrawn = false; this.stringDrawn = false;
this.deleteStrings(); this.deleteStrings();
setEntityCustomData('grabbableKey', this.entityID, {
grabbable: true, var data = getEntityCustomData('grabbableKey', this.entityID, {});
invertSolidWhileHeld: true, data.grabbable = true;
spatialKey: BOW_SPATIAL_KEY setEntityCustomData('grabbableKey', this.entityID, data);
});
Entities.deleteEntity(this.preNotchString); Entities.deleteEntity(this.preNotchString);
Entities.deleteEntity(this.arrow); Entities.deleteEntity(this.arrow);
this.aiming = false; this.aiming = false;

View file

@ -49,14 +49,14 @@ var bow = Entities.addEntity({
invertSolidWhileHeld: true, invertSolidWhileHeld: true,
spatialKey: { spatialKey: {
leftRelativePosition: { leftRelativePosition: {
x: 0.05, x: -0.02,
y: 0.06, y: 0.08,
z: -0.05 z: 0.09
}, },
rightRelativePosition: { relativePosition: {
x: -0.05, x: 0.02,
y: 0.06, y: 0.08,
z: -0.05 z: 0.09
}, },
relativeRotation: Quat.fromPitchYawRollDegrees(0, 90, -90) relativeRotation: Quat.fromPitchYawRollDegrees(0, 90, -90)
} }

View file

@ -53,8 +53,13 @@ var wand = Entities.addEntity({
y: 0.1, y: 0.1,
z: 0 z: 0
}, },
relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 90) relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, -90)
} }
} }
}) })
}); });
function scriptEnding() {
Entities.deleteEntity(wand);
}
Script.scriptEnding.connect(scriptEnding);

View file

@ -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 //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(); 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. //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; 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 // 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'; this.hand = 'LEFT';
}, },
startNearGrab: function() { startNearGrab: function(entityID) {
if (!this.hasSpotlight) { 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 light casts the beam
this.spotlight = Entities.addEntity({ this.spotlight = Entities.addEntity({
type: "Light", type: "Light",
@ -97,6 +102,7 @@
y: 2, y: 2,
z: 20 z: 20
}, },
parentID: this.entityID,
color: { color: {
red: 255, red: 255,
green: 255, green: 255,
@ -105,7 +111,9 @@
intensity: 2, intensity: 2,
exponent: 0.3, exponent: 0.3,
cutoff: 20, 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 //this light creates the effect of a bulb at the end of the flashlight
@ -116,6 +124,7 @@
y: 0.25, y: 0.25,
z: 0.25 z: 0.25
}, },
parentID: this.entityID,
isSpotlight: false, isSpotlight: false,
color: { color: {
red: 255, red: 255,
@ -123,8 +132,11 @@
blue: 255 blue: 255
}, },
exponent: 0, exponent: 0,
lifetime: LIFETIME,
cutoff: 90, // in degrees cutoff: 90, // in degrees
lifetime: LIFETIME position: glowLightTransform.p,
rotation: glowLightTransform.q,
}); });
this.hasSpotlight = true; 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 //only set the active hand once -- if we always read the current hand, our 'holding' hand will get overwritten
this.setWhichHand(); this.setWhichHand();
} else { } else {
this.updateLightPositions();
this.changeLightWithTriggerPressure(this.whichHand); this.changeLightWithTriggerPressure(this.whichHand);
} }
}, },
@ -160,28 +171,6 @@
} }
}, },
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) { changeLightWithTriggerPressure: function(flashLightHand) {
if (flashLightHand === 'LEFT') { if (flashLightHand === 'LEFT') {

View file

@ -28,10 +28,10 @@ var pistol = Entities.addEntity({
spatialKey: { spatialKey: {
relativePosition: { relativePosition: {
x: 0, x: 0,
y: 0, y: 0.05,
z: 0 z: -0.08
}, },
relativeRotation: Quat.fromPitchYawRollDegrees(45, 90, 0) relativeRotation: Quat.fromPitchYawRollDegrees(90, 90, 0)
}, },
invertSolidWhileHeld: true invertSolidWhileHeld: true
} }

View file

@ -1058,7 +1058,7 @@ void MyAvatar::rebuildSkeletonBody() {
void MyAvatar::prepareForPhysicsSimulation() { void MyAvatar::prepareForPhysicsSimulation() {
relayDriveKeysToCharacterController(); relayDriveKeysToCharacterController();
_characterController.setTargetVelocity(getTargetVelocity()); _characterController.setTargetVelocity(getTargetVelocity());
_characterController.setAvatarPositionAndOrientation(getPosition(), getOrientation()); _characterController.setPositionAndOrientation(getPosition(), getOrientation());
if (qApp->isHMDMode()) { if (qApp->isHMDMode()) {
updateHMDFollowVelocity(); updateHMDFollowVelocity();
} else if (_followSpeed > 0.0f) { } else if (_followSpeed > 0.0f) {
@ -1071,7 +1071,7 @@ void MyAvatar::prepareForPhysicsSimulation() {
void MyAvatar::harvestResultsFromPhysicsSimulation() { void MyAvatar::harvestResultsFromPhysicsSimulation() {
glm::vec3 position = getPosition(); glm::vec3 position = getPosition();
glm::quat orientation = getOrientation(); glm::quat orientation = getOrientation();
_characterController.getAvatarPositionAndOrientation(position, orientation); _characterController.getPositionAndOrientation(position, orientation);
nextAttitude(position, orientation); nextAttitude(position, orientation);
if (_followSpeed > 0.0f) { if (_followSpeed > 0.0f) {
adjustSensorTransform(); adjustSensorTransform();

View file

@ -11,255 +11,25 @@
#include "MyCharacterController.h" #include "MyCharacterController.h"
#include <BulletCollision/CollisionShapes/btMultiSphereShape.h> #include <BulletUtil.h>
#include <BulletDynamics/Dynamics/btRigidBody.h>
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
#include <LinearMath/btDefaultMotionState.h>
#include <GLMHelpers.h>
#include <PhysicsLogging.h>
#include <PhysicsCollisionGroups.h>
#include "MyAvatar.h" #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: improve walking up steps
// TODO: make avatars able to walk up and down steps/slopes // TODO: make avatars able to walk up and down steps/slopes
// TODO: make avatars stand on steep slope // TODO: make avatars stand on steep slope
// TODO: make avatars not snag on low ceilings // 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) { MyCharacterController::MyCharacterController(MyAvatar* avatar) {
_halfHeight = 1.0f;
assert(avatar); assert(avatar);
_avatar = 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(); updateShapeIfNecessary();
} }
MyCharacterController::~MyCharacterController() { 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() { void MyCharacterController::updateShapeIfNecessary() {
if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) {
_pendingFlags &= ~ PENDING_FLAG_UPDATE_SHAPE; _pendingFlags &= ~ PENDING_FLAG_UPDATE_SHAPE;
@ -300,7 +70,7 @@ void MyCharacterController::updateShapeIfNecessary() {
if (_isHovering) { if (_isHovering) {
_rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f)); _rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f));
} else { } else {
_rigidBody->setGravity(DEFAULT_GRAVITY * _currentUp); _rigidBody->setGravity(DEFAULT_CHARACTER_GRAVITY * _currentUp);
} }
//_rigidBody->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT); //_rigidBody->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
} else { } 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
}

View file

@ -13,12 +13,8 @@
#ifndef hifi_MyCharacterController_h #ifndef hifi_MyCharacterController_h
#define hifi_MyCharacterController_h #define hifi_MyCharacterController_h
#include <btBulletDynamicsCommon.h>
#include <glm/glm.hpp>
#include <BulletUtil.h>
#include <CharacterController.h> #include <CharacterController.h>
#include <SharedUtil.h> //#include <SharedUtil.h>
class btCollisionShape; class btCollisionShape;
class MyAvatar; class MyAvatar;
@ -28,79 +24,10 @@ public:
MyCharacterController(MyAvatar* avatar); MyCharacterController(MyAvatar* avatar);
~MyCharacterController (); ~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; 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: 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 }; 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 #endif // hifi_MyCharacterController_h

View file

@ -14,8 +14,6 @@
#include "stereo/InterleavedStereoDisplayPlugin.h" #include "stereo/InterleavedStereoDisplayPlugin.h"
#include "Basic2DWindowOpenGLDisplayPlugin.h" #include "Basic2DWindowOpenGLDisplayPlugin.h"
#include "openvr/OpenVrDisplayPlugin.h"
const QString& DisplayPlugin::MENU_PATH() { const QString& DisplayPlugin::MENU_PATH() {
static const QString value = "Display"; static const QString value = "Display";
return value; return value;
@ -25,22 +23,14 @@ const QString& DisplayPlugin::MENU_PATH() {
DisplayPluginList getDisplayPlugins() { DisplayPluginList getDisplayPlugins() {
DisplayPlugin* PLUGIN_POOL[] = { DisplayPlugin* PLUGIN_POOL[] = {
new Basic2DWindowOpenGLDisplayPlugin(), new Basic2DWindowOpenGLDisplayPlugin(),
new NullDisplayPlugin(),
#ifdef DEBUG #ifdef DEBUG
new NullDisplayPlugin(),
#endif #endif
// Stereo modes // Stereo modes
// SBS left/right // SBS left/right
new SideBySideStereoDisplayPlugin(), new SideBySideStereoDisplayPlugin(),
// Interleaved left/right // Interleaved left/right
new InterleavedStereoDisplayPlugin(), new InterleavedStereoDisplayPlugin(),
// HMDs
//#ifdef Q_OS_WIN
// // SteamVR SDK
// new OpenVrDisplayPlugin(),
//#endif
nullptr nullptr
}; };

View file

@ -15,6 +15,7 @@
#include <QtOpenGL/QGLWidget> #include <QtOpenGL/QGLWidget>
#include <QtGui/QImage> #include <QtGui/QImage>
#include <QtGui/QOpenGLContext>
#include <gl/GLWidget.h> #include <gl/GLWidget.h>
#include <NumericalConstants.h> #include <NumericalConstants.h>
@ -103,8 +104,12 @@ public:
// take the latest texture and present it // take the latest texture and present it
_context->makeCurrent(); _context->makeCurrent();
if (QOpenGLContext::currentContext() == _context->contextHandle()) {
currentPlugin->present(); currentPlugin->present();
_context->doneCurrent(); _context->doneCurrent();
} else {
qWarning() << "Makecurrent failed";
}
} }
_context->makeCurrent(); _context->makeCurrent();

View file

@ -74,7 +74,7 @@ protected:
ProgramPtr _program; ProgramPtr _program;
ShapeWrapperPtr _plane; ShapeWrapperPtr _plane;
Mutex _mutex; mutable Mutex _mutex;
SimpleMovingAverage _usecsPerFrame { 10 }; SimpleMovingAverage _usecsPerFrame { 10 };
QMap<uint32_t, uint32_t> _sceneTextureToFrameIndexMap; QMap<uint32_t, uint32_t> _sceneTextureToFrameIndexMap;

View file

@ -60,9 +60,6 @@ public:
void setTexture(gpu::TexturePointer texture) { _texture = texture; } void setTexture(gpu::TexturePointer texture) { _texture = texture; }
const gpu::TexturePointer& getTexture() const { return _texture; } const gpu::TexturePointer& getTexture() const { return _texture; }
bool getVisibleFlag() const { return _visibleFlag; }
void setVisibleFlag(bool visibleFlag) { _visibleFlag = visibleFlag; }
void render(RenderArgs* args) const { void render(RenderArgs* args) const {
assert(_pipeline); assert(_pipeline);
@ -82,8 +79,9 @@ public:
batch.drawIndexed(gpu::TRIANGLES, numIndices); batch.drawIndexed(gpu::TRIANGLES, numIndices);
} }
protected:
EntityItemPointer _entity; EntityItemPointer _entity;
protected:
Transform _modelTransform; Transform _modelTransform;
AABox _bound; AABox _bound;
gpu::PipelinePointer _pipeline; gpu::PipelinePointer _pipeline;
@ -91,13 +89,12 @@ protected:
gpu::BufferPointer _vertexBuffer; gpu::BufferPointer _vertexBuffer;
gpu::BufferPointer _indexBuffer; gpu::BufferPointer _indexBuffer;
gpu::TexturePointer _texture; gpu::TexturePointer _texture;
bool _visibleFlag = true;
}; };
namespace render { namespace render {
template <> template <>
const ItemKey payloadGetKey(const ParticlePayload::Pointer& payload) { const ItemKey payloadGetKey(const ParticlePayload::Pointer& payload) {
if (payload->getVisibleFlag()) { if (payload->_entity->getVisible()) {
return ItemKey::Builder::transparentShape(); return ItemKey::Builder::transparentShape();
} else { } else {
return ItemKey::Builder().withInvisible().build(); return ItemKey::Builder().withInvisible().build();
@ -111,8 +108,11 @@ namespace render {
template <> template <>
void payloadRender(const ParticlePayload::Pointer& payload, RenderArgs* args) { void payloadRender(const ParticlePayload::Pointer& payload, RenderArgs* args) {
if (payload->_entity->getVisible()) {
payload->render(args); payload->render(args);
} }
}
} }

View file

@ -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_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_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_HOLD, Animation, animation, Hold, hold, _animationLoop->getHold);
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically, _animationLoop->getStartAutomatically);
} else { } else {
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, Animation, animation, FPS, fps); 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); 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_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_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_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, firstFrame, float, _animationLoop->setFirstFrame);
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, _animationLoop->setLastFrame); 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, hold, bool, _animationLoop->setHold);
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, _animationLoop->setStartAutomatically);
// legacy property support // legacy property support
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, _animationLoop->setFPS, _animationLoop->getFPS); 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, firstFrame, float, setFirstFrame);
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, setLastFrame); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, setLastFrame);
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, setHold); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, setHold);
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, setStartAutomatically);
// legacy property support // legacy property support
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, setFPS, getFPS); 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(); float lastFrame = _animationLoop ? _animationLoop->getLastFrame() : getLastFrame();
bool loop = _animationLoop ? _animationLoop->getLoop() : getLoop(); bool loop = _animationLoop ? _animationLoop->getLoop() : getLoop();
bool hold = _animationLoop ? _animationLoop->getHold() : getHold(); bool hold = _animationLoop ? _animationLoop->getHold() : getHold();
bool startAutomatically = _animationLoop ? _animationLoop->getStartAutomatically() : getStartAutomatically();
QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8());
QJsonObject settingsAsJsonObject = settingsAsJson.object(); QJsonObject settingsAsJsonObject = settingsAsJson.object();
@ -130,10 +125,6 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) {
running = settingsMap["hold"].toBool(); running = settingsMap["hold"].toBool();
} }
if (settingsMap.contains("startAutomatically")) {
running = settingsMap["startAutomatically"].toBool();
}
if (_animationLoop) { if (_animationLoop) {
_animationLoop->setFPS(fps); _animationLoop->setFPS(fps);
_animationLoop->setCurrentFrame(currentFrame); _animationLoop->setCurrentFrame(currentFrame);
@ -142,7 +133,6 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) {
_animationLoop->setLastFrame(lastFrame); _animationLoop->setLastFrame(lastFrame);
_animationLoop->setLoop(loop); _animationLoop->setLoop(loop);
_animationLoop->setHold(hold); _animationLoop->setHold(hold);
_animationLoop->setStartAutomatically(startAutomatically);
} else { } else {
setFPS(fps); setFPS(fps);
setCurrentFrame(currentFrame); setCurrentFrame(currentFrame);
@ -151,7 +141,6 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) {
setLastFrame(lastFrame); setLastFrame(lastFrame);
setLoop(loop); setLoop(loop);
setHold(hold); 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_FIRST_FRAME, _animationLoop->getFirstFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically());
} else { } else {
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame()); 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_FIRST_FRAME, getFirstFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically());
} }
return true; 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_FIRST_FRAME, float, _animationLoop->setFirstFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold); READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold);
READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically);
} else { } else {
READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS);
READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame); 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_FIRST_FRAME, float, setFirstFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); 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); 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_FIRST_FRAME, FirstFrame);
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LAST_FRAME, LastFrame); 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_HOLD, Hold);
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically);
processedBytes += bytesRead; processedBytes += bytesRead;
@ -273,7 +257,6 @@ EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const {
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FIRST_FRAME, firstFrame); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FIRST_FRAME, firstFrame);
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LAST_FRAME, lastFrame); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LAST_FRAME, lastFrame);
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_HOLD, hold); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_HOLD, hold);
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_START_AUTOMATICALLY, startAutomatically);
return changedProperties; 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, FirstFrame, _animationLoop->getFirstFrame);
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, _animationLoop->getLastFrame); 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, Hold, _animationLoop->getHold);
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, _animationLoop->getStartAutomatically);
} else { } else {
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, getFPS); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, getFPS);
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, CurrentFrame, getCurrentFrame); 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, FirstFrame, getFirstFrame);
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, getLastFrame); 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, 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, FirstFrame, firstFrame, _animationLoop->setFirstFrame);
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, _animationLoop->setLastFrame); 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, Hold, hold, _animationLoop->setHold);
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, _animationLoop->setStartAutomatically);
} else { } else {
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, setFPS); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, setFPS);
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, CurrentFrame, currentFrame, setCurrentFrame); 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, FirstFrame, firstFrame, setFirstFrame);
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, setLastFrame); 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, Hold, hold, setHold);
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, setStartAutomatically);
} }
return somethingChanged; return somethingChanged;
@ -339,7 +318,6 @@ EntityPropertyFlags AnimationPropertyGroup::getEntityProperties(EncodeBitstreamP
requestedProperties += PROP_ANIMATION_FIRST_FRAME; requestedProperties += PROP_ANIMATION_FIRST_FRAME;
requestedProperties += PROP_ANIMATION_LAST_FRAME; requestedProperties += PROP_ANIMATION_LAST_FRAME;
requestedProperties += PROP_ANIMATION_HOLD; requestedProperties += PROP_ANIMATION_HOLD;
requestedProperties += PROP_ANIMATION_START_AUTOMATICALLY;
return requestedProperties; 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_FIRST_FRAME, _animationLoop->getFirstFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically());
} else { } else {
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame()); 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_FIRST_FRAME, getFirstFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame());
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); 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_FIRST_FRAME, float, _animationLoop->setFirstFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold); READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold);
READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically);
} else { } else {
READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS);
READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame); 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_FIRST_FRAME, float, setFirstFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame);
READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold);
READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically);
} }
return bytesRead; return bytesRead;

View file

@ -80,7 +80,6 @@ public:
DEFINE_PROPERTY(PROP_ANIMATION_FIRST_FRAME, FirstFrame, firstFrame, float, 0.0f); // was animationSettings.firstFrame 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_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_HOLD, Hold, hold, bool, false); // was animationSettings.hold
DEFINE_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically, startAutomatically, bool, false); // was animationSettings.startAutomatically
protected: protected:
void setFromOldAnimationSettings(const QString& value); void setFromOldAnimationSettings(const QString& value);

View file

@ -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_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_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_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_CENTER, Atmosphere, atmosphere, Center, center);
ADD_GROUP_PROPERTY_TO_MAP(PROP_ATMOSPHERE_INNER_RADIUS, Atmosphere, atmosphere, InnerRadius, innerRadius); ADD_GROUP_PROPERTY_TO_MAP(PROP_ATMOSPHERE_INNER_RADIUS, Atmosphere, atmosphere, InnerRadius, innerRadius);

View file

@ -384,11 +384,6 @@ void ModelEntityItem::setAnimationSettings(const QString& value) {
setAnimationHold(hold); setAnimationHold(hold);
} }
if (settingsMap.contains("startAutomatically")) {
bool startAutomatically = settingsMap["startAutomatically"].toBool();
setAnimationStartAutomatically(startAutomatically);
}
_dirtyFlags |= Simulation::DIRTY_UPDATEABLE; _dirtyFlags |= Simulation::DIRTY_UPDATEABLE;
} }

View file

@ -97,9 +97,6 @@ public:
void setAnimationHold(bool hold) { _animationLoop.setHold(hold); } void setAnimationHold(bool hold) { _animationLoop.setHold(hold); }
bool getAnimationHold() const { return _animationLoop.getHold(); } 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); } void setAnimationFirstFrame(float firstFrame) { _animationLoop.setFirstFrame(firstFrame); }
float getAnimationFirstFrame() const { return _animationLoop.getFirstFrame(); } float getAnimationFirstFrame() const { return _animationLoop.getFirstFrame(); }

View file

@ -1,15 +1,5 @@
set(TARGET_NAME input-plugins) set(TARGET_NAME input-plugins)
setup_hifi_library() setup_hifi_library()
link_hifi_libraries(shared plugins controllers script-engine render-utils) link_hifi_libraries(shared plugins controllers)
GroupSources("src/input-plugins") 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()

View file

@ -15,7 +15,6 @@
#include "KeyboardMouseDevice.h" #include "KeyboardMouseDevice.h"
#include "SDL2Manager.h" #include "SDL2Manager.h"
#include "SixenseManager.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 // TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class
InputPluginList getInputPlugins() { InputPluginList getInputPlugins() {
@ -23,7 +22,6 @@ InputPluginList getInputPlugins() {
new KeyboardMouseDevice(), new KeyboardMouseDevice(),
new SDL2Manager(), new SDL2Manager(),
new SixenseManager(), new SixenseManager(),
new ViveControllerManager(),
nullptr nullptr
}; };

View file

@ -21,6 +21,7 @@
#include <controllers/UserInputMapper.h> #include <controllers/UserInputMapper.h>
#include <GLMHelpers.h> #include <GLMHelpers.h>
#include <DebugDraw.h>
#include <NumericalConstants.h> #include <NumericalConstants.h>
#include <PathUtils.h> #include <PathUtils.h>
#include <PerfStat.h> #include <PerfStat.h>
@ -48,6 +49,8 @@ const QString MENU_PARENT = "Avatar";
const QString MENU_NAME = "Sixense"; const QString MENU_NAME = "Sixense";
const QString MENU_PATH = MENU_PARENT + ">" + MENU_NAME; const QString MENU_PATH = MENU_PARENT + ">" + MENU_NAME;
const QString TOGGLE_SMOOTH = "Smooth Sixense Movement"; 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 { bool SixenseManager::isSupported() const {
#ifdef HAVE_SIXENSE #ifdef HAVE_SIXENSE
@ -72,6 +75,14 @@ void SixenseManager::activate() {
[this] (bool clicked) { setSixenseFilter(clicked); }, [this] (bool clicked) { setSixenseFilter(clicked); },
true, true); 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<controller::UserInputMapper>(); auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
userInputMapper->registerDevice(_inputDevice); userInputMapper->registerDevice(_inputDevice);
@ -149,6 +160,9 @@ void SixenseManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
// we only support two controllers // we only support two controllers
SixenseControllerData controllers[2]; SixenseControllerData controllers[2];
// store the raw controller data for debug rendering
controller::Pose rawPoses[2];
int numActiveControllers = 0; int numActiveControllers = 0;
for (int i = 0; i < maxControllers && numActiveControllers < 2; i++) { for (int i = 0; i < maxControllers && numActiveControllers < 2; i++) {
if (!sixenseIsControllerEnabled(i)) { if (!sixenseIsControllerEnabled(i)) {
@ -175,7 +189,7 @@ void SixenseManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
// Rotation of Palm // Rotation of Palm
glm::quat rotation(data->rot_quat[3], data->rot_quat[0], data->rot_quat[1], data->rot_quat[2]); glm::quat rotation(data->rot_quat[3], data->rot_quat[0], data->rot_quat[1], data->rot_quat[2]);
handlePoseEvent(deltaTime, position, rotation, left); handlePoseEvent(deltaTime, position, rotation, left);
rawPoses[i] = controller::Pose(position, rotation, glm::vec3(0), glm::quat());
} else { } else {
_poseStateMap.clear(); _poseStateMap.clear();
_collectedSamples.clear(); _collectedSamples.clear();
@ -197,9 +211,54 @@ void SixenseManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
_axisStateMap[axisState.first] = 0.0f; _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 #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 #ifdef HAVE_SIXENSE
// the calibration sequence is: // the calibration sequence is:

View file

@ -60,6 +60,8 @@ private:
class InputDevice : public controller::InputDevice { class InputDevice : public controller::InputDevice {
public: public:
InputDevice() : controller::InputDevice("Hydra") {} InputDevice() : controller::InputDevice("Hydra") {}
void setDebugDrawRaw(bool flag);
void setDebugDrawCalibrated(bool flag);
private: private:
// Device functions // Device functions
virtual controller::Input::NamedVector getAvailableInputs() const override; virtual controller::Input::NamedVector getAvailableInputs() const override;
@ -82,6 +84,8 @@ private:
float _lastDistance; float _lastDistance;
bool _requestReset { false }; bool _requestReset { false };
bool _debugDrawRaw { false };
bool _debugDrawCalibrated { false };
// these are measured values used to compute the calibration results // these are measured values used to compute the calibration results
quint64 _lockExpiry; quint64 _lockExpiry;
glm::vec3 _averageLeft; glm::vec3 _averageLeft;

View file

@ -41,7 +41,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
case PacketType::EntityAdd: case PacketType::EntityAdd:
case PacketType::EntityEdit: case PacketType::EntityEdit:
case PacketType::EntityData: case PacketType::EntityData:
return VERSION_ENTITIES_HAVE_PARENTS; return VERSION_ENTITITES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP;
case PacketType::AvatarData: case PacketType::AvatarData:
case PacketType::BulkAvatarData: case PacketType::BulkAvatarData:
return 17; return 17;

View file

@ -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_PARTICLES_ADDITIVE_BLENDING = 49;
const PacketVersion VERSION_ENTITIES_POLYLINE_TEXTURE = 50; const PacketVersion VERSION_ENTITIES_POLYLINE_TEXTURE = 50;
const PacketVersion VERSION_ENTITIES_HAVE_PARENTS = 51; const PacketVersion VERSION_ENTITIES_HAVE_PARENTS = 51;
const PacketVersion VERSION_ENTITITES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP = 52;
#endif // hifi_PacketHeaders_h #endif // hifi_PacketHeaders_h

View file

@ -11,8 +11,55 @@
#include "CharacterController.h" #include "CharacterController.h"
#include <NumericalConstants.h>
#include "BulletUtil.h"
#include "PhysicsCollisionGroups.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 { bool CharacterController::needsRemoval() const {
return ((_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION) == PENDING_FLAG_REMOVE_FROM_SIMULATION); return ((_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION) == PENDING_FLAG_REMOVE_FROM_SIMULATION);
} }
@ -33,9 +80,13 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) {
if (world && _rigidBody) { if (world && _rigidBody) {
_dynamicsWorld = world; _dynamicsWorld = world;
_pendingFlags &= ~PENDING_FLAG_JUMP; _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->addRigidBody(_rigidBody, COLLISION_GROUP_MY_AVATAR, COLLISION_MASK_MY_AVATAR);
_dynamicsWorld->addAction(this); _dynamicsWorld->addAction(this);
//reset(_dynamicsWorld); // restore gravity settings
_rigidBody->setGravity(oldGravity);
} }
} }
if (_dynamicsWorld) { if (_dynamicsWorld) {
@ -50,3 +101,281 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) {
} }
} }
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
}

View file

@ -17,11 +17,14 @@
#include <btBulletDynamicsCommon.h> #include <btBulletDynamicsCommon.h>
#include <BulletDynamics/Character/btCharacterControllerInterface.h> #include <BulletDynamics/Character/btCharacterControllerInterface.h>
#include <GLMHelpers.h>
const uint32_t PENDING_FLAG_ADD_TO_SIMULATION = 1U << 0; 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_REMOVE_FROM_SIMULATION = 1U << 1;
const uint32_t PENDING_FLAG_UPDATE_SHAPE = 1U << 2; const uint32_t PENDING_FLAG_UPDATE_SHAPE = 1U << 2;
const uint32_t PENDING_FLAG_JUMP = 1U << 3; const uint32_t PENDING_FLAG_JUMP = 1U << 3;
const float DEFAULT_CHARACTER_GRAVITY = -5.0f;
class btRigidBody; class btRigidBody;
class btCollisionWorld; class btCollisionWorld;
@ -29,31 +32,89 @@ class btDynamicsWorld;
class CharacterController : public btCharacterControllerInterface { class CharacterController : public btCharacterControllerInterface {
public: public:
CharacterController();
virtual ~CharacterController() {}
bool needsRemoval() const; bool needsRemoval() const;
bool needsAddition() const; bool needsAddition() const;
void setDynamicsWorld(btDynamicsWorld* world); void setDynamicsWorld(btDynamicsWorld* world);
btCollisionObject* getCollisionObject() { return _rigidBody; } btCollisionObject* getCollisionObject() { return _rigidBody; }
virtual void updateShapeIfNecessary() = 0; 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 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: 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 }; btDynamicsWorld* _dynamicsWorld { nullptr };
btRigidBody* _rigidBody { nullptr }; btRigidBody* _rigidBody { nullptr };
uint32_t _pendingFlags { 0 }; uint32_t _pendingFlags { 0 };
}; };
#endif // hifi_CharacterControllerInterface_h #endif // hifi_CharacterControllerInterface_h

View file

@ -82,7 +82,7 @@ void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) {
} }
Q_DECLARE_METATYPE(controller::InputController*) Q_DECLARE_METATYPE(controller::InputController*)
static int inputControllerPointerId = qRegisterMetaType<controller::InputController*>(); //static int inputControllerPointerId = qRegisterMetaType<controller::InputController*>();
QScriptValue inputControllerToScriptValue(QScriptEngine *engine, controller::InputController* const &in) { QScriptValue inputControllerToScriptValue(QScriptEngine *engine, controller::InputController* const &in) {
return engine->newQObject(in); return engine->newQObject(in);

View file

@ -20,9 +20,7 @@ glm::mat4 OculusBaseDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseP
} }
void OculusBaseDisplayPlugin::resetSensors() { void OculusBaseDisplayPlugin::resetSensors() {
#if (OVR_MAJOR_VERSION >= 6) ovr_RecenterPose(_session);
ovr_RecenterPose(_hmd);
#endif
} }
glm::mat4 OculusBaseDisplayPlugin::getEyeToHeadTransform(Eye eye) const { 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 { glm::mat4 OculusBaseDisplayPlugin::getHeadPose(uint32_t frameIndex) const {
#if (OVR_MAJOR_VERSION >= 6) static uint32_t lastFrameSeen = 0;
auto frameTiming = ovr_GetFrameTiming(_hmd, frameIndex); auto displayTime = ovr_GetPredictedDisplayTime(_session, frameIndex);
auto trackingState = ovr_GetTrackingState(_hmd, frameTiming.DisplayMidpointSeconds); auto trackingState = ovr_GetTrackingState(_session, displayTime, frameIndex > lastFrameSeen);
if (frameIndex > lastFrameSeen) {
lastFrameSeen = frameIndex;
}
return toGlm(trackingState.HeadPose.ThePose); return toGlm(trackingState.HeadPose.ThePose);
#endif
} }
bool OculusBaseDisplayPlugin::isSupported() const { bool OculusBaseDisplayPlugin::isSupported() const {
#if (OVR_MAJOR_VERSION >= 6)
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
return false; return false;
} }
bool result = false;
if (ovrHmd_Detect() > 0) { ovrSession session { nullptr };
result = true; ovrGraphicsLuid luid;
} auto result = ovr_Create(&session, &luid);
if (!OVR_SUCCESS(result)) {
ovrErrorInfo error;
ovr_GetLastErrorInfo(&error);
ovr_Shutdown(); ovr_Shutdown();
return result;
#else
return false; return false;
#endif }
auto hmdDesc = ovr_GetHmdDesc(session);
if (hmdDesc.Type == ovrHmd_None) {
ovr_Destroy(session);
ovr_Shutdown();
return false;
}
ovr_Shutdown();
return true;
} }
// DLL based display plugins MUST initialize GLEW inside the DLL code. // DLL based display plugins MUST initialize GLEW inside the DLL code.
@ -69,28 +79,22 @@ void OculusBaseDisplayPlugin::deinit() {
void OculusBaseDisplayPlugin::activate() { void OculusBaseDisplayPlugin::activate() {
WindowOpenGLDisplayPlugin::activate(); WindowOpenGLDisplayPlugin::activate();
#if (OVR_MAJOR_VERSION >= 6)
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
qFatal("Could not init OVR"); qFatal("Could not init OVR");
} }
#if (OVR_MAJOR_VERSION == 6) if (!OVR_SUCCESS(ovr_Create(&_session, &_luid))) {
if (!OVR_SUCCESS(ovr_Create(0, &_hmd))) {
#elif (OVR_MAJOR_VERSION == 7)
if (!OVR_SUCCESS(ovr_Create(&_hmd, &_luid))) {
#endif
Q_ASSERT(false);
qFatal("Failed to acquire HMD"); 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]; glm::uvec2 eyeSizes[2];
ovr_for_each_eye([&](ovrEyeType eye) { ovr_for_each_eye([&](ovrEyeType eye) {
_eyeFovs[eye] = _hmdDesc.DefaultEyeFov[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 ovrPerspectiveProjection =
ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded); ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
_eyeProjections[eye] = toGlm(ovrPerspectiveProjection); _eyeProjections[eye] = toGlm(ovrPerspectiveProjection);
@ -100,7 +104,7 @@ void OculusBaseDisplayPlugin::activate() {
_compositeEyeProjections[eye] = toGlm(ovrPerspectiveProjection); _compositeEyeProjections[eye] = toGlm(ovrPerspectiveProjection);
_eyeOffsets[eye] = erd.HmdToEyeViewOffset; _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]; ovrFovPort combined = _eyeFovs[Left];
combined.LeftTan = std::max(_eyeFovs[Left].LeftTan, _eyeFovs[Right].LeftTan); combined.LeftTan = std::max(_eyeFovs[Left].LeftTan, _eyeFovs[Right].LeftTan);
@ -115,34 +119,33 @@ void OculusBaseDisplayPlugin::activate() {
eyeSizes[0].x + eyeSizes[1].x, eyeSizes[0].x + eyeSizes[1].x,
std::max(eyeSizes[0].y, eyeSizes[1].y)); 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))) { ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) {
qFatal("Could not attach to sensor device"); 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)); memset(&_sceneLayer, 0, sizeof(ovrLayerEyeFov));
_sceneLayer.Header.Type = ovrLayerType_EyeFov; _sceneLayer.Header.Type = ovrLayerType_EyeFov;
_sceneLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; _sceneLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft;
ovr_for_each_eye([&](ovrEyeType eye) { ovr_for_each_eye([&](ovrEyeType eye) {
ovrFovPort & fov = _sceneLayer.Fov[eye] = _eyeRenderDescs[eye].Fov; 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 }; _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))) { ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) {
qFatal("Could not attach to sensor device"); qFatal("Could not attach to sensor device");
} }
#endif
} }
void OculusBaseDisplayPlugin::deactivate() { void OculusBaseDisplayPlugin::deactivate() {
WindowOpenGLDisplayPlugin::deactivate(); WindowOpenGLDisplayPlugin::deactivate();
#if (OVR_MAJOR_VERSION >= 6) #if (OVR_MAJOR_VERSION >= 6)
ovr_Destroy(_hmd); ovr_Destroy(_session);
_hmd = nullptr; _session = nullptr;
ovr_Shutdown(); ovr_Shutdown();
#endif #endif
} }
@ -151,7 +154,7 @@ void OculusBaseDisplayPlugin::deactivate() {
float OculusBaseDisplayPlugin::getIPD() const { float OculusBaseDisplayPlugin::getIPD() const {
float result = OVR_DEFAULT_IPD; float result = OVR_DEFAULT_IPD;
#if (OVR_MAJOR_VERSION >= 6) #if (OVR_MAJOR_VERSION >= 6)
result = ovr_GetFloat(_hmd, OVR_KEY_IPD, result); result = ovr_GetFloat(_session, OVR_KEY_IPD, result);
#endif #endif
return result; return result;
} }

View file

@ -43,17 +43,13 @@ protected:
mat4 _compositeEyeProjections[2]; mat4 _compositeEyeProjections[2];
uvec2 _desiredFramebufferSize; uvec2 _desiredFramebufferSize;
#if (OVR_MAJOR_VERSION >= 6) ovrSession _session;
ovrHmd _hmd; ovrGraphicsLuid _luid;
float _ipd{ OVR_DEFAULT_IPD }; float _ipd{ OVR_DEFAULT_IPD };
ovrEyeRenderDesc _eyeRenderDescs[2]; ovrEyeRenderDesc _eyeRenderDescs[2];
ovrFovPort _eyeFovs[2]; ovrFovPort _eyeFovs[2];
ovrHmdDesc _hmdDesc; ovrHmdDesc _hmdDesc;
ovrLayerEyeFov _sceneLayer; ovrLayerEyeFov _sceneLayer;
#endif
#if (OVR_MAJOR_VERSION == 7)
ovrGraphicsLuid _luid;
#endif
}; };
#if (OVR_MAJOR_VERSION == 6) #if (OVR_MAJOR_VERSION == 6)

View file

@ -23,12 +23,16 @@
// ovr_CreateMirrorTextureGL, etc // ovr_CreateMirrorTextureGL, etc
template <typename C> template <typename C>
struct RiftFramebufferWrapper : public FramebufferWrapper<C, char> { struct RiftFramebufferWrapper : public FramebufferWrapper<C, char> {
ovrHmd hmd; ovrSession session;
RiftFramebufferWrapper(const ovrHmd & hmd) : hmd(hmd) { RiftFramebufferWrapper(const ovrSession& session) : session(session) {
color = 0; color = 0;
depth = 0; depth = 0;
}; };
~RiftFramebufferWrapper() {
destroyColor();
}
void Resize(const uvec2 & size) { void Resize(const uvec2 & size) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oglplus::GetName(fbo)); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oglplus::GetName(fbo));
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
@ -39,6 +43,9 @@ struct RiftFramebufferWrapper : public FramebufferWrapper<C, char> {
} }
protected: protected:
virtual void destroyColor() {
}
virtual void initDepth() override final { virtual void initDepth() override final {
} }
}; };
@ -53,12 +60,6 @@ struct SwapFramebufferWrapper : public RiftFramebufferWrapper<ovrSwapTextureSet*
: RiftFramebufferWrapper(hmd) { : RiftFramebufferWrapper(hmd) {
} }
~SwapFramebufferWrapper() {
if (color) {
ovr_DestroySwapTextureSet(hmd, color);
color = nullptr;
}
}
void Increment() { void Increment() {
++color->CurrentIndex; ++color->CurrentIndex;
@ -66,13 +67,17 @@ struct SwapFramebufferWrapper : public RiftFramebufferWrapper<ovrSwapTextureSet*
} }
protected: protected:
virtual void initColor() override { virtual void destroyColor() override {
if (color) { if (color) {
ovr_DestroySwapTextureSet(hmd, color); ovr_DestroySwapTextureSet(session, color);
color = nullptr; color = nullptr;
} }
}
if (!OVR_SUCCESS(ovr_CreateSwapTextureSetGL(hmd, GL_RGBA, size.x, size.y, &color))) { virtual void initColor() override {
destroyColor();
if (!OVR_SUCCESS(ovr_CreateSwapTextureSetGL(session, GL_SRGB8_ALPHA8, size.x, size.y, &color))) {
qFatal("Unable to create swap textures"); qFatal("Unable to create swap textures");
} }
@ -107,20 +112,17 @@ struct MirrorFramebufferWrapper : public RiftFramebufferWrapper<ovrGLTexture*> {
MirrorFramebufferWrapper(const ovrHmd & hmd) MirrorFramebufferWrapper(const ovrHmd & hmd)
: RiftFramebufferWrapper(hmd) { } : RiftFramebufferWrapper(hmd) { }
virtual ~MirrorFramebufferWrapper() { private:
virtual void destroyColor() override {
if (color) { if (color) {
ovr_DestroyMirrorTexture(hmd, (ovrTexture*)color); ovr_DestroyMirrorTexture(session, (ovrTexture*)color);
color = nullptr; color = nullptr;
} }
} }
private:
void initColor() override { void initColor() override {
if (color) { destroyColor();
ovr_DestroyMirrorTexture(hmd, (ovrTexture*)color); ovrResult result = ovr_CreateMirrorTextureGL(session, GL_SRGB8_ALPHA8, size.x, size.y, (ovrTexture**)&color);
color = nullptr;
}
ovrResult result = ovr_CreateMirrorTextureGL(hmd, GL_RGBA, size.x, size.y, (ovrTexture**)&color);
Q_ASSERT(OVR_SUCCESS(result)); Q_ASSERT(OVR_SUCCESS(result));
} }
@ -154,8 +156,7 @@ void OculusDisplayPlugin::activate() {
void OculusDisplayPlugin::customizeContext() { void OculusDisplayPlugin::customizeContext() {
OculusBaseDisplayPlugin::customizeContext(); OculusBaseDisplayPlugin::customizeContext();
#if (OVR_MAJOR_VERSION >= 6) _sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_session));
_sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_hmd));
_sceneFbo->Init(getRecommendedRenderSize()); _sceneFbo->Init(getRecommendedRenderSize());
// We're rendering both eyes to the same texture, so only one of the // 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; _sceneLayer.ColorTexture[0] = _sceneFbo->color;
// not needed since the structure was zeroed on init, but explicit // not needed since the structure was zeroed on init, but explicit
_sceneLayer.ColorTexture[1] = nullptr; _sceneLayer.ColorTexture[1] = nullptr;
#endif
enableVsync(false); enableVsync(false);
// Only enable mirroring if we know vsync is disabled // Only enable mirroring if we know vsync is disabled
_enablePreview = !isVsyncEnabled(); _enablePreview = !isVsyncEnabled();
@ -177,7 +178,6 @@ void OculusDisplayPlugin::uncustomizeContext() {
} }
void OculusDisplayPlugin::internalPresent() { void OculusDisplayPlugin::internalPresent() {
#if (OVR_MAJOR_VERSION >= 6)
if (!_currentSceneTexture) { if (!_currentSceneTexture) {
return; return;
} }
@ -206,8 +206,10 @@ void OculusDisplayPlugin::internalPresent() {
auto size = _sceneFbo->size; auto size = _sceneFbo->size;
Context::Viewport(size.x, size.y); Context::Viewport(size.x, size.y);
glBindTexture(GL_TEXTURE_2D, _currentSceneTexture); glBindTexture(GL_TEXTURE_2D, _currentSceneTexture);
//glEnable(GL_FRAMEBUFFER_SRGB);
GLenum err = glGetError(); GLenum err = glGetError();
drawUnitQuad(); drawUnitQuad();
//glDisable(GL_FRAMEBUFFER_SRGB);
}); });
uint32_t frameIndex { 0 }; uint32_t frameIndex { 0 };
@ -230,13 +232,12 @@ void OculusDisplayPlugin::internalPresent() {
viewScaleDesc.HmdToEyeViewOffset[1] = _eyeOffsets[1]; viewScaleDesc.HmdToEyeViewOffset[1] = _eyeOffsets[1];
ovrLayerHeader* layers = &_sceneLayer.Header; 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)) { if (!OVR_SUCCESS(result)) {
qDebug() << result; qDebug() << result;
} }
} }
_sceneFbo->Increment(); _sceneFbo->Increment();
#endif
/* /*
The swapbuffer call here is only required if we want to mirror the content to the screen. The swapbuffer call here is only required if we want to mirror the content to the screen.

View file

@ -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()

View file

@ -7,24 +7,23 @@
// //
#include "OpenVrDisplayPlugin.h" #include "OpenVrDisplayPlugin.h"
#if defined(Q_OS_WIN)
#include <memory> #include <memory>
#include <QMainWindow> #include <QMainWindow>
#include <QLoggingCategory>
#include <QGLWidget> #include <QGLWidget>
#include <GLMHelpers.h>
#include <QEvent> #include <QEvent>
#include <QResizeEvent> #include <QResizeEvent>
#include <GLMHelpers.h>
#include <gl/GlWindow.h>
#include <PerfStat.h> #include <PerfStat.h>
#include <plugins/PluginContainer.h> #include <plugins/PluginContainer.h>
#include <ViewFrustum.h> #include <ViewFrustum.h>
#include "OpenVrHelpers.h" #include "OpenVrHelpers.h"
#include "GLMHelpers.h"
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(displayplugins) Q_DECLARE_LOGGING_CATEGORY(displayplugins)
Q_LOGGING_CATEGORY(displayplugins, "hifi.displayplugins") Q_LOGGING_CATEGORY(displayplugins, "hifi.displayplugins")
@ -41,12 +40,11 @@ vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount]; mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
static mat4 _sensorResetMat; static mat4 _sensorResetMat;
static uvec2 _windowSize; static uvec2 _windowSize;
static ivec2 _windowPosition;
static uvec2 _renderTargetSize; static uvec2 _renderTargetSize;
struct PerEyeData { struct PerEyeData {
uvec2 _viewportOrigin; //uvec2 _viewportOrigin;
uvec2 _viewportSize; //uvec2 _viewportSize;
mat4 _projectionMatrix; mat4 _projectionMatrix;
mat4 _eyeOffset; mat4 _eyeOffset;
mat4 _pose; mat4 _pose;
@ -89,36 +87,17 @@ void OpenVrDisplayPlugin::activate() {
} }
Q_ASSERT(_hmd); Q_ASSERT(_hmd);
_hmd->GetWindowBounds(&_windowPosition.x, &_windowPosition.y, &_windowSize.x, &_windowSize.y);
_hmd->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y); _hmd->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y);
// Recommended render target size is per-eye, so double the X size for // Recommended render target size is per-eye, so double the X size for
// left + right eyes // left + right eyes
_renderTargetSize.x *= 2; _renderTargetSize.x *= 2;
openvr_for_each_eye([&](vr::Hmd_Eye eye) { openvr_for_each_eye([&](vr::Hmd_Eye eye) {
PerEyeData& eyeData = _eyesData[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._projectionMatrix = toGlm(_hmd->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, vr::API_OpenGL));
eyeData._eyeOffset = toGlm(_hmd->GetEyeToHeadTransform(eye)); eyeData._eyeOffset = toGlm(_hmd->GetEyeToHeadTransform(eye));
}); });
_compositor = vr::VRCompositor();
vr::HmdError eError = vr::HmdError_None;
_compositor = (vr::IVRCompositor*)vr::VR_GetGenericInterface(vr::IVRCompositor_Version, &eError);
Q_ASSERT(eError == vr::HmdError_None);
Q_ASSERT(_compositor); 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(); WindowOpenGLDisplayPlugin::activate();
} }
@ -132,6 +111,16 @@ void OpenVrDisplayPlugin::deactivate() {
WindowOpenGLDisplayPlugin::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 { uvec2 OpenVrDisplayPlugin::getRecommendedRenderSize() const {
return _renderTargetSize; return _renderTargetSize;
} }
@ -153,33 +142,41 @@ glm::mat4 OpenVrDisplayPlugin::getEyeToHeadTransform(Eye eye) const {
} }
glm::mat4 OpenVrDisplayPlugin::getHeadPose(uint32_t frameIndex) 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) { void OpenVrDisplayPlugin::internalPresent() {
// // Flip y-axis since GL UV coords are backwards. // Flip y-axis since GL UV coords are backwards.
// static vr::Compositor_TextureBounds leftBounds{ 0, 1, 0.5f, 0 }; static vr::VRTextureBounds_t leftBounds{ 0, 0, 0.5f, 1 };
// static vr::Compositor_TextureBounds rightBounds{ 0.5f, 1, 1, 0 }; static vr::VRTextureBounds_t rightBounds{ 0.5f, 0, 1, 1 };
// _compositor->Submit(vr::Eye_Left, (void*)finalTexture, &leftBounds); vr::Texture_t texture{ (void*)_currentSceneTexture, vr::API_OpenGL, vr::ColorSpace_Auto };
// _compositor->Submit(vr::Eye_Right, (void*)finalTexture, &rightBounds); {
// glFinish(); Lock lock(_mutex);
//} _compositor->Submit(vr::Eye_Left, &texture, &leftBounds);
_compositor->Submit(vr::Eye_Right, &texture, &rightBounds);
//void OpenVrDisplayPlugin::finishFrame() { }
//// swapBuffers(); glFinish();
// doneCurrent(); {
// _compositor->WaitGetPoses(_trackedDevicePose, vr::k_unMaxTrackedDeviceCount); Lock lock(_mutex);
// for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) { _compositor->WaitGetPoses(_trackedDevicePose, vr::k_unMaxTrackedDeviceCount, nullptr, 0);
// _trackedDevicePoseMat4[i] = _sensorResetMat * toGlm(_trackedDevicePose[i].mDeviceToAbsoluteTracking); 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]; openvr_for_each_eye([&](vr::Hmd_Eye eye) {
// }); _eyesData[eye]._pose = _trackedDevicePoseMat4[0];
//}; });
}
#endif
//WindowOpenGLDisplayPlugin::internalPresent();
}

View file

@ -9,10 +9,9 @@
#include <QtGlobal> #include <QtGlobal>
#if defined(Q_OS_WIN)
#include <openvr.h> #include <openvr.h>
#include "../WindowOpenGLDisplayPlugin.h" #include <display-plugins/WindowOpenGLDisplayPlugin.h>
const float TARGET_RATE_OpenVr = 90.0f; // FIXME: get from sdk tracked device property? This number is vive-only. 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 activate() override;
virtual void deactivate() override; virtual void deactivate() override;
virtual void customizeContext() override;
virtual glm::uvec2 getRecommendedRenderSize() const override; virtual glm::uvec2 getRecommendedRenderSize() const override;
virtual glm::uvec2 getRecommendedUiSize() const override { return uvec2(1920, 1080); } 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 getEyeToHeadTransform(Eye eye) const override;
virtual glm::mat4 getHeadPose(uint32_t frameIndex) 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: protected:
// virtual void display(uint32_t frameIndex, uint32_t finalTexture, const glm::uvec2& sceneSize) override; virtual void internalPresent() override;
virtual void customizeContext() override;
private: private:
vr::IVRSystem* _hmd { nullptr }; vr::IVRSystem* _hmd { nullptr };
static const QString NAME; static const QString NAME;
}; };
#endif

View file

@ -7,14 +7,15 @@
// //
#include "OpenVrHelpers.h" #include "OpenVrHelpers.h"
#if defined(Q_OS_WIN)
#include <QtCore/QTimer>
#include <atomic> #include <atomic>
#include <mutex> #include <mutex>
#include "../Logging.h" #include <QtCore/QDebug>
#include <QtCore/QTimer>
#include <QtCore/QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(displayplugins)
using Mutex = std::mutex; using Mutex = std::mutex;
using Lock = std::unique_lock<Mutex>; using Lock = std::unique_lock<Mutex>;
@ -30,13 +31,13 @@ vr::IVRSystem* acquireOpenVrSystem() {
if (hmdPresent) { if (hmdPresent) {
Lock lock(mutex); Lock lock(mutex);
if (!activeHmd) { if (!activeHmd) {
qCDebug(displayPlugins) << "openvr: No vr::IVRSystem instance active, building"; qCDebug(displayplugins) << "openvr: No vr::IVRSystem instance active, building";
vr::HmdError eError = vr::HmdError_None; vr::EVRInitError eError = vr::VRInitError_None;
activeHmd = vr::VR_Init(&eError); 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) { if (activeHmd) {
qCDebug(displayPlugins) << "openvr: incrementing refcount"; qCDebug(displayplugins) << "openvr: incrementing refcount";
++refCount; ++refCount;
} }
} }
@ -46,10 +47,10 @@ vr::IVRSystem* acquireOpenVrSystem() {
void releaseOpenVrSystem() { void releaseOpenVrSystem() {
if (activeHmd) { if (activeHmd) {
Lock lock(mutex); Lock lock(mutex);
qDebug() << "openvr: decrementing refcount"; qCDebug(displayplugins) << "openvr: decrementing refcount";
--refCount; --refCount;
if (0 == 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 // 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 // putting in a delay before we destory the shutdown the VR subsystem
@ -71,5 +72,3 @@ void releaseOpenVrSystem() {
} }
} }
} }
#endif

View file

@ -7,9 +7,6 @@
// //
#pragma once #pragma once
#include <QtGlobal>
#if defined(Q_OS_WIN)
#include <openvr.h> #include <openvr.h>
#include <GLMHelpers.h> #include <GLMHelpers.h>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
@ -18,5 +15,3 @@
vr::IVRSystem* acquireOpenVrSystem(); vr::IVRSystem* acquireOpenVrSystem();
void releaseOpenVrSystem(); void releaseOpenVrSystem();
#endif

View file

@ -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 <mutex>
#include <QtCore/QObject>
#include <QtCore/QtPlugin>
#include <QtCore/QStringList>
#include <plugins/RuntimePlugin.h>
#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"

View file

@ -17,7 +17,6 @@
#include <gpu/Batch.h> #include <gpu/Batch.h>
#include <gpu/Context.h> #include <gpu/Context.h>
#include <DeferredLightingEffect.h> #include <DeferredLightingEffect.h>
#include <display-plugins/openvr/OpenVrHelpers.h>
#include <NumericalConstants.h> #include <NumericalConstants.h>
#include <plugins/PluginContainer.h> #include <plugins/PluginContainer.h>
#include <UserActivityLogger.h> #include <UserActivityLogger.h>
@ -26,10 +25,10 @@
#include <controllers/StandardControls.h> #include <controllers/StandardControls.h>
#ifdef Q_OS_WIN #include "OpenVrHelpers.h"
extern vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount]; extern vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
extern mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount]; extern mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
#endif
vr::IVRSystem* acquireOpenVrSystem(); vr::IVRSystem* acquireOpenVrSystem();
void releaseOpenVrSystem(); 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, static const glm::vec3 CONTROLLER_OFFSET = glm::vec3(CONTROLLER_LENGTH_OFFSET / 2.0f,
CONTROLLER_LENGTH_OFFSET / 2.0f, 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_PARENT = "Avatar";
static const QString MENU_NAME = "Vive Controllers"; static const QString MENU_NAME = "Vive Controllers";
@ -49,19 +48,14 @@ static const QString RENDER_CONTROLLERS = "Render Hand Controllers";
const QString ViveControllerManager::NAME = "OpenVR"; const QString ViveControllerManager::NAME = "OpenVR";
bool ViveControllerManager::isSupported() const { bool ViveControllerManager::isSupported() const {
#ifdef Q_OS_WIN
auto hmd = acquireOpenVrSystem(); auto hmd = acquireOpenVrSystem();
bool success = hmd != nullptr; bool success = hmd != nullptr;
releaseOpenVrSystem(); releaseOpenVrSystem();
return success; return success;
#else
return false;
#endif
} }
void ViveControllerManager::activate() { void ViveControllerManager::activate() {
InputPlugin::activate(); InputPlugin::activate();
#ifdef Q_OS_WIN
_container->addMenu(MENU_PATH); _container->addMenu(MENU_PATH);
_container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, RENDER_CONTROLLERS, _container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, RENDER_CONTROLLERS,
[this] (bool clicked) { this->setRenderControllers(clicked); }, [this] (bool clicked) { this->setRenderControllers(clicked); },
@ -72,8 +66,11 @@ void ViveControllerManager::activate() {
} }
Q_ASSERT(_hmd); Q_ASSERT(_hmd);
auto renderModels = vr::VRRenderModels();
vr::RenderModel_t model; 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); qDebug() << QString("Unable to load render model %1\n").arg(CONTROLLER_MODEL_STRING);
} else { } else {
model::Mesh* mesh = new model::Mesh(); model::Mesh* mesh = new model::Mesh();
@ -118,7 +115,7 @@ void ViveControllerManager::activate() {
_modelLoaded = true; _modelLoaded = true;
_renderControllers = true; _renderControllers = true;
} }
#endif */
// unregister with UserInputMapper // unregister with UserInputMapper
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>(); auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
@ -129,7 +126,6 @@ void ViveControllerManager::activate() {
void ViveControllerManager::deactivate() { void ViveControllerManager::deactivate() {
InputPlugin::deactivate(); InputPlugin::deactivate();
#ifdef Q_OS_WIN
_container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS); _container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS);
_container->removeMenu(MENU_PATH); _container->removeMenu(MENU_PATH);
@ -139,7 +135,6 @@ void ViveControllerManager::deactivate() {
} }
_inputDevice->_poseStateMap.clear(); _inputDevice->_poseStateMap.clear();
#endif
// unregister with UserInputMapper // unregister with UserInputMapper
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>(); auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
@ -225,7 +220,6 @@ void ViveControllerManager::pluginUpdate(float deltaTime, bool jointsCaptured) {
} }
void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCaptured) { void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
#ifdef Q_OS_WIN
_poseStateMap.clear(); _poseStateMap.clear();
_buttonPressedMap.clear(); _buttonPressedMap.clear();
@ -276,7 +270,6 @@ void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCapt
} }
_trackedControllers = numTrackedControllers; _trackedControllers = numTrackedControllers;
#endif
} }
void ViveControllerManager::InputDevice::focusOutEvent() { 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 // 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) { 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 //FIX ME? It enters here every frame: probably we want to enter only if an event occurs
axis += vr::k_EButton_Axis0; axis += vr::k_EButton_Axis0;
using namespace controller; using namespace controller;
@ -296,12 +288,10 @@ void ViveControllerManager::InputDevice::handleAxisEvent(uint32_t axis, float x,
} else if (axis == vr::k_EButton_SteamVR_Trigger) { } else if (axis == vr::k_EButton_SteamVR_Trigger) {
_axisStateMap[left ? LT : RT] = x; _axisStateMap[left ? LT : RT] = x;
} }
#endif
} }
// These functions do translation from the Steam IDs to the standard controller IDs // These functions do translation from the Steam IDs to the standard controller IDs
void ViveControllerManager::InputDevice::handleButtonEvent(uint32_t button, bool pressed, bool left) { void ViveControllerManager::InputDevice::handleButtonEvent(uint32_t button, bool pressed, bool left) {
#ifdef Q_OS_WIN
if (!pressed) { if (!pressed) {
return; return;
} }
@ -319,7 +309,6 @@ void ViveControllerManager::InputDevice::handleButtonEvent(uint32_t button, bool
//FIX ME: not able to ovrewrite the behaviour of this button //FIX ME: not able to ovrewrite the behaviour of this button
_buttonPressedMap.insert(left ? controller::LEFT_SECONDARY_THUMB : controller::RIGHT_SECONDARY_THUMB); _buttonPressedMap.insert(left ? controller::LEFT_SECONDARY_THUMB : controller::RIGHT_SECONDARY_THUMB);
} }
#endif
} }
void ViveControllerManager::InputDevice::handlePoseEvent(const mat4& mat, bool left) { void ViveControllerManager::InputDevice::handlePoseEvent(const mat4& mat, bool left) {

View file

@ -20,7 +20,7 @@
#include <model/Geometry.h> #include <model/Geometry.h>
#include <gpu/Texture.h> #include <gpu/Texture.h>
#include <controllers/InputDevice.h> #include <controllers/InputDevice.h>
#include "InputPlugin.h" #include <plugins/InputPlugin.h>
#include <RenderArgs.h> #include <RenderArgs.h>
#include <render/Scene.h> #include <render/Scene.h>

View file

@ -0,0 +1 @@
{}