mirror of
https://github.com/JulianGro/overte.git
synced 2025-08-08 08:07:47 +02:00
Merge branch 'master' into vr-edit-a
This commit is contained in:
commit
75365847a1
14 changed files with 314 additions and 31 deletions
|
@ -14,7 +14,6 @@
|
|||
var isWindowFocused = true;
|
||||
var isKeyboardRaised = false;
|
||||
var isNumericKeyboard = false;
|
||||
var KEYBOARD_HEIGHT = 200;
|
||||
|
||||
function shouldRaiseKeyboard() {
|
||||
var nodeName = document.activeElement.nodeName;
|
||||
|
@ -38,6 +37,19 @@
|
|||
return document.activeElement.type === "number";
|
||||
};
|
||||
|
||||
function scheduleBringToView(timeout) {
|
||||
|
||||
var timer = setTimeout(function () {
|
||||
clearTimeout(timer);
|
||||
|
||||
var elementRect = document.activeElement.getBoundingClientRect();
|
||||
var absoluteElementTop = elementRect.top + window.scrollY;
|
||||
var middle = absoluteElementTop - (window.innerHeight / 2);
|
||||
|
||||
window.scrollTo(0, middle);
|
||||
}, timeout);
|
||||
}
|
||||
|
||||
setInterval(function () {
|
||||
var keyboardRaised = shouldRaiseKeyboard();
|
||||
var numericKeyboard = shouldSetNumeric();
|
||||
|
@ -56,13 +68,8 @@
|
|||
}
|
||||
|
||||
if (!isKeyboardRaised) {
|
||||
var delta = document.activeElement.getBoundingClientRect().bottom + 10
|
||||
- (document.body.clientHeight - KEYBOARD_HEIGHT);
|
||||
if (delta > 0) {
|
||||
setTimeout(function () {
|
||||
document.body.scrollTop += delta;
|
||||
}, 500); // Allow time for keyboard to be raised in QML.
|
||||
}
|
||||
scheduleBringToView(250); // Allow time for keyboard to be raised in QML.
|
||||
// 2DO: should it be rather done from 'client area height changed' event?
|
||||
}
|
||||
|
||||
isKeyboardRaised = keyboardRaised;
|
||||
|
@ -70,6 +77,13 @@
|
|||
}
|
||||
}, POLL_FREQUENCY);
|
||||
|
||||
window.addEventListener("click", function () {
|
||||
var keyboardRaised = shouldRaiseKeyboard();
|
||||
if(keyboardRaised && isKeyboardRaised) {
|
||||
scheduleBringToView(150);
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener("focus", function () {
|
||||
isWindowFocused = true;
|
||||
});
|
||||
|
|
|
@ -278,9 +278,10 @@ Transform Line3DOverlay::evalRenderTransform() {
|
|||
auto endPos = getEnd();
|
||||
|
||||
auto vec = endPos - transform.getTranslation();
|
||||
auto scale = glm::length(vec);
|
||||
const float MIN_LINE_LENGTH = 0.0001f;
|
||||
auto scale = glm::max(glm::length(vec), MIN_LINE_LENGTH);
|
||||
auto dir = vec / scale;
|
||||
auto orientation = glm::rotation(glm::vec3(0,0,-1), dir);
|
||||
auto orientation = glm::rotation(glm::vec3(0.0f, 0.0f, -1.0f), dir);
|
||||
transform.setRotation(orientation);
|
||||
transform.setScale(scale);
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
||||
#include "ModelOverlay.h"
|
||||
#include <Rig.h>
|
||||
|
||||
|
@ -60,6 +63,15 @@ void ModelOverlay::update(float deltatime) {
|
|||
_model->simulate(deltatime);
|
||||
}
|
||||
_isLoaded = _model->isActive();
|
||||
|
||||
|
||||
if (isAnimatingSomething()) {
|
||||
if (!jointsMapped()) {
|
||||
mapAnimationJoints(_model->getJointNames());
|
||||
}
|
||||
animate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool ModelOverlay::addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) {
|
||||
|
@ -172,6 +184,51 @@ void ModelOverlay::setProperties(const QVariantMap& properties) {
|
|||
}
|
||||
_updateModel = true;
|
||||
}
|
||||
|
||||
auto animationSettings = properties["animationSettings"];
|
||||
if (animationSettings.canConvert(QVariant::Map)) {
|
||||
QVariantMap animationSettingsMap = animationSettings.toMap();
|
||||
|
||||
auto animationURL = animationSettingsMap["url"];
|
||||
auto animationFPS = animationSettingsMap["fps"];
|
||||
auto animationCurrentFrame = animationSettingsMap["currentFrame"];
|
||||
auto animationFirstFrame = animationSettingsMap["firstFrame"];
|
||||
auto animationLastFrame = animationSettingsMap["lastFrame"];
|
||||
auto animationRunning = animationSettingsMap["running"];
|
||||
auto animationLoop = animationSettingsMap["loop"];
|
||||
auto animationHold = animationSettingsMap["hold"];
|
||||
auto animationAllowTranslation = animationSettingsMap["allowTranslation"];
|
||||
|
||||
if (animationURL.canConvert(QVariant::Url)) {
|
||||
_animationURL = animationURL.toUrl();
|
||||
}
|
||||
if (animationFPS.isValid()) {
|
||||
_animationFPS = animationFPS.toFloat();
|
||||
}
|
||||
if (animationCurrentFrame.isValid()) {
|
||||
_animationCurrentFrame = animationCurrentFrame.toFloat();
|
||||
}
|
||||
if (animationFirstFrame.isValid()) {
|
||||
_animationFirstFrame = animationFirstFrame.toFloat();
|
||||
}
|
||||
if (animationLastFrame.isValid()) {
|
||||
_animationLastFrame = animationLastFrame.toFloat();
|
||||
}
|
||||
|
||||
if (animationRunning.canConvert(QVariant::Bool)) {
|
||||
_animationRunning = animationRunning.toBool();
|
||||
}
|
||||
if (animationLoop.canConvert(QVariant::Bool)) {
|
||||
_animationLoop = animationLoop.toBool();
|
||||
}
|
||||
if (animationHold.canConvert(QVariant::Bool)) {
|
||||
_animationHold = animationHold.toBool();
|
||||
}
|
||||
if (animationAllowTranslation.canConvert(QVariant::Bool)) {
|
||||
_animationAllowTranslation = animationAllowTranslation.toBool();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template <typename vectorType, typename itemType>
|
||||
|
@ -259,6 +316,24 @@ QVariant ModelOverlay::getProperty(const QString& property) {
|
|||
});
|
||||
}
|
||||
|
||||
// animation properties
|
||||
if (property == "animationSettings") {
|
||||
QVariantMap animationSettingsMap;
|
||||
|
||||
animationSettingsMap["url"] = _animationURL;
|
||||
animationSettingsMap["fps"] = _animationFPS;
|
||||
animationSettingsMap["currentFrame"] = _animationCurrentFrame;
|
||||
animationSettingsMap["firstFrame"] = _animationFirstFrame;
|
||||
animationSettingsMap["lastFrame"] = _animationLastFrame;
|
||||
animationSettingsMap["running"] = _animationRunning;
|
||||
animationSettingsMap["loop"] = _animationLoop;
|
||||
animationSettingsMap["hold"]= _animationHold;
|
||||
animationSettingsMap["allowTranslation"] = _animationAllowTranslation;
|
||||
|
||||
return animationSettingsMap;
|
||||
}
|
||||
|
||||
|
||||
return Volume3DOverlay::getProperty(property);
|
||||
}
|
||||
|
||||
|
@ -301,3 +376,134 @@ QString ModelOverlay::getName() const {
|
|||
}
|
||||
return QString("Overlay:") + getType() + ":" + _url.toString();
|
||||
}
|
||||
|
||||
|
||||
void ModelOverlay::animate() {
|
||||
|
||||
if (!_animation || !_animation->isLoaded() || !_model || !_model->isLoaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
QVector<JointData> jointsData;
|
||||
|
||||
const QVector<FBXAnimationFrame>& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy
|
||||
int frameCount = frames.size();
|
||||
if (frameCount <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_lastAnimated) {
|
||||
_lastAnimated = usecTimestampNow();
|
||||
return;
|
||||
}
|
||||
|
||||
auto now = usecTimestampNow();
|
||||
auto interval = now - _lastAnimated;
|
||||
_lastAnimated = now;
|
||||
float deltaTime = (float)interval / (float)USECS_PER_SECOND;
|
||||
_animationCurrentFrame += (deltaTime * _animationFPS);
|
||||
|
||||
int animationCurrentFrame = (int)(glm::floor(_animationCurrentFrame)) % frameCount;
|
||||
if (animationCurrentFrame < 0 || animationCurrentFrame > frameCount) {
|
||||
animationCurrentFrame = 0;
|
||||
}
|
||||
|
||||
if (animationCurrentFrame == _lastKnownCurrentFrame) {
|
||||
return;
|
||||
}
|
||||
_lastKnownCurrentFrame = animationCurrentFrame;
|
||||
|
||||
if (_jointMapping.size() != _model->getJointStateCount()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList animationJointNames = _animation->getGeometry().getJointNames();
|
||||
auto& fbxJoints = _animation->getGeometry().joints;
|
||||
|
||||
auto& originalFbxJoints = _model->getFBXGeometry().joints;
|
||||
auto& originalFbxIndices = _model->getFBXGeometry().jointIndices;
|
||||
|
||||
const QVector<glm::quat>& rotations = frames[_lastKnownCurrentFrame].rotations;
|
||||
const QVector<glm::vec3>& translations = frames[_lastKnownCurrentFrame].translations;
|
||||
|
||||
jointsData.resize(_jointMapping.size());
|
||||
for (int j = 0; j < _jointMapping.size(); j++) {
|
||||
int index = _jointMapping[j];
|
||||
|
||||
if (index >= 0) {
|
||||
glm::mat4 translationMat;
|
||||
|
||||
if (_animationAllowTranslation) {
|
||||
if (index < translations.size()) {
|
||||
translationMat = glm::translate(translations[index]);
|
||||
}
|
||||
} else if (index < animationJointNames.size()) {
|
||||
QString jointName = fbxJoints[index].name;
|
||||
|
||||
if (originalFbxIndices.contains(jointName)) {
|
||||
// Making sure the joint names exist in the original model the animation is trying to apply onto. If they do, then remap and get its translation.
|
||||
int remappedIndex = originalFbxIndices[jointName] - 1; // JointIndeces seem to always start from 1 and the found index is always 1 higher than actual.
|
||||
translationMat = glm::translate(originalFbxJoints[remappedIndex].translation);
|
||||
}
|
||||
}
|
||||
glm::mat4 rotationMat;
|
||||
if (index < rotations.size()) {
|
||||
rotationMat = glm::mat4_cast(fbxJoints[index].preRotation * rotations[index] * fbxJoints[index].postRotation);
|
||||
} else {
|
||||
rotationMat = glm::mat4_cast(fbxJoints[index].preRotation * fbxJoints[index].postRotation);
|
||||
}
|
||||
|
||||
glm::mat4 finalMat = (translationMat * fbxJoints[index].preTransform *
|
||||
rotationMat * fbxJoints[index].postTransform);
|
||||
auto& jointData = jointsData[j];
|
||||
jointData.translation = extractTranslation(finalMat);
|
||||
jointData.translationSet = true;
|
||||
jointData.rotation = glmExtractRotation(finalMat);
|
||||
jointData.rotationSet = true;
|
||||
}
|
||||
}
|
||||
// Set the data in the model
|
||||
copyAnimationJointDataToModel(jointsData);
|
||||
}
|
||||
|
||||
|
||||
void ModelOverlay::mapAnimationJoints(const QStringList& modelJointNames) {
|
||||
|
||||
// if we don't have animation, or we're already joint mapped then bail early
|
||||
if (!hasAnimation() || jointsMapped()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_animation || _animation->getURL() != _animationURL) {
|
||||
_animation = DependencyManager::get<AnimationCache>()->getAnimation(_animationURL);
|
||||
}
|
||||
|
||||
if (_animation && _animation->isLoaded()) {
|
||||
QStringList animationJointNames = _animation->getJointNames();
|
||||
|
||||
if (modelJointNames.size() > 0 && animationJointNames.size() > 0) {
|
||||
_jointMapping.resize(modelJointNames.size());
|
||||
for (int i = 0; i < modelJointNames.size(); i++) {
|
||||
_jointMapping[i] = animationJointNames.indexOf(modelJointNames[i]);
|
||||
}
|
||||
_jointMappingCompleted = true;
|
||||
_jointMappingURL = _animationURL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModelOverlay::copyAnimationJointDataToModel(QVector<JointData> jointsData) {
|
||||
if (!_model || !_model->isLoaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// relay any inbound joint changes from scripts/animation/network to the model/rig
|
||||
for (int index = 0; index < jointsData.size(); ++index) {
|
||||
auto& jointData = jointsData[index];
|
||||
_model->setJointRotation(index, true, jointData.rotation, 1.0f);
|
||||
_model->setJointTranslation(index, true, jointData.translation, 1.0f);
|
||||
}
|
||||
_updateModel = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#define hifi_ModelOverlay_h
|
||||
|
||||
#include <Model.h>
|
||||
#include <AnimationCache.h>
|
||||
|
||||
#include "Volume3DOverlay.h"
|
||||
|
||||
|
@ -45,6 +46,9 @@ public:
|
|||
|
||||
float getLoadPriority() const { return _loadPriority; }
|
||||
|
||||
bool hasAnimation() const { return !_animationURL.isEmpty(); }
|
||||
bool jointsMapped() const { return _jointMappingURL == _animationURL && _jointMappingCompleted; }
|
||||
|
||||
protected:
|
||||
Transform evalRenderTransform() override;
|
||||
|
||||
|
@ -53,6 +57,14 @@ protected:
|
|||
template <typename vectorType, typename itemType>
|
||||
vectorType mapJoints(mapFunction<itemType> function) const;
|
||||
|
||||
void animate();
|
||||
void mapAnimationJoints(const QStringList& modelJointNames);
|
||||
bool isAnimatingSomething() const {
|
||||
return !_animationURL.isEmpty() && _animationRunning && _animationFPS != 0.0f;
|
||||
}
|
||||
void copyAnimationJointDataToModel(QVector<JointData> jointsData);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
ModelPointer _model;
|
||||
|
@ -62,6 +74,25 @@ private:
|
|||
bool _updateModel = { false };
|
||||
bool _scaleToFit = { false };
|
||||
float _loadPriority { 0.0f };
|
||||
|
||||
AnimationPointer _animation;
|
||||
|
||||
QUrl _animationURL;
|
||||
float _animationFPS { 0.0f };
|
||||
float _animationCurrentFrame { 0.0f };
|
||||
bool _animationRunning { false };
|
||||
bool _animationLoop { false };
|
||||
float _animationFirstFrame { 0.0f };
|
||||
float _animationLastFrame = { 0.0f };
|
||||
bool _animationHold { false };
|
||||
bool _animationAllowTranslation { false };
|
||||
uint64_t _lastAnimated { 0 };
|
||||
int _lastKnownCurrentFrame { -1 };
|
||||
|
||||
QUrl _jointMappingURL;
|
||||
bool _jointMappingCompleted { false };
|
||||
QVector<int> _jointMapping; // domain is index into model-joints, range is index into animation-joints
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_ModelOverlay_h
|
||||
|
|
|
@ -45,7 +45,19 @@ void Volume3DOverlay::setProperties(const QVariantMap& properties) {
|
|||
}
|
||||
|
||||
if (dimensions.isValid()) {
|
||||
setDimensions(vec3FromVariant(dimensions));
|
||||
glm::vec3 scale = vec3FromVariant(dimensions);
|
||||
// don't allow a zero or negative dimension component to reach the renderTransform
|
||||
const float MIN_DIMENSION = 0.0001f;
|
||||
if (scale.x < MIN_DIMENSION) {
|
||||
scale.x = MIN_DIMENSION;
|
||||
}
|
||||
if (scale.y < MIN_DIMENSION) {
|
||||
scale.y = MIN_DIMENSION;
|
||||
}
|
||||
if (scale.z < MIN_DIMENSION) {
|
||||
scale.z = MIN_DIMENSION;
|
||||
}
|
||||
setDimensions(scale);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1570,13 +1570,17 @@ void EntityItem::updatePosition(const glm::vec3& value) {
|
|||
}
|
||||
|
||||
void EntityItem::updateParentID(const QUuid& value) {
|
||||
if (getParentID() != value) {
|
||||
QUuid oldParentID = getParentID();
|
||||
if (oldParentID != value) {
|
||||
EntityTreePointer tree = getTree();
|
||||
if (!oldParentID.isNull()) {
|
||||
tree->removeFromChildrenOfAvatars(getThisPointer());
|
||||
}
|
||||
setParentID(value);
|
||||
// children are forced to be kinematic
|
||||
// may need to not collide with own avatar
|
||||
markDirtyFlags(Simulation::DIRTY_MOTION_TYPE | Simulation::DIRTY_COLLISION_GROUP);
|
||||
|
||||
EntityTreePointer tree = getTree();
|
||||
if (tree) {
|
||||
tree->addToNeedsParentFixupList(getThisPointer());
|
||||
}
|
||||
|
|
|
@ -1148,11 +1148,8 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c
|
|||
} else if (!senderNode->getCanRez() && !senderNode->getCanRezTmp()) {
|
||||
failedAdd = true;
|
||||
qCDebug(entities) << "User without 'rez rights' [" << senderNode->getUUID()
|
||||
<< "] attempted to add an entity ID:" << entityItemID;
|
||||
// FIXME after Cert ID property integrated
|
||||
} else if (/*!properties.getCertificateID().isNull() && */!senderNode->getCanRezCertified() && !senderNode->getCanRezTmpCertified()) {
|
||||
qCDebug(entities) << "User without 'certified rez rights' [" << senderNode->getUUID()
|
||||
<< "] attempted to add a certified entity with ID:" << entityItemID;
|
||||
<< "] attempted to add an entity ID:" << entityItemID;
|
||||
|
||||
} else {
|
||||
// this is a new entity... assign a new entityID
|
||||
properties.setCreated(properties.getLastEdited());
|
||||
|
@ -1329,6 +1326,13 @@ void EntityTree::deleteDescendantsOfAvatar(QUuid avatarID) {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityTree::removeFromChildrenOfAvatars(EntityItemPointer entity) {
|
||||
QUuid avatarID = entity->getParentID();
|
||||
if (_childrenOfAvatars.contains(avatarID)) {
|
||||
_childrenOfAvatars[avatarID].remove(entity->getID());
|
||||
}
|
||||
}
|
||||
|
||||
void EntityTree::addToNeedsParentFixupList(EntityItemPointer entity) {
|
||||
QWriteLocker locker(&_needsParentFixupLock);
|
||||
_needsParentFixup.append(entity);
|
||||
|
|
|
@ -254,6 +254,7 @@ public:
|
|||
void knowAvatarID(QUuid avatarID) { _avatarIDs += avatarID; }
|
||||
void forgetAvatarID(QUuid avatarID) { _avatarIDs -= avatarID; }
|
||||
void deleteDescendantsOfAvatar(QUuid avatarID);
|
||||
void removeFromChildrenOfAvatars(EntityItemPointer entity);
|
||||
|
||||
void addToNeedsParentFixupList(EntityItemPointer entity);
|
||||
|
||||
|
|
|
@ -334,10 +334,8 @@ void OculusControllerManager::TouchDevice::handleHeadPose(float deltaTime,
|
|||
glm::mat4 defaultHeadOffset = glm::inverse(inputCalibrationData.defaultCenterEyeMat) *
|
||||
inputCalibrationData.defaultHeadMat;
|
||||
|
||||
controller::Pose hmdHeadPose = pose.transform(sensorToAvatar);
|
||||
|
||||
pose.valid = true;
|
||||
_poseStateMap[controller::HEAD] = hmdHeadPose.postTransform(defaultHeadOffset);
|
||||
_poseStateMap[controller::HEAD] = pose.postTransform(defaultHeadOffset).transform(sensorToAvatar);
|
||||
}
|
||||
|
||||
void OculusControllerManager::TouchDevice::handleRotationForUntrackedHand(const controller::InputCalibrationData& inputCalibrationData,
|
||||
|
|
|
@ -255,6 +255,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
this.messageGrabEntity = false;
|
||||
this.grabEntityProps = null;
|
||||
this.shouldSendStart = false;
|
||||
this.equipedWithSecondary = false;
|
||||
|
||||
this.parameters = makeDispatcherModuleParameters(
|
||||
300,
|
||||
|
@ -370,6 +371,10 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
return this.rawSecondaryValue < BUMPER_ON_VALUE;
|
||||
};
|
||||
|
||||
this.secondarySmoothedSqueezed = function() {
|
||||
return this.rawSecondaryValue > BUMPER_ON_VALUE;
|
||||
};
|
||||
|
||||
this.chooseNearEquipHotspots = function(candidateEntityProps, controllerData) {
|
||||
var _this = this;
|
||||
var collectedHotspots = flatten(candidateEntityProps.map(function(props) {
|
||||
|
@ -592,11 +597,13 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
// if the potentialHotspot os not cloneable and locked return null
|
||||
|
||||
if (potentialEquipHotspot &&
|
||||
((this.triggerSmoothedSqueezed() && !this.waitForTriggerRelease) || this.messageGrabEntity)) {
|
||||
(((this.triggerSmoothedSqueezed() || this.secondarySmoothedSqueezed()) && !this.waitForTriggerRelease) ||
|
||||
this.messageGrabEntity)) {
|
||||
this.grabbedHotspot = potentialEquipHotspot;
|
||||
this.targetEntityID = this.grabbedHotspot.entityID;
|
||||
this.startEquipEntity(controllerData);
|
||||
this.messageGrabEnity = false;
|
||||
this.equipedWithSecondary = this.secondarySmoothedSqueezed();
|
||||
return makeRunningValues(true, [potentialEquipHotspot.entityID], []);
|
||||
} else {
|
||||
return makeRunningValues(false, [], []);
|
||||
|
@ -627,7 +634,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
return this.checkNearbyHotspots(controllerData, deltaTime, timestamp);
|
||||
}
|
||||
|
||||
if (controllerData.secondaryValues[this.hand]) {
|
||||
if (controllerData.secondaryValues[this.hand] && !this.equipedWithSecondary) {
|
||||
// this.secondaryReleased() will always be true when not depressed
|
||||
// so we cannot simply rely on that for release - ensure that the
|
||||
// trigger was first "prepared" by being pushed in before the release
|
||||
|
@ -644,7 +651,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
|
||||
var dropDetected = this.dropGestureProcess(deltaTime);
|
||||
|
||||
if (this.triggerSmoothedReleased()) {
|
||||
if (this.triggerSmoothedReleased() || this.secondaryReleased()) {
|
||||
if (this.shouldSendStart) {
|
||||
// we don't want to send startEquip message until the trigger is released. otherwise,
|
||||
// guns etc will fire right as they are equipped.
|
||||
|
@ -653,6 +660,9 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
this.shouldSendStart = false;
|
||||
}
|
||||
this.waitForTriggerRelease = false;
|
||||
if (this.secondaryReleased() && this.equipedWithSecondary) {
|
||||
this.equipedWithSecondary = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (dropDetected && this.prevDropDetected !== dropDetected) {
|
||||
|
|
|
@ -132,7 +132,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
this.updateLaserPointer = function(controllerData) {
|
||||
var SEARCH_SPHERE_SIZE = 0.011;
|
||||
var MIN_SPHERE_SIZE = 0.0005;
|
||||
var radius = Math.max(1.2 * SEARCH_SPHERE_SIZE * this.intersectionDistance, MIN_SPHERE_SIZE);
|
||||
var radius = Math.max(1.2 * SEARCH_SPHERE_SIZE * this.intersectionDistance, MIN_SPHERE_SIZE) * MyAvatar.sensorToWorldScale;
|
||||
var dim = {x: radius, y: radius, z: radius};
|
||||
var mode = "hold";
|
||||
if (!this.distanceHolding && !this.distanceRotating) {
|
||||
|
@ -424,7 +424,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
this.laserPointerOff();
|
||||
return makeRunningValues(false, [], []);
|
||||
}
|
||||
|
||||
this.intersectionDistance = controllerData.rayPicks[this.hand].distance;
|
||||
this.updateLaserPointer(controllerData);
|
||||
|
||||
var otherModuleName =this.hand === RIGHT_HAND ? "LeftFarActionGrabEntity" : "RightFarActionGrabEntity";
|
||||
|
|
|
@ -335,7 +335,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
var SCALED_TABLET_MAX_HOVER_DISTANCE = TABLET_MAX_HOVER_DISTANCE * sensorScaleFactor;
|
||||
|
||||
if (nearestStylusTarget && nearestStylusTarget.distance > SCALED_TABLET_MIN_TOUCH_DISTANCE &&
|
||||
nearestStylusTarget.distance < SCALED_TABLET_MAX_HOVER_DISTANCE) {
|
||||
nearestStylusTarget.distance < SCALED_TABLET_MAX_HOVER_DISTANCE && !this.getOtherHandController().stylusTouchingTarget) {
|
||||
|
||||
this.requestTouchFocus(nearestStylusTarget);
|
||||
|
||||
|
|
|
@ -306,7 +306,7 @@ Grabber.prototype.computeNewGrabPlane = function() {
|
|||
};
|
||||
|
||||
Grabber.prototype.pressEvent = function(event) {
|
||||
if (isInEditMode()) {
|
||||
if (isInEditMode() || HMD.active) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -401,7 +401,7 @@ Grabber.prototype.pressEvent = function(event) {
|
|||
};
|
||||
|
||||
Grabber.prototype.releaseEvent = function(event) {
|
||||
if (event.isLeftButton!==true || event.isRightButton===true || event.isMiddleButton===true) {
|
||||
if ((event.isLeftButton!==true || event.isRightButton===true || event.isMiddleButton===true) && !HMD.active) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -447,7 +447,7 @@ Grabber.prototype.moveEvent = function(event) {
|
|||
// during the handling of the event, do as little as possible. We save the updated mouse position,
|
||||
// and start a timer to react to the change. If more changes arrive before the timer fires, only
|
||||
// the last update will be considered. This is done to avoid backing-up Qt's event queue.
|
||||
if (!this.isGrabbing) {
|
||||
if (!this.isGrabbing || HMD.active) {
|
||||
return;
|
||||
}
|
||||
mouse.updateDrag(event);
|
||||
|
@ -458,7 +458,7 @@ Grabber.prototype.moveEventProcess = function() {
|
|||
this.moveEventTimer = null;
|
||||
// see if something added/restored gravity
|
||||
var entityProperties = Entities.getEntityProperties(this.entityID);
|
||||
if (!entityProperties || !entityProperties.gravity) {
|
||||
if (!entityProperties || !entityProperties.gravity || HMD.active) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1474,6 +1474,8 @@ function onFileSaveChanged(filename) {
|
|||
}
|
||||
|
||||
function onFileOpenChanged(filename) {
|
||||
// disconnect the event, otherwise the requests will stack up
|
||||
Window.openFileChanged.disconnect(onFileOpenChanged);
|
||||
var importURL = null;
|
||||
if (filename !== "") {
|
||||
importURL = "file:///" + filename;
|
||||
|
|
Loading…
Reference in a new issue