Merge remote-tracking branch 'upstream/master' into HEAD

This commit is contained in:
Brad Davis 2015-10-14 10:54:32 -07:00
commit f051a84dc6
11 changed files with 1266 additions and 1114 deletions

View file

@ -16,8 +16,9 @@ var scriptURL = Script.resolvePath('wallTarget.js');
var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx'; var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx';
var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target_collision_hull.obj'; var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target_collision_hull.obj';
var MINIMUM_MOVE_LENGTH = 0.05;
var RESET_DISTANCE = 0.5;
var RESET_DISTANCE = 1;
var TARGET_USER_DATA_KEY = 'hifi-ping_pong_target'; var TARGET_USER_DATA_KEY = 'hifi-ping_pong_target';
var NUMBER_OF_TARGETS = 6; var NUMBER_OF_TARGETS = 6;
var TARGETS_PER_ROW = 3; var TARGETS_PER_ROW = 3;
@ -60,6 +61,8 @@ var targets = [];
var originalPositions = []; var originalPositions = [];
var lastPositions = [];
function addTargets() { function addTargets() {
var i; var i;
var row = -1; var row = -1;
@ -77,6 +80,7 @@ function addTargets() {
position.y = startPosition.y - (row * VERTICAL_SPACING); position.y = startPosition.y - (row * VERTICAL_SPACING);
originalPositions.push(position); originalPositions.push(position);
lastPositions.push(position);
var targetProperties = { var targetProperties = {
name: 'Target', name: 'Target',
@ -103,7 +107,11 @@ function testTargetDistanceFromStart() {
var distance = Vec3.subtract(originalPosition, currentPosition); var distance = Vec3.subtract(originalPosition, currentPosition);
var length = Vec3.length(distance); var length = Vec3.length(distance);
if (length > RESET_DISTANCE) { var moving = Vec3.length(Vec3.subtract(currentPosition, lastPositions[index]));
lastPositions[index] = currentPosition;
if (length > RESET_DISTANCE && moving < MINIMUM_MOVE_LENGTH) {
Entities.deleteEntity(target); Entities.deleteEntity(target);
@ -117,10 +125,16 @@ function testTargetDistanceFromStart() {
compoundShapeURL: COLLISION_HULL_URL, compoundShapeURL: COLLISION_HULL_URL,
position: originalPositions[index], position: originalPositions[index],
rotation: rotation, rotation: rotation,
script: scriptURL script: scriptURL,
userData: JSON.stringify({
grabbableKey: {
grabbable: false
}
})
}; };
targets[index] = Entities.addEntity(targetProperties); targets[index] = Entities.addEntity(targetProperties);
} }
}); });
} }
@ -142,7 +156,7 @@ function deleteTargets() {
} }
Entities.deletingEntity.connect(deleteEntity); Entities.deletingEntity.connect(deleteEntity);
var distanceCheckInterval = Script.setInterval(testTargetDistanceFromStart, 1000); var distanceCheckInterval = Script.setInterval(testTargetDistanceFromStart, 500);
addTargets(); addTargets();

View file

@ -1559,7 +1559,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
cursor->setIcon(Cursor::Icon::DEFAULT); cursor->setIcon(Cursor::Icon::DEFAULT);
} }
} else { } else {
resetSensors(); resetSensors(true);
} }
break; break;
} }
@ -3581,7 +3581,7 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi
renderArgs->_viewport = originalViewport; renderArgs->_viewport = originalViewport;
} }
void Application::resetSensors() { void Application::resetSensors(bool andReload) {
DependencyManager::get<Faceshift>()->reset(); DependencyManager::get<Faceshift>()->reset();
DependencyManager::get<DdeFaceTracker>()->reset(); DependencyManager::get<DdeFaceTracker>()->reset();
DependencyManager::get<EyeTracker>()->reset(); DependencyManager::get<EyeTracker>()->reset();
@ -3593,7 +3593,7 @@ void Application::resetSensors() {
QPoint windowCenter = mainWindow->geometry().center(); QPoint windowCenter = mainWindow->geometry().center();
_glWidget->cursor().setPos(currentScreen, windowCenter); _glWidget->cursor().setPos(currentScreen, windowCenter);
getMyAvatar()->reset(); getMyAvatar()->reset(andReload);
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "reset", Qt::QueuedConnection); QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "reset", Qt::QueuedConnection);
} }

View file

@ -274,7 +274,7 @@ public slots:
void setRawAvatarUpdateThreading(); void setRawAvatarUpdateThreading();
void setRawAvatarUpdateThreading(bool isThreaded); void setRawAvatarUpdateThreading(bool isThreaded);
void resetSensors(); void resetSensors(bool andReload = false);
void setActiveFaceTracker(); void setActiveFaceTracker();
#ifdef HAVE_IVIEWHMD #ifdef HAVE_IVIEWHMD

View file

@ -461,6 +461,7 @@ Menu::Menu() {
0, false, 0, false,
&ConnexionClient::getInstance(), &ConnexionClient::getInstance(),
SLOT(toggleConnexion(bool))); SLOT(toggleConnexion(bool)));
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ComfortMode, 0, true);
MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands"); MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands");
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);

View file

@ -159,6 +159,7 @@ namespace MenuOption {
const QString CenterPlayerInView = "Center Player In View"; const QString CenterPlayerInView = "Center Player In View";
const QString Chat = "Chat..."; const QString Chat = "Chat...";
const QString Collisions = "Collisions"; const QString Collisions = "Collisions";
const QString ComfortMode = "Comfort Mode";
const QString Connexion = "Activate 3D Connexion Devices"; const QString Connexion = "Activate 3D Connexion Devices";
const QString Console = "Console..."; const QString Console = "Console...";
const QString ControlWithSpeech = "Control With Speech"; const QString ControlWithSpeech = "Control With Speech";

View file

@ -144,7 +144,7 @@ void PluginContainerProxy::unsetFullscreen(const QScreen* avoid) {
void PluginContainerProxy::requestReset() { void PluginContainerProxy::requestReset() {
// We could signal qApp to sequence this, but it turns out that requestReset is only used from within the main thread anyway. // We could signal qApp to sequence this, but it turns out that requestReset is only used from within the main thread anyway.
qApp->resetSensors(); qApp->resetSensors(true);
} }
void PluginContainerProxy::showDisplayPluginsTools() { void PluginContainerProxy::showDisplayPluginsTools() {

View file

@ -140,16 +140,18 @@ QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) {
return AvatarData::toByteArray(cullSmallChanges, sendAll); return AvatarData::toByteArray(cullSmallChanges, sendAll);
} }
void MyAvatar::reset() { void MyAvatar::reset(bool andReload) {
// Gather animation mode... // Gather animation mode...
// This should be simpler when we have only graph animations always on. // This should be simpler when we have only graph animations always on.
bool isRig = _rig->getEnableRig(); bool isRig = _rig->getEnableRig();
// seting rig animation to true, below, will clear the graph animation menu item, so grab it now. // seting rig animation to true, below, will clear the graph animation menu item, so grab it now.
bool isGraph = _rig->getEnableAnimGraph() || Menu::getInstance()->isOptionChecked(MenuOption::EnableAnimGraph); bool isGraph = _rig->getEnableAnimGraph() || Menu::getInstance()->isOptionChecked(MenuOption::EnableAnimGraph);
// ... and get to sane configuration where other activity won't bother us. // ... and get to sane configuration where other activity won't bother us.
qApp->setRawAvatarUpdateThreading(false); if (andReload) {
_rig->disableHands = true; qApp->setRawAvatarUpdateThreading(false);
setEnableRigAnimations(true); _rig->disableHands = true;
setEnableRigAnimations(true);
}
// Reset dynamic state. // Reset dynamic state.
_wasPushing = _isPushing = _isBraking = _billboardValid = _straighteningLean = false; _wasPushing = _isPushing = _isBraking = _billboardValid = _straighteningLean = false;
@ -158,32 +160,34 @@ void MyAvatar::reset() {
_targetVelocity = glm::vec3(0.0f); _targetVelocity = glm::vec3(0.0f);
setThrust(glm::vec3(0.0f)); setThrust(glm::vec3(0.0f));
// Get fresh data, in case we're really slow and out of wack. if (andReload) {
_hmdSensorMatrix = qApp->getHMDSensorPose(); // Get fresh data, in case we're really slow and out of wack.
_hmdSensorPosition = extractTranslation(_hmdSensorMatrix); _hmdSensorMatrix = qApp->getHMDSensorPose();
_hmdSensorOrientation = glm::quat_cast(_hmdSensorMatrix); _hmdSensorPosition = extractTranslation(_hmdSensorMatrix);
_hmdSensorOrientation = glm::quat_cast(_hmdSensorMatrix);
// Reset body position/orientation under the head. // Reset body position/orientation under the head.
auto newBodySensorMatrix = deriveBodyFromHMDSensor(); // Based on current cached HMD position/rotation.. auto newBodySensorMatrix = deriveBodyFromHMDSensor(); // Based on current cached HMD position/rotation..
auto worldBodyMatrix = _sensorToWorldMatrix * newBodySensorMatrix; auto worldBodyMatrix = _sensorToWorldMatrix * newBodySensorMatrix;
glm::vec3 worldBodyPos = extractTranslation(worldBodyMatrix); glm::vec3 worldBodyPos = extractTranslation(worldBodyMatrix);
glm::quat worldBodyRot = glm::normalize(glm::quat_cast(worldBodyMatrix)); glm::quat worldBodyRot = glm::normalize(glm::quat_cast(worldBodyMatrix));
// FIXME: Hack to retain the previous behavior wrt height. // FIXME: Hack to retain the previous behavior wrt height.
// I'd like to make the body match head height, but that will have to wait for separate PR. // I'd like to make the body match head height, but that will have to wait for separate PR.
worldBodyPos.y = getPosition().y; worldBodyPos.y = getPosition().y;
setPosition(worldBodyPos); setPosition(worldBodyPos);
setOrientation(worldBodyRot); setOrientation(worldBodyRot);
// If there is any discrepency between positioning and the head (as there is in initial deriveBodyFromHMDSensor), // If there is any discrepency between positioning and the head (as there is in initial deriveBodyFromHMDSensor),
// we can make that right by setting _bodySensorMatrix = newBodySensorMatrix. // we can make that right by setting _bodySensorMatrix = newBodySensorMatrix.
// However, doing so will make the head want to point to the previous body orientation, as cached above. // However, doing so will make the head want to point to the previous body orientation, as cached above.
//_bodySensorMatrix = newBodySensorMatrix; //_bodySensorMatrix = newBodySensorMatrix;
//updateSensorToWorldMatrix(); // Uses updated position/orientation and _bodySensorMatrix changes //updateSensorToWorldMatrix(); // Uses updated position/orientation and _bodySensorMatrix changes
_skeletonModel.simulate(0.1f); // non-zero _skeletonModel.simulate(0.1f); // non-zero
setEnableRigAnimations(false); setEnableRigAnimations(false);
_skeletonModel.simulate(0.1f); _skeletonModel.simulate(0.1f);
}
if (isRig) { if (isRig) {
setEnableRigAnimations(true); setEnableRigAnimations(true);
Menu::getInstance()->setIsOptionChecked(MenuOption::EnableRigAnimations, true); Menu::getInstance()->setIsOptionChecked(MenuOption::EnableRigAnimations, true);
@ -191,8 +195,10 @@ void MyAvatar::reset() {
setEnableAnimGraph(true); setEnableAnimGraph(true);
Menu::getInstance()->setIsOptionChecked(MenuOption::EnableAnimGraph, true); Menu::getInstance()->setIsOptionChecked(MenuOption::EnableAnimGraph, true);
} }
_rig->disableHands = false; if (andReload) {
qApp->setRawAvatarUpdateThreading(); _rig->disableHands = false;
qApp->setRawAvatarUpdateThreading();
}
} }
void MyAvatar::update(float deltaTime) { void MyAvatar::update(float deltaTime) {
@ -1514,33 +1520,69 @@ bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
void MyAvatar::updateOrientation(float deltaTime) { void MyAvatar::updateOrientation(float deltaTime) {
// Smoothly rotate body with arrow keys // Smoothly rotate body with arrow keys
float targetSpeed = (_driveKeys[ROT_LEFT] - _driveKeys[ROT_RIGHT]) * YAW_SPEED; float targetSpeed = 0.0f;
if (targetSpeed != 0.0f) {
const float ROTATION_RAMP_TIMESCALE = 0.1f; // FIXME - this comfort mode code is a total hack, remove it when we have new input mapping
float blend = deltaTime / ROTATION_RAMP_TIMESCALE; bool isComfortMode = Menu::getInstance()->isOptionChecked(MenuOption::ComfortMode);
if (blend > 1.0f) { bool isHMDMode = qApp->getAvatarUpdater()->isHMDMode();
blend = 1.0f;
} if (!isHMDMode || !isComfortMode) {
_bodyYawDelta = (1.0f - blend) * _bodyYawDelta + blend * targetSpeed; targetSpeed = (_driveKeys[ROT_LEFT] - _driveKeys[ROT_RIGHT]) * YAW_SPEED;
} else if (_bodyYawDelta != 0.0f) {
// attenuate body rotation speed if (targetSpeed != 0.0f) {
const float ROTATION_DECAY_TIMESCALE = 0.05f; const float ROTATION_RAMP_TIMESCALE = 0.1f;
float attenuation = 1.0f - deltaTime / ROTATION_DECAY_TIMESCALE; float blend = deltaTime / ROTATION_RAMP_TIMESCALE;
if (attenuation < 0.0f) { if (blend > 1.0f) {
attenuation = 0.0f; blend = 1.0f;
} }
_bodyYawDelta *= attenuation; _bodyYawDelta = (1.0f - blend) * _bodyYawDelta + blend * targetSpeed;
} else if (_bodyYawDelta != 0.0f) {
// attenuate body rotation speed
const float ROTATION_DECAY_TIMESCALE = 0.05f;
float attenuation = 1.0f - deltaTime / ROTATION_DECAY_TIMESCALE;
if (attenuation < 0.0f) {
attenuation = 0.0f;
}
_bodyYawDelta *= attenuation;
float MINIMUM_ROTATION_RATE = 2.0f;
if (fabsf(_bodyYawDelta) < MINIMUM_ROTATION_RATE) {
_bodyYawDelta = 0.0f;
}
}
// update body orientation by movement inputs
setOrientation(getOrientation() *
glm::quat(glm::radians(glm::vec3(0.0f, _bodyYawDelta * deltaTime, 0.0f))));
} else {
// Comfort Mode: If you press any of the left/right rotation drive keys or input, you'll
// get an instantaneous 15 degree turn. If you keep holding the key down you'll get another
// snap turn every half second.
_bodyYawDelta = 0.0f;
static quint64 lastPulse = 0;
quint64 now = usecTimestampNow();
quint64 COMFORT_MODE_PULSE_TIMING = USECS_PER_SECOND / 2; // turn once per half second
float driveLeft = _driveKeys[ROT_LEFT];
float driveRight= _driveKeys[ROT_RIGHT];
if ((driveLeft != 0.0f || driveRight != 0.0f) && (now - lastPulse > COMFORT_MODE_PULSE_TIMING)) {
lastPulse = now;
const float SNAP_TURN_DELTA = 15.0f; // degrees
float direction = (driveLeft - driveRight) < 0.0f ? -1.0f : 1.0f;
float turnAmount = direction * SNAP_TURN_DELTA;
// update body orientation by movement inputs
setOrientation(getOrientation() *
glm::quat(glm::radians(glm::vec3(0.0f, turnAmount, 0.0f))));
float MINIMUM_ROTATION_RATE = 2.0f;
if (fabsf(_bodyYawDelta) < MINIMUM_ROTATION_RATE) {
_bodyYawDelta = 0.0f;
} }
} }
getHead()->setBasePitch(getHead()->getBasePitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime); getHead()->setBasePitch(getHead()->getBasePitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime);
// update body orientation by movement inputs
setOrientation(getOrientation() *
glm::quat(glm::radians(glm::vec3(0.0f, _bodyYawDelta * deltaTime, 0.0f))));
if (qApp->getAvatarUpdater()->isHMDMode()) { if (qApp->getAvatarUpdater()->isHMDMode()) {
glm::quat orientation = glm::quat_cast(getSensorToWorldMatrix()) * getHMDSensorOrientation(); glm::quat orientation = glm::quat_cast(getSensorToWorldMatrix()) * getHMDSensorOrientation();

View file

@ -58,7 +58,7 @@ public:
AudioListenerMode getAudioListenerModeCamera() const { return FROM_CAMERA; } AudioListenerMode getAudioListenerModeCamera() const { return FROM_CAMERA; }
AudioListenerMode getAudioListenerModeCustom() const { return CUSTOM; } AudioListenerMode getAudioListenerModeCustom() const { return CUSTOM; }
void reset(); void reset(bool andReload = false);
void update(float deltaTime); void update(float deltaTime);
void preRender(RenderArgs* renderArgs); void preRender(RenderArgs* renderArgs);

View file

@ -24,7 +24,7 @@ void AssetResourceRequest::doSend() {
// Make request to atp // Make request to atp
auto assetClient = DependencyManager::get<AssetClient>(); auto assetClient = DependencyManager::get<AssetClient>();
auto parts = _url.path().split(".", QString::SkipEmptyParts); auto parts = _url.path().split(".", QString::SkipEmptyParts);
auto hash = parts[0]; auto hash = parts.length() > 0 ? parts[0] : "";
auto extension = parts.length() > 1 ? parts[1] : ""; auto extension = parts.length() > 1 ? parts[1] : "";
if (hash.length() != SHA256_HASH_HEX_LENGTH) { if (hash.length() != SHA256_HASH_HEX_LENGTH) {

View file

@ -319,6 +319,9 @@
userData: JSON.stringify({ userData: JSON.stringify({
resetMe: { resetMe: {
resetMe: true resetMe: true
},
grabbableKey: {
invertSolidWhileHeld: true
} }
}) })
}); });
@ -378,7 +381,8 @@
var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx'; var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx';
var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target_collision_hull.obj'; var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target_collision_hull.obj';
var RESET_DISTANCE = 1; var MINIMUM_MOVE_LENGTH = 0.05;
var RESET_DISTANCE = 0.5;
var TARGET_USER_DATA_KEY = 'hifi-ping_pong_target'; var TARGET_USER_DATA_KEY = 'hifi-ping_pong_target';
var NUMBER_OF_TARGETS = 6; var NUMBER_OF_TARGETS = 6;
var TARGETS_PER_ROW = 3; var TARGETS_PER_ROW = 3;
@ -392,7 +396,6 @@
var VERTICAL_SPACING = TARGET_DIMENSIONS.y + 0.5; var VERTICAL_SPACING = TARGET_DIMENSIONS.y + 0.5;
var HORIZONTAL_SPACING = TARGET_DIMENSIONS.z + 0.5; var HORIZONTAL_SPACING = TARGET_DIMENSIONS.z + 0.5;
var startPosition = { var startPosition = {
x: 548.68, x: 548.68,
y: 497.30, y: 497.30,
@ -413,6 +416,9 @@
userData: JSON.stringify({ userData: JSON.stringify({
resetMe: { resetMe: {
resetMe: true resetMe: true
},
grabbableKey: {
grabbable: false
} }
}) })
}); });
@ -421,6 +427,8 @@
var originalPositions = []; var originalPositions = [];
var lastPositions = [];
function addTargets() { function addTargets() {
var i; var i;
var row = -1; var row = -1;
@ -437,6 +445,7 @@
position.y = startPosition.y - (row * VERTICAL_SPACING); position.y = startPosition.y - (row * VERTICAL_SPACING);
originalPositions.push(position); originalPositions.push(position);
lastPositions.push(position);
var targetProperties = { var targetProperties = {
name: 'Target', name: 'Target',
@ -452,6 +461,9 @@
userData: JSON.stringify({ userData: JSON.stringify({
resetMe: { resetMe: {
resetMe: true resetMe: true
},
grabbableKey: {
grabbable: false
} }
}) })
}; };
@ -468,7 +480,11 @@
var distance = Vec3.subtract(originalPosition, currentPosition); var distance = Vec3.subtract(originalPosition, currentPosition);
var length = Vec3.length(distance); var length = Vec3.length(distance);
if (length > RESET_DISTANCE) { var moving = Vec3.length(Vec3.subtract(currentPosition, lastPositions[index]));
lastPositions[index] = currentPosition;
if (length > RESET_DISTANCE && moving < MINIMUM_MOVE_LENGTH) {
Entities.deleteEntity(target); Entities.deleteEntity(target);
@ -486,11 +502,14 @@
userData: JSON.stringify({ userData: JSON.stringify({
resetMe: { resetMe: {
resetMe: true resetMe: true
},
grabbableKey: {
grabbable: false
} }
}) })
}; };
var target = Entities.addEntity(targetProperties);
targets[index] = target; targets[index] = Entities.addEntity(targetProperties);
} }
}); });
@ -548,6 +567,9 @@
userData: JSON.stringify({ userData: JSON.stringify({
resetMe: { resetMe: {
resetMe: true resetMe: true
},
grabbableKey: {
grabbable: false
} }
}) })
}); });
@ -583,7 +605,11 @@
userData: JSON.stringify({ userData: JSON.stringify({
resetMe: { resetMe: {
resetMe: true resetMe: true
},
grabbableKey: {
invertSolidWhileHeld: true
} }
}) })
}); });
@ -851,6 +877,9 @@
userData: JSON.stringify({ userData: JSON.stringify({
resetMe: { resetMe: {
resetMe: true, resetMe: true,
},
grabbableKey: {
invertSolidWhileHeld: true
} }
}) })
}; };
@ -940,6 +969,9 @@
userData: JSON.stringify({ userData: JSON.stringify({
resetMe: { resetMe: {
resetMe: true, resetMe: true,
},
grabbableKey: {
invertSolidWhileHeld: true
} }
}) })
}); });
@ -1014,6 +1046,9 @@
userData: JSON.stringify({ userData: JSON.stringify({
resetMe: { resetMe: {
resetMe: true, resetMe: true,
},
grabbableKey: {
invertSolidWhileHeld: true
} }
}) })
}); });
@ -1053,6 +1088,9 @@
userData: JSON.stringify({ userData: JSON.stringify({
resetMe: { resetMe: {
resetMe: true, resetMe: true,
},
grabbableKey: {
invertSolidWhileHeld: true
} }
}) })
}); });
@ -1090,6 +1128,9 @@
userData: JSON.stringify({ userData: JSON.stringify({
resetMe: { resetMe: {
resetMe: true, resetMe: true,
},
grabbableKey: {
invertSolidWhileHeld: true
} }
}) })
}); });
@ -1126,6 +1167,9 @@
userData: JSON.stringify({ userData: JSON.stringify({
resetMe: { resetMe: {
resetMe: true, resetMe: true,
},
grabbableKey: {
invertSolidWhileHeld: true
} }
}) })
}); });

File diff suppressed because it is too large Load diff