mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 19:56:44 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into loginInitiative2
This commit is contained in:
commit
9e4c93c95d
19 changed files with 346 additions and 106 deletions
|
@ -3278,3 +3278,7 @@ void EntityItem::prepareForSimulationOwnershipBid(EntityItemProperties& properti
|
||||||
properties.setOwningAvatarID(getOwningAvatarID());
|
properties.setOwningAvatarID(getOwningAvatarID());
|
||||||
setLastBroadcast(now); // for debug/physics status icons
|
setLastBroadcast(now); // for debug/physics status icons
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EntityItem::isWearable() const {
|
||||||
|
return isVisible() && (getParentID() == DependencyManager::get<NodeList>()->getSessionUUID() || getParentID() == AVATAR_SELF_ID);
|
||||||
|
}
|
|
@ -489,7 +489,7 @@ public:
|
||||||
void scriptHasUnloaded();
|
void scriptHasUnloaded();
|
||||||
void setScriptHasFinishedPreload(bool value);
|
void setScriptHasFinishedPreload(bool value);
|
||||||
bool isScriptPreloadFinished();
|
bool isScriptPreloadFinished();
|
||||||
|
virtual bool isWearable() const;
|
||||||
bool isDomainEntity() const { return _hostType == entity::HostType::DOMAIN; }
|
bool isDomainEntity() const { return _hostType == entity::HostType::DOMAIN; }
|
||||||
bool isAvatarEntity() const { return _hostType == entity::HostType::AVATAR; }
|
bool isAvatarEntity() const { return _hostType == entity::HostType::AVATAR; }
|
||||||
bool isLocalEntity() const { return _hostType == entity::HostType::LOCAL; }
|
bool isLocalEntity() const { return _hostType == entity::HostType::LOCAL; }
|
||||||
|
|
|
@ -114,6 +114,8 @@ bool EntityScriptingInterface::canReplaceContent() {
|
||||||
|
|
||||||
void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) {
|
void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) {
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
|
disconnect(_entityTree.get(), &EntityTree::addingEntityPointer, this, &EntityScriptingInterface::onAddingEntity);
|
||||||
|
disconnect(_entityTree.get(), &EntityTree::deletingEntityPointer, this, &EntityScriptingInterface::onDeletingEntity);
|
||||||
disconnect(_entityTree.get(), &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity);
|
disconnect(_entityTree.get(), &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity);
|
||||||
disconnect(_entityTree.get(), &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity);
|
disconnect(_entityTree.get(), &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity);
|
||||||
disconnect(_entityTree.get(), &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities);
|
disconnect(_entityTree.get(), &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities);
|
||||||
|
@ -122,6 +124,8 @@ void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) {
|
||||||
_entityTree = elementTree;
|
_entityTree = elementTree;
|
||||||
|
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
|
connect(_entityTree.get(), &EntityTree::addingEntityPointer, this, &EntityScriptingInterface::onAddingEntity, Qt::DirectConnection);
|
||||||
|
connect(_entityTree.get(), &EntityTree::deletingEntityPointer, this, &EntityScriptingInterface::onDeletingEntity, Qt::DirectConnection);
|
||||||
connect(_entityTree.get(), &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity);
|
connect(_entityTree.get(), &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity);
|
||||||
connect(_entityTree.get(), &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity);
|
connect(_entityTree.get(), &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity);
|
||||||
connect(_entityTree.get(), &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities);
|
connect(_entityTree.get(), &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities);
|
||||||
|
@ -1060,7 +1064,17 @@ void EntityScriptingInterface::handleEntityScriptCallMethodPacket(QSharedPointer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityScriptingInterface::onAddingEntity(EntityItem* entity) {
|
||||||
|
if (entity->isWearable()) {
|
||||||
|
emit addingWearable(entity->getEntityItemID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityScriptingInterface::onDeletingEntity(EntityItem* entity) {
|
||||||
|
if (entity->isWearable()) {
|
||||||
|
emit deletingWearable(entity->getEntityItemID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
|
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
|
||||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||||
|
|
|
@ -1908,6 +1908,31 @@ signals:
|
||||||
*/
|
*/
|
||||||
void addingEntity(const EntityItemID& entityID);
|
void addingEntity(const EntityItemID& entityID);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Triggered when an 'wearable' entity is deleted.
|
||||||
|
* @function Entities.deletingWearable
|
||||||
|
* @param {Uuid} entityID - The ID of the 'wearable' entity deleted.
|
||||||
|
* @returns {Signal}
|
||||||
|
* @example <caption>Report when an 'wearable' entity is deleted.</caption>
|
||||||
|
* Entities.deletingWearable.connect(function (entityID) {
|
||||||
|
* print("Deleted wearable: " + entityID);
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
void deletingWearable(const EntityItemID& entityID);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Triggered when an 'wearable' entity is added to Interface's local in-memory tree of entities it knows about. This may occur when
|
||||||
|
* 'wearable' entities are added to avatar
|
||||||
|
* @function Entities.addingWearable
|
||||||
|
* @param {Uuid} entityID - The ID of the 'wearable' entity added.
|
||||||
|
* @returns {Signal}
|
||||||
|
* @example <caption>Report when an 'wearable' entity is added.</caption>
|
||||||
|
* Entities.addingWearable.connect(function (entityID) {
|
||||||
|
* print("Added wearable: " + entityID);
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
void addingWearable(const EntityItemID& entityID);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Triggered when you disconnect from a domain, at which time Interface's local in-memory tree of entities it knows about
|
* Triggered when you disconnect from a domain, at which time Interface's local in-memory tree of entities it knows about
|
||||||
* is cleared.
|
* is cleared.
|
||||||
|
@ -1938,6 +1963,8 @@ protected:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode);
|
void handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode);
|
||||||
|
void onAddingEntity(EntityItem* entity);
|
||||||
|
void onDeletingEntity(EntityItem* entity);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool actionWorker(const QUuid& entityID, std::function<bool(EntitySimulationPointer, EntityItemPointer)> actor);
|
bool actionWorker(const QUuid& entityID, std::function<bool(EntitySimulationPointer, EntityItemPointer)> actor);
|
||||||
|
|
|
@ -305,6 +305,7 @@ void EntityTree::postAddEntity(EntityItemPointer entity) {
|
||||||
fixupNeedsParentFixups();
|
fixupNeedsParentFixups();
|
||||||
|
|
||||||
emit addingEntity(entity->getEntityItemID());
|
emit addingEntity(entity->getEntityItemID());
|
||||||
|
emit addingEntityPointer(entity.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode) {
|
bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode) {
|
||||||
|
|
|
@ -309,6 +309,7 @@ signals:
|
||||||
void deletingEntity(const EntityItemID& entityID);
|
void deletingEntity(const EntityItemID& entityID);
|
||||||
void deletingEntityPointer(EntityItem* entityID);
|
void deletingEntityPointer(EntityItem* entityID);
|
||||||
void addingEntity(const EntityItemID& entityID);
|
void addingEntity(const EntityItemID& entityID);
|
||||||
|
void addingEntityPointer(EntityItem* entityID);
|
||||||
void editingEntityPointer(const EntityItemPointer& entityID);
|
void editingEntityPointer(const EntityItemPointer& entityID);
|
||||||
void entityScriptChanging(const EntityItemID& entityItemID, const bool reload);
|
void entityScriptChanging(const EntityItemID& entityItemID, const bool reload);
|
||||||
void entityServerScriptChanging(const EntityItemID& entityItemID, const bool reload);
|
void entityServerScriptChanging(const EntityItemID& entityItemID, const bool reload);
|
||||||
|
|
|
@ -519,7 +519,6 @@ QVector<bool> ModelEntityItem::getJointTranslationsSet() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ModelEntityItem::hasModel() const {
|
bool ModelEntityItem::hasModel() const {
|
||||||
return resultWithReadLock<bool>([&] {
|
return resultWithReadLock<bool>([&] {
|
||||||
return !_modelURL.isEmpty();
|
return !_modelURL.isEmpty();
|
||||||
|
|
|
@ -31,6 +31,8 @@ static const QUrl DEFAULT_SCRIPTS_LOCATION { "file:///~//defaultScripts.js" };
|
||||||
// Using a QVariantList so this is human-readable in the settings file
|
// Using a QVariantList so this is human-readable in the settings file
|
||||||
static Setting::Handle<QVariantList> runningScriptsHandle(SETTINGS_KEY, { QVariant(DEFAULT_SCRIPTS_LOCATION) });
|
static Setting::Handle<QVariantList> runningScriptsHandle(SETTINGS_KEY, { QVariant(DEFAULT_SCRIPTS_LOCATION) });
|
||||||
|
|
||||||
|
const int RELOAD_ALL_SCRIPTS_TIMEOUT = 1000;
|
||||||
|
|
||||||
|
|
||||||
ScriptsModel& getScriptsModel() {
|
ScriptsModel& getScriptsModel() {
|
||||||
static ScriptsModel scriptsModel;
|
static ScriptsModel scriptsModel;
|
||||||
|
@ -387,15 +389,10 @@ void ScriptEngines::stopAllScripts(bool restart) {
|
||||||
// queue user scripts if restarting
|
// queue user scripts if restarting
|
||||||
if (restart && scriptEngine->isUserLoaded()) {
|
if (restart && scriptEngine->isUserLoaded()) {
|
||||||
_isReloading = true;
|
_isReloading = true;
|
||||||
bool lastScript = (it == _scriptEnginesHash.constEnd() - 1);
|
|
||||||
ScriptEngine::Type type = scriptEngine->getType();
|
ScriptEngine::Type type = scriptEngine->getType();
|
||||||
|
|
||||||
connect(scriptEngine.data(), &ScriptEngine::finished, this, [this, type, lastScript] (QString scriptName) {
|
connect(scriptEngine.data(), &ScriptEngine::finished, this, [this, type] (QString scriptName) {
|
||||||
reloadScript(scriptName, true)->setType(type);
|
reloadScript(scriptName, true)->setType(type);
|
||||||
|
|
||||||
if (lastScript) {
|
|
||||||
_isReloading = false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,6 +402,9 @@ void ScriptEngines::stopAllScripts(bool restart) {
|
||||||
|
|
||||||
if (restart) {
|
if (restart) {
|
||||||
qCDebug(scriptengine) << "stopAllScripts -- emitting scriptsReloading";
|
qCDebug(scriptengine) << "stopAllScripts -- emitting scriptsReloading";
|
||||||
|
QTimer::singleShot(RELOAD_ALL_SCRIPTS_TIMEOUT, this, [&] {
|
||||||
|
_isReloading = false;
|
||||||
|
});
|
||||||
emit scriptsReloading();
|
emit scriptsReloading();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,12 +69,12 @@ function getMyAvatarSettings() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateAvatarWearables(avatar, bookmarkAvatarName, callback) {
|
function updateAvatarWearables(avatar, callback) {
|
||||||
executeLater(function() {
|
executeLater(function() {
|
||||||
var wearables = getMyAvatarWearables();
|
var wearables = getMyAvatarWearables();
|
||||||
avatar[ENTRY_AVATAR_ENTITIES] = wearables;
|
avatar[ENTRY_AVATAR_ENTITIES] = wearables;
|
||||||
|
|
||||||
sendToQml({'method' : 'wearablesUpdated', 'wearables' : wearables, 'avatarName' : bookmarkAvatarName})
|
sendToQml({'method' : 'wearablesUpdated', 'wearables' : wearables})
|
||||||
|
|
||||||
if(callback)
|
if(callback)
|
||||||
callback();
|
callback();
|
||||||
|
@ -188,7 +188,11 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
|
||||||
sendToQml(message)
|
sendToQml(message)
|
||||||
break;
|
break;
|
||||||
case 'selectAvatar':
|
case 'selectAvatar':
|
||||||
|
Entities.addingWearable.disconnect(onAddingWearable);
|
||||||
|
Entities.deletingWearable.disconnect(onDeletingWearable);
|
||||||
AvatarBookmarks.loadBookmark(message.name);
|
AvatarBookmarks.loadBookmark(message.name);
|
||||||
|
Entities.addingWearable.connect(onAddingWearable);
|
||||||
|
Entities.deletingWearable.connect(onDeletingWearable);
|
||||||
break;
|
break;
|
||||||
case 'deleteAvatar':
|
case 'deleteAvatar':
|
||||||
AvatarBookmarks.removeBookmark(message.name);
|
AvatarBookmarks.removeBookmark(message.name);
|
||||||
|
@ -223,7 +227,7 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
|
||||||
// revert changes using snapshot of wearables
|
// revert changes using snapshot of wearables
|
||||||
if(currentAvatarWearablesBackup !== null) {
|
if(currentAvatarWearablesBackup !== null) {
|
||||||
AvatarBookmarks.updateAvatarEntities(currentAvatarWearablesBackup);
|
AvatarBookmarks.updateAvatarEntities(currentAvatarWearablesBackup);
|
||||||
updateAvatarWearables(currentAvatar, message.avatarName);
|
updateAvatarWearables(currentAvatar);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sendToQml({'method' : 'updateAvatarInBookmarks'});
|
sendToQml({'method' : 'updateAvatarInBookmarks'});
|
||||||
|
@ -256,8 +260,11 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
|
||||||
parentJointIndex: hipsIndex
|
parentJointIndex: hipsIndex
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Entities.addingWearable.disconnect(onAddingWearable);
|
||||||
var entityID = Entities.addEntity(properties, true);
|
var entityID = Entities.addEntity(properties, true);
|
||||||
updateAvatarWearables(currentAvatar, message.avatarName, function() {
|
Entities.addingWearable.connect(onAddingWearable);
|
||||||
|
|
||||||
|
updateAvatarWearables(currentAvatar, function() {
|
||||||
onSelectedEntity(entityID);
|
onSelectedEntity(entityID);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
@ -265,8 +272,12 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
|
||||||
ensureWearableSelected(message.entityID);
|
ensureWearableSelected(message.entityID);
|
||||||
break;
|
break;
|
||||||
case 'deleteWearable':
|
case 'deleteWearable':
|
||||||
|
|
||||||
|
Entities.deletingWearable.disconnect(onDeletingWearable);
|
||||||
Entities.deleteEntity(message.entityID);
|
Entities.deleteEntity(message.entityID);
|
||||||
updateAvatarWearables(currentAvatar, message.avatarName);
|
Entities.deletingWearable.connect(onDeletingWearable);
|
||||||
|
|
||||||
|
updateAvatarWearables(currentAvatar);
|
||||||
break;
|
break;
|
||||||
case 'changeDisplayName':
|
case 'changeDisplayName':
|
||||||
if (MyAvatar.displayName !== message.displayName) {
|
if (MyAvatar.displayName !== message.displayName) {
|
||||||
|
@ -380,6 +391,18 @@ function onSelectedEntity(entityID, pointerEvent) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onAddingWearable(entityID) {
|
||||||
|
updateAvatarWearables(currentAvatar, function() {
|
||||||
|
sendToQml({'method' : 'updateAvatarInBookmarks'});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDeletingWearable(entityID) {
|
||||||
|
updateAvatarWearables(currentAvatar, function() {
|
||||||
|
sendToQml({'method' : 'updateAvatarInBookmarks'});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function handleWearableMessages(channel, message, sender) {
|
function handleWearableMessages(channel, message, sender) {
|
||||||
if (channel !== 'Hifi-Object-Manipulation') {
|
if (channel !== 'Hifi-Object-Manipulation') {
|
||||||
return;
|
return;
|
||||||
|
@ -485,6 +508,8 @@ function off() {
|
||||||
AvatarBookmarks.bookmarkDeleted.disconnect(onBookmarkDeleted);
|
AvatarBookmarks.bookmarkDeleted.disconnect(onBookmarkDeleted);
|
||||||
AvatarBookmarks.bookmarkAdded.disconnect(onBookmarkAdded);
|
AvatarBookmarks.bookmarkAdded.disconnect(onBookmarkAdded);
|
||||||
|
|
||||||
|
Entities.addingWearable.disconnect(onAddingWearable);
|
||||||
|
Entities.deletingWearable.disconnect(onDeletingWearable);
|
||||||
MyAvatar.skeletonModelURLChanged.disconnect(onSkeletonModelURLChanged);
|
MyAvatar.skeletonModelURLChanged.disconnect(onSkeletonModelURLChanged);
|
||||||
MyAvatar.dominantHandChanged.disconnect(onDominantHandChanged);
|
MyAvatar.dominantHandChanged.disconnect(onDominantHandChanged);
|
||||||
MyAvatar.collisionsEnabledChanged.disconnect(onCollisionsEnabledChanged);
|
MyAvatar.collisionsEnabledChanged.disconnect(onCollisionsEnabledChanged);
|
||||||
|
@ -495,16 +520,23 @@ function off() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function on() {
|
function on() {
|
||||||
AvatarBookmarks.bookmarkLoaded.connect(onBookmarkLoaded);
|
|
||||||
AvatarBookmarks.bookmarkDeleted.connect(onBookmarkDeleted);
|
|
||||||
AvatarBookmarks.bookmarkAdded.connect(onBookmarkAdded);
|
|
||||||
|
|
||||||
MyAvatar.skeletonModelURLChanged.connect(onSkeletonModelURLChanged);
|
if (!isWired) { // It is not ok to connect these twice, hence guard.
|
||||||
MyAvatar.dominantHandChanged.connect(onDominantHandChanged);
|
isWired = true;
|
||||||
MyAvatar.collisionsEnabledChanged.connect(onCollisionsEnabledChanged);
|
|
||||||
MyAvatar.newCollisionSoundURL.connect(onNewCollisionSoundUrl);
|
AvatarBookmarks.bookmarkLoaded.connect(onBookmarkLoaded);
|
||||||
MyAvatar.animGraphUrlChanged.connect(onAnimGraphUrlChanged);
|
AvatarBookmarks.bookmarkDeleted.connect(onBookmarkDeleted);
|
||||||
MyAvatar.targetScaleChanged.connect(onTargetScaleChanged);
|
AvatarBookmarks.bookmarkAdded.connect(onBookmarkAdded);
|
||||||
|
|
||||||
|
Entities.addingWearable.connect(onAddingWearable);
|
||||||
|
Entities.deletingWearable.connect(onDeletingWearable);
|
||||||
|
MyAvatar.skeletonModelURLChanged.connect(onSkeletonModelURLChanged);
|
||||||
|
MyAvatar.dominantHandChanged.connect(onDominantHandChanged);
|
||||||
|
MyAvatar.collisionsEnabledChanged.connect(onCollisionsEnabledChanged);
|
||||||
|
MyAvatar.newCollisionSoundURL.connect(onNewCollisionSoundUrl);
|
||||||
|
MyAvatar.animGraphUrlChanged.connect(onAnimGraphUrlChanged);
|
||||||
|
MyAvatar.targetScaleChanged.connect(onTargetScaleChanged);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onTabletButtonClicked() {
|
function onTabletButtonClicked() {
|
||||||
|
@ -514,7 +546,6 @@ function onTabletButtonClicked() {
|
||||||
} else {
|
} else {
|
||||||
ContextOverlay.enabled = false;
|
ContextOverlay.enabled = false;
|
||||||
tablet.loadQMLSource(AVATARAPP_QML_SOURCE);
|
tablet.loadQMLSource(AVATARAPP_QML_SOURCE);
|
||||||
isWired = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var hasEventBridge = false;
|
var hasEventBridge = false;
|
||||||
|
|
|
@ -424,9 +424,19 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.leftBlacklistTabletIDs = [];
|
||||||
|
this.rightBlacklistTabletIDs = [];
|
||||||
|
|
||||||
|
this.setLeftBlacklist = function () {
|
||||||
|
Pointers.setIgnoreItems(_this.leftPointer, _this.blacklist.concat(_this.leftBlacklistTabletIDs));
|
||||||
|
};
|
||||||
|
this.setRightBlacklist = function () {
|
||||||
|
Pointers.setIgnoreItems(_this.rightPointer, _this.blacklist.concat(_this.rightBlacklistTabletIDs));
|
||||||
|
};
|
||||||
|
|
||||||
this.setBlacklist = function() {
|
this.setBlacklist = function() {
|
||||||
Pointers.setIgnoreItems(_this.leftPointer, this.blacklist);
|
_this.setLeftBlacklist();
|
||||||
Pointers.setIgnoreItems(_this.rightPointer, this.blacklist);
|
_this.setRightBlacklist();
|
||||||
};
|
};
|
||||||
|
|
||||||
var MAPPING_NAME = "com.highfidelity.controllerDispatcher";
|
var MAPPING_NAME = "com.highfidelity.controllerDispatcher";
|
||||||
|
@ -490,7 +500,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
filter: Picks.PICK_OVERLAYS | Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_NONCOLLIDABLE,
|
filter: Picks.PICK_OVERLAYS | Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_NONCOLLIDABLE,
|
||||||
enabled: true
|
enabled: true
|
||||||
});
|
});
|
||||||
this.handleHandMessage = function(channel, data, sender) {
|
this.handleMessage = function (channel, data, sender) {
|
||||||
var message;
|
var message;
|
||||||
if (sender === MyAvatar.sessionUUID) {
|
if (sender === MyAvatar.sessionUUID) {
|
||||||
try {
|
try {
|
||||||
|
@ -511,6 +521,18 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
_this.setBlacklist();
|
_this.setBlacklist();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action === "tablet") {
|
||||||
|
var tabletIDs = message.blacklist
|
||||||
|
? [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID, HMD.homeButtonHighlightID] : [];
|
||||||
|
if (message.hand === LEFT_HAND) {
|
||||||
|
_this.leftBlacklistTabletIDs = tabletIDs;
|
||||||
|
_this.setLeftBlacklist();
|
||||||
|
} else {
|
||||||
|
_this.rightBlacklistTabletIDs = tabletIDs;
|
||||||
|
_this.setRightBlacklist();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("WARNING: handControllerGrab.js -- error parsing message: " + data);
|
print("WARNING: handControllerGrab.js -- error parsing message: " + data);
|
||||||
|
@ -550,7 +572,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
|
|
||||||
var controllerDispatcher = new ControllerDispatcher();
|
var controllerDispatcher = new ControllerDispatcher();
|
||||||
Messages.subscribe('Hifi-Hand-RayPick-Blacklist');
|
Messages.subscribe('Hifi-Hand-RayPick-Blacklist');
|
||||||
Messages.messageReceived.connect(controllerDispatcher.handleHandMessage);
|
Messages.messageReceived.connect(controllerDispatcher.handleMessage);
|
||||||
|
|
||||||
Script.scriptEnding.connect(controllerDispatcher.cleanup);
|
Script.scriptEnding.connect(controllerDispatcher.cleanup);
|
||||||
Script.setTimeout(controllerDispatcher.update, BASIC_TIMER_INTERVAL_MS);
|
Script.setTimeout(controllerDispatcher.update, BASIC_TIMER_INTERVAL_MS);
|
||||||
}());
|
}());
|
||||||
|
|
|
@ -48,6 +48,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
|
|
||||||
function FarActionGrabEntity(hand) {
|
function FarActionGrabEntity(hand) {
|
||||||
this.hand = hand;
|
this.hand = hand;
|
||||||
|
this.grabbing = false;
|
||||||
this.grabbedThingID = null;
|
this.grabbedThingID = null;
|
||||||
this.targetObject = null;
|
this.targetObject = null;
|
||||||
this.actionID = null; // action this script created...
|
this.actionID = null; // action this script created...
|
||||||
|
@ -151,6 +152,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
|
|
||||||
Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand);
|
Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand);
|
||||||
this.previousRoomControllerPosition = roomControllerPosition;
|
this.previousRoomControllerPosition = roomControllerPosition;
|
||||||
|
this.grabbing = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.continueDistanceHolding = function(controllerData) {
|
this.continueDistanceHolding = function(controllerData) {
|
||||||
|
@ -246,6 +248,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.grabbedThingID = null;
|
this.grabbedThingID = null;
|
||||||
this.targetObject = null;
|
this.targetObject = null;
|
||||||
this.potentialEntityWithContextOverlay = false;
|
this.potentialEntityWithContextOverlay = false;
|
||||||
|
this.grabbing = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.updateRecommendedArea = function() {
|
this.updateRecommendedArea = function() {
|
||||||
|
@ -357,8 +360,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.run = function (controllerData) {
|
this.run = function (controllerData) {
|
||||||
if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE ||
|
if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE || this.targetIsNull()) {
|
||||||
this.notPointingAtEntity(controllerData) || this.targetIsNull()) {
|
|
||||||
this.endFarGrabAction();
|
this.endFarGrabAction();
|
||||||
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
|
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
|
||||||
this.highlightedEntity);
|
this.highlightedEntity);
|
||||||
|
@ -375,10 +377,12 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.hand === RIGHT_HAND ? "RightScaleAvatar" : "LeftScaleAvatar",
|
this.hand === RIGHT_HAND ? "RightScaleAvatar" : "LeftScaleAvatar",
|
||||||
this.hand === RIGHT_HAND ? "RightFarTriggerEntity" : "LeftFarTriggerEntity",
|
this.hand === RIGHT_HAND ? "RightFarTriggerEntity" : "LeftFarTriggerEntity",
|
||||||
this.hand === RIGHT_HAND ? "RightNearActionGrabEntity" : "LeftNearActionGrabEntity",
|
this.hand === RIGHT_HAND ? "RightNearActionGrabEntity" : "LeftNearActionGrabEntity",
|
||||||
this.hand === RIGHT_HAND ? "RightNearParentingGrabEntity" : "LeftNearParentingGrabEntity",
|
this.hand === RIGHT_HAND ? "RightNearParentingGrabEntity" : "LeftNearParentingGrabEntity"
|
||||||
this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay",
|
|
||||||
this.hand === RIGHT_HAND ? "RightNearTabletHighlight" : "LeftNearTabletHighlight"
|
|
||||||
];
|
];
|
||||||
|
if (!this.grabbing) {
|
||||||
|
nearGrabNames.push(this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay");
|
||||||
|
nearGrabNames.push(this.hand === RIGHT_HAND ? "RightNearTabletHighlight" : "LeftNearTabletHighlight");
|
||||||
|
}
|
||||||
|
|
||||||
var nearGrabReadiness = [];
|
var nearGrabReadiness = [];
|
||||||
for (var i = 0; i < nearGrabNames.length; i++) {
|
for (var i = 0; i < nearGrabNames.length; i++) {
|
||||||
|
|
|
@ -47,6 +47,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
|
|
||||||
function FarParentGrabEntity(hand) {
|
function FarParentGrabEntity(hand) {
|
||||||
this.hand = hand;
|
this.hand = hand;
|
||||||
|
this.grabbing = false;
|
||||||
this.targetEntityID = null;
|
this.targetEntityID = null;
|
||||||
this.targetObject = null;
|
this.targetObject = null;
|
||||||
this.previouslyUnhooked = {};
|
this.previouslyUnhooked = {};
|
||||||
|
@ -455,8 +456,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.run = function (controllerData) {
|
this.run = function (controllerData) {
|
||||||
if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE ||
|
if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE || this.targetIsNull()) {
|
||||||
this.notPointingAtEntity(controllerData) || this.targetIsNull()) {
|
|
||||||
this.endFarParentGrab(controllerData);
|
this.endFarParentGrab(controllerData);
|
||||||
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", this.highlightedEntity);
|
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", this.highlightedEntity);
|
||||||
this.highlightedEntity = null;
|
this.highlightedEntity = null;
|
||||||
|
@ -472,10 +472,12 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
this.hand === RIGHT_HAND ? "RightScaleAvatar" : "LeftScaleAvatar",
|
this.hand === RIGHT_HAND ? "RightScaleAvatar" : "LeftScaleAvatar",
|
||||||
this.hand === RIGHT_HAND ? "RightFarTriggerEntity" : "LeftFarTriggerEntity",
|
this.hand === RIGHT_HAND ? "RightFarTriggerEntity" : "LeftFarTriggerEntity",
|
||||||
this.hand === RIGHT_HAND ? "RightNearActionGrabEntity" : "LeftNearActionGrabEntity",
|
this.hand === RIGHT_HAND ? "RightNearActionGrabEntity" : "LeftNearActionGrabEntity",
|
||||||
this.hand === RIGHT_HAND ? "RightNearParentingGrabEntity" : "LeftNearParentingGrabEntity",
|
this.hand === RIGHT_HAND ? "RightNearParentingGrabEntity" : "LeftNearParentingGrabEntity"
|
||||||
this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay",
|
|
||||||
this.hand === RIGHT_HAND ? "RightNearTabletHighlight" : "LeftNearTabletHighlight"
|
|
||||||
];
|
];
|
||||||
|
if (!this.grabbing) {
|
||||||
|
nearGrabNames.push(this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay");
|
||||||
|
nearGrabNames.push(this.hand === RIGHT_HAND ? "RightNearTabletHighlight" : "LeftNearTabletHighlight");
|
||||||
|
}
|
||||||
|
|
||||||
var nearGrabReadiness = [];
|
var nearGrabReadiness = [];
|
||||||
for (var i = 0; i < nearGrabNames.length; i++) {
|
for (var i = 0; i < nearGrabNames.length; i++) {
|
||||||
|
@ -485,11 +487,10 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.targetEntityID) {
|
if (this.targetEntityID) {
|
||||||
// if we are doing a distance grab and the object or tablet gets close enough to the controller,
|
// if we are doing a distance grab and the object gets close enough to the controller,
|
||||||
// stop the far-grab so the near-grab or equip can take over.
|
// stop the far-grab so the near-grab or equip can take over.
|
||||||
for (var k = 0; k < nearGrabReadiness.length; k++) {
|
for (var k = 0; k < nearGrabReadiness.length; k++) {
|
||||||
if (nearGrabReadiness[k].active && (nearGrabReadiness[k].targets[0] === this.targetEntityID ||
|
if (nearGrabReadiness[k].active && (nearGrabReadiness[k].targets[0] === this.targetEntityID)) {
|
||||||
HMD.tabletID && nearGrabReadiness[k].targets[0] === HMD.tabletID)) {
|
|
||||||
this.endFarParentGrab(controllerData);
|
this.endFarParentGrab(controllerData);
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
|
|
||||||
this.getTargetProps = function (controllerData) {
|
this.getTargetProps = function (controllerData) {
|
||||||
var targetEntity = controllerData.rayPicks[this.hand].objectID;
|
var targetEntity = controllerData.rayPicks[this.hand].objectID;
|
||||||
if (targetEntity) {
|
if (targetEntity && controllerData.rayPicks[this.hand].type === RayPick.INTERSECTED_ENTITY) {
|
||||||
var targetProperties = Entities.getEntityProperties(targetEntity, DISPATCHER_PROPERTIES);
|
var targetProperties = Entities.getEntityProperties(targetEntity, DISPATCHER_PROPERTIES);
|
||||||
if (entityWantsFarTrigger(targetProperties)) {
|
if (entityWantsFarTrigger(targetProperties)) {
|
||||||
return targetProperties;
|
return targetProperties;
|
||||||
|
|
|
@ -20,6 +20,7 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
var MARGIN = 25;
|
var MARGIN = 25;
|
||||||
function InEditMode(hand) {
|
function InEditMode(hand) {
|
||||||
this.hand = hand;
|
this.hand = hand;
|
||||||
|
this.isEditing = false;
|
||||||
this.triggerClicked = false;
|
this.triggerClicked = false;
|
||||||
this.selectedTarget = null;
|
this.selectedTarget = null;
|
||||||
this.reticleMinX = MARGIN;
|
this.reticleMinX = MARGIN;
|
||||||
|
@ -62,25 +63,27 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
return point2d;
|
return point2d;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.ENTITY_TOOL_UPDATES_CHANNEL = "entityToolUpdates";
|
||||||
|
|
||||||
this.sendPickData = function(controllerData) {
|
this.sendPickData = function(controllerData) {
|
||||||
if (controllerData.triggerClicks[this.hand]) {
|
if (controllerData.triggerClicks[this.hand]) {
|
||||||
var hand = this.hand === RIGHT_HAND ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
|
var hand = this.hand === RIGHT_HAND ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
|
||||||
if (!this.triggerClicked) {
|
if (!this.triggerClicked) {
|
||||||
this.selectedTarget = controllerData.rayPicks[this.hand];
|
this.selectedTarget = controllerData.rayPicks[this.hand];
|
||||||
if (!this.selectedTarget.intersects) {
|
if (!this.selectedTarget.intersects) {
|
||||||
Messages.sendLocalMessage("entityToolUpdates", JSON.stringify({
|
Messages.sendLocalMessage(this.ENTITY_TOOL_UPDATES_CHANNEL, JSON.stringify({
|
||||||
method: "clearSelection",
|
method: "clearSelection",
|
||||||
hand: hand
|
hand: hand
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
if (this.selectedTarget.type === Picks.INTERSECTED_ENTITY) {
|
if (this.selectedTarget.type === Picks.INTERSECTED_ENTITY) {
|
||||||
Messages.sendLocalMessage("entityToolUpdates", JSON.stringify({
|
Messages.sendLocalMessage(this.ENTITY_TOOL_UPDATES_CHANNEL, JSON.stringify({
|
||||||
method: "selectEntity",
|
method: "selectEntity",
|
||||||
entityID: this.selectedTarget.objectID,
|
entityID: this.selectedTarget.objectID,
|
||||||
hand: hand
|
hand: hand
|
||||||
}));
|
}));
|
||||||
} else if (this.selectedTarget.type === Picks.INTERSECTED_OVERLAY) {
|
} else if (this.selectedTarget.type === Picks.INTERSECTED_OVERLAY) {
|
||||||
Messages.sendLocalMessage("entityToolUpdates", JSON.stringify({
|
Messages.sendLocalMessage(this.ENTITY_TOOL_UPDATES_CHANNEL, JSON.stringify({
|
||||||
method: "selectOverlay",
|
method: "selectOverlay",
|
||||||
overlayID: this.selectedTarget.objectID,
|
overlayID: this.selectedTarget.objectID,
|
||||||
hand: hand
|
hand: hand
|
||||||
|
@ -102,7 +105,7 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
var desktopWindow = Window.isPointOnDesktopWindow(point2d);
|
var desktopWindow = Window.isPointOnDesktopWindow(point2d);
|
||||||
var tablet = this.pointingAtTablet(rayPick.objectID);
|
var tablet = this.pointingAtTablet(rayPick.objectID);
|
||||||
var rightHand = this.hand === RIGHT_HAND;
|
var rightHand = this.hand === RIGHT_HAND;
|
||||||
Messages.sendLocalMessage("entityToolUpdates", JSON.stringify({
|
Messages.sendLocalMessage(this.ENTITY_TOOL_UPDATES_CHANNEL, JSON.stringify({
|
||||||
method: "pointingAt",
|
method: "pointingAt",
|
||||||
desktopWindow: desktopWindow,
|
desktopWindow: desktopWindow,
|
||||||
tablet: tablet,
|
tablet: tablet,
|
||||||
|
@ -110,6 +113,10 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.runModule = function() {
|
||||||
|
return makeRunningValues(true, [], []);
|
||||||
|
};
|
||||||
|
|
||||||
this.exitModule = function() {
|
this.exitModule = function() {
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
};
|
};
|
||||||
|
@ -120,13 +127,15 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
this.triggerClicked = false;
|
this.triggerClicked = false;
|
||||||
}
|
}
|
||||||
Messages.sendLocalMessage('Hifi-unhighlight-all', '');
|
Messages.sendLocalMessage('Hifi-unhighlight-all', '');
|
||||||
return makeRunningValues(true, [], []);
|
return this.runModule();
|
||||||
}
|
}
|
||||||
this.triggerClicked = false;
|
this.triggerClicked = false;
|
||||||
return makeRunningValues(false, [], []);
|
return this.exitModule();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.run = function(controllerData) {
|
this.run = function(controllerData) {
|
||||||
|
|
||||||
|
// Tablet stylus.
|
||||||
var tabletStylusInput = getEnabledModuleByName(this.hand === RIGHT_HAND
|
var tabletStylusInput = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||||
? "RightTabletStylusInput" : "LeftTabletStylusInput");
|
? "RightTabletStylusInput" : "LeftTabletStylusInput");
|
||||||
if (tabletStylusInput) {
|
if (tabletStylusInput) {
|
||||||
|
@ -136,6 +145,7 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tablet surface.
|
||||||
var webLaser = getEnabledModuleByName(this.hand === RIGHT_HAND
|
var webLaser = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||||
? "RightWebSurfaceLaserInput" : "LeftWebSurfaceLaserInput");
|
? "RightWebSurfaceLaserInput" : "LeftWebSurfaceLaserInput");
|
||||||
if (webLaser) {
|
if (webLaser) {
|
||||||
|
@ -147,6 +157,7 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HUD overlay.
|
||||||
if (!controllerData.triggerClicks[this.hand]) { // Don't grab if trigger pressed when laser starts intersecting.
|
if (!controllerData.triggerClicks[this.hand]) { // Don't grab if trigger pressed when laser starts intersecting.
|
||||||
var hudLaser = getEnabledModuleByName(this.hand === RIGHT_HAND
|
var hudLaser = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||||
? "RightHudOverlayPointer" : "LeftHudOverlayPointer");
|
? "RightHudOverlayPointer" : "LeftHudOverlayPointer");
|
||||||
|
@ -168,6 +179,7 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Teleport.
|
||||||
var teleport = getEnabledModuleByName(this.hand === RIGHT_HAND ? "RightTeleporter" : "LeftTeleporter");
|
var teleport = getEnabledModuleByName(this.hand === RIGHT_HAND ? "RightTeleporter" : "LeftTeleporter");
|
||||||
if (teleport) {
|
if (teleport) {
|
||||||
var teleportReady = teleport.isReady(controllerData);
|
var teleportReady = teleport.isReady(controllerData);
|
||||||
|
@ -176,8 +188,6 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var stopRunning = false;
|
|
||||||
|
|
||||||
if ((controllerData.triggerClicks[this.hand] === 0 && controllerData.secondaryValues[this.hand] === 0)) {
|
if ((controllerData.triggerClicks[this.hand] === 0 && controllerData.secondaryValues[this.hand] === 0)) {
|
||||||
var stopRunning = false;
|
var stopRunning = false;
|
||||||
controllerData.nearbyOverlayIDs[this.hand].forEach(function(overlayID) {
|
controllerData.nearbyOverlayIDs[this.hand].forEach(function(overlayID) {
|
||||||
|
@ -203,6 +213,37 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
enableDispatcherModule("LeftHandInEditMode", leftHandInEditMode);
|
enableDispatcherModule("LeftHandInEditMode", leftHandInEditMode);
|
||||||
enableDispatcherModule("RightHandInEditMode", rightHandInEditMode);
|
enableDispatcherModule("RightHandInEditMode", rightHandInEditMode);
|
||||||
|
|
||||||
|
var INEDIT_STATUS_CHANNEL = "Hifi-InEdit-Status";
|
||||||
|
var HAND_RAYPICK_BLACKLIST_CHANNEL = "Hifi-Hand-RayPick-Blacklist";
|
||||||
|
this.handleMessage = function (channel, data, sender) {
|
||||||
|
if (channel === INEDIT_STATUS_CHANNEL && sender === MyAvatar.sessionUUID) {
|
||||||
|
var message;
|
||||||
|
|
||||||
|
try {
|
||||||
|
message = JSON.parse(data);
|
||||||
|
} catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (message.method) {
|
||||||
|
case "editing":
|
||||||
|
if (message.hand === LEFT_HAND) {
|
||||||
|
leftHandInEditMode.isEditing = message.editing;
|
||||||
|
} else {
|
||||||
|
rightHandInEditMode.isEditing = message.editing;
|
||||||
|
}
|
||||||
|
Messages.sendLocalMessage(HAND_RAYPICK_BLACKLIST_CHANNEL, JSON.stringify({
|
||||||
|
action: "tablet",
|
||||||
|
hand: message.hand,
|
||||||
|
blacklist: message.editing
|
||||||
|
}));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Messages.subscribe(INEDIT_STATUS_CHANNEL);
|
||||||
|
Messages.messageReceived.connect(this.handleMessage);
|
||||||
|
|
||||||
function cleanup() {
|
function cleanup() {
|
||||||
disableDispatcherModule("LeftHandInEditMode");
|
disableDispatcherModule("LeftHandInEditMode");
|
||||||
disableDispatcherModule("RightHandInEditMode");
|
disableDispatcherModule("RightHandInEditMode");
|
||||||
|
|
|
@ -18,7 +18,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
|
|
||||||
function InVREditMode(hand) {
|
function InVREditMode(hand) {
|
||||||
this.hand = hand;
|
this.hand = hand;
|
||||||
this.disableModules = false;
|
this.isAppActive = false;
|
||||||
|
this.isEditing = false;
|
||||||
this.running = false;
|
this.running = false;
|
||||||
var NO_HAND_LASER = -1; // Invalid hand parameter so that standard laser is not displayed.
|
var NO_HAND_LASER = -1; // Invalid hand parameter so that standard laser is not displayed.
|
||||||
this.parameters = makeDispatcherModuleParameters(
|
this.parameters = makeDispatcherModuleParameters(
|
||||||
|
@ -66,7 +67,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.isReady = function (controllerData) {
|
this.isReady = function (controllerData) {
|
||||||
if (this.disableModules) {
|
if (this.isAppActive) {
|
||||||
return makeRunningValues(true, [], []);
|
return makeRunningValues(true, [], []);
|
||||||
}
|
}
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
|
@ -74,14 +75,13 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
|
|
||||||
this.run = function (controllerData) {
|
this.run = function (controllerData) {
|
||||||
// Default behavior if disabling is not enabled.
|
// Default behavior if disabling is not enabled.
|
||||||
if (!this.disableModules) {
|
if (!this.isAppActive) {
|
||||||
return this.exitModule();
|
return this.exitModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tablet stylus.
|
// Tablet stylus.
|
||||||
var tabletStylusInput = getEnabledModuleByName(this.hand === RIGHT_HAND ?
|
var tabletStylusInput = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||||
"RightTabletStylusInput" :
|
? "RightTabletStylusInput" : "LeftTabletStylusInput");
|
||||||
"LeftTabletStylusInput");
|
|
||||||
if (tabletStylusInput) {
|
if (tabletStylusInput) {
|
||||||
var tabletReady = tabletStylusInput.isReady(controllerData);
|
var tabletReady = tabletStylusInput.isReady(controllerData);
|
||||||
if (tabletReady.active) {
|
if (tabletReady.active) {
|
||||||
|
@ -90,9 +90,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tablet surface.
|
// Tablet surface.
|
||||||
var overlayLaser = getEnabledModuleByName(this.hand === RIGHT_HAND ?
|
var overlayLaser = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||||
"RightWebSurfaceLaserInput" :
|
? "RightWebSurfaceLaserInput" : "LeftWebSurfaceLaserInput");
|
||||||
"LeftWebSurfaceLaserInput");
|
|
||||||
if (overlayLaser) {
|
if (overlayLaser) {
|
||||||
var overlayLaserReady = overlayLaser.isReady(controllerData);
|
var overlayLaserReady = overlayLaser.isReady(controllerData);
|
||||||
var target = controllerData.rayPicks[this.hand].objectID;
|
var target = controllerData.rayPicks[this.hand].objectID;
|
||||||
|
@ -114,8 +113,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
// HUD overlay.
|
// HUD overlay.
|
||||||
if (!controllerData.triggerClicks[this.hand]) {
|
if (!controllerData.triggerClicks[this.hand]) {
|
||||||
var hudLaser = getEnabledModuleByName(this.hand === RIGHT_HAND
|
var hudLaser = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||||
? "RightHudOverlayPointer"
|
? "RightHudOverlayPointer" : "LeftHudOverlayPointer");
|
||||||
: "LeftHudOverlayPointer");
|
|
||||||
if (hudLaser) {
|
if (hudLaser) {
|
||||||
var hudLaserReady = hudLaser.isReady(controllerData);
|
var hudLaserReady = hudLaser.isReady(controllerData);
|
||||||
if (hudLaserReady.active) {
|
if (hudLaserReady.active) {
|
||||||
|
@ -125,9 +123,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Teleport.
|
// Teleport.
|
||||||
var teleporter = getEnabledModuleByName(this.hand === RIGHT_HAND ?
|
var teleporter = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||||
"RightTeleporter" :
|
? "RightTeleporter" : "LeftTeleporter");
|
||||||
"LeftTeleporter");
|
|
||||||
if (teleporter) {
|
if (teleporter) {
|
||||||
var teleporterReady = teleporter.isReady(controllerData);
|
var teleporterReady = teleporter.isReady(controllerData);
|
||||||
if (teleporterReady.active) {
|
if (teleporterReady.active) {
|
||||||
|
@ -145,19 +142,39 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
enableDispatcherModule("LeftHandInVREditMode", leftHandInVREditMode);
|
enableDispatcherModule("LeftHandInVREditMode", leftHandInVREditMode);
|
||||||
enableDispatcherModule("RightHandInVREditMode", rightHandInVREditMode);
|
enableDispatcherModule("RightHandInVREditMode", rightHandInVREditMode);
|
||||||
|
|
||||||
var INVREDIT_DISABLER_MESSAGE_CHANNEL = "Hifi-InVREdit-Disabler";
|
var INVREDIT_STATUS_CHANNEL = "Hifi-InVREdit-Status";
|
||||||
this.handleMessage = function (channel, message, sender) {
|
var HAND_RAYPICK_BLACKLIST_CHANNEL = "Hifi-Hand-RayPick-Blacklist";
|
||||||
if (sender === MyAvatar.sessionUUID && channel === INVREDIT_DISABLER_MESSAGE_CHANNEL) {
|
this.handleMessage = function (channel, data, sender) {
|
||||||
if (message === "both") {
|
if (channel === INVREDIT_STATUS_CHANNEL && sender === MyAvatar.sessionUUID) {
|
||||||
leftHandInVREditMode.disableModules = true;
|
var message;
|
||||||
rightHandInVREditMode.disableModules = true;
|
|
||||||
} else if (message === "none") {
|
try {
|
||||||
leftHandInVREditMode.disableModules = false;
|
message = JSON.parse(data);
|
||||||
rightHandInVREditMode.disableModules = false;
|
} catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (message.method) {
|
||||||
|
case "active":
|
||||||
|
leftHandInVREditMode.isAppActive = message.active;
|
||||||
|
rightHandInVREditMode.isAppActive = message.active;
|
||||||
|
break;
|
||||||
|
case "editing":
|
||||||
|
if (message.hand === LEFT_HAND) {
|
||||||
|
leftHandInVREditMode.isEditing = message.editing;
|
||||||
|
} else {
|
||||||
|
rightHandInVREditMode.isEditing = message.editing;
|
||||||
|
}
|
||||||
|
Messages.sendLocalMessage(HAND_RAYPICK_BLACKLIST_CHANNEL, JSON.stringify({
|
||||||
|
action: "tablet",
|
||||||
|
hand: message.hand,
|
||||||
|
blacklist: message.editing
|
||||||
|
}));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Messages.subscribe(INVREDIT_DISABLER_MESSAGE_CHANNEL);
|
Messages.subscribe(INVREDIT_STATUS_CHANNEL);
|
||||||
Messages.messageReceived.connect(this.handleMessage);
|
Messages.messageReceived.connect(this.handleMessage);
|
||||||
|
|
||||||
this.cleanup = function () {
|
this.cleanup = function () {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
/* global Script, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, getControllerJointIndex,
|
/* global Script, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, getControllerJointIndex,
|
||||||
enableDispatcherModule, disableDispatcherModule, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
enableDispatcherModule, disableDispatcherModule, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
||||||
makeDispatcherModuleParameters, Overlays, makeRunningValues, Vec3, resizeTablet, getTabletWidthFromSettings,
|
makeDispatcherModuleParameters, Overlays, makeRunningValues, Vec3, resizeTablet, getTabletWidthFromSettings,
|
||||||
NEAR_GRAB_RADIUS, HMD, Uuid
|
NEAR_GRAB_RADIUS, HMD, Uuid, getEnabledModuleByName
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
|
@ -176,10 +176,23 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.isEditing = function () {
|
||||||
|
var inEditModeModule = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||||
|
? "RightHandInEditMode" : "LeftHandInEditMode");
|
||||||
|
if (inEditModeModule && inEditModeModule.isEditing) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var inVREditModeModule = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||||
|
? "RightHandInVREditMode" : "LeftHandInVREditMode");
|
||||||
|
if (inVREditModeModule && inVREditModeModule.isEditing) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
this.isReady = function (controllerData) {
|
this.isReady = function (controllerData) {
|
||||||
if ((controllerData.triggerClicks[this.hand] === 0 &&
|
if ((controllerData.triggerClicks[this.hand] === 0 && controllerData.secondaryValues[this.hand] === 0)
|
||||||
controllerData.secondaryValues[this.hand] === 0)) {
|
|| this.isEditing()) {
|
||||||
this.robbed = false;
|
this.robbed = false;
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
|
@ -202,7 +215,8 @@ Script.include("/~/system/libraries/utils.js");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.run = function (controllerData) {
|
this.run = function (controllerData) {
|
||||||
if ((controllerData.triggerClicks[this.hand] === 0 && controllerData.secondaryValues[this.hand] === 0) || !this.isGrabbedThingVisible()) {
|
if ((controllerData.triggerClicks[this.hand] === 0 && controllerData.secondaryValues[this.hand] === 0)
|
||||||
|
|| this.isEditing() || !this.isGrabbedThingVisible()) {
|
||||||
this.endNearParentingGrabOverlay();
|
this.endNearParentingGrabOverlay();
|
||||||
this.robbed = false;
|
this.robbed = false;
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
/* global LEFT_HAND, RIGHT_HAND, makeDispatcherModuleParameters, makeRunningValues, enableDispatcherModule,
|
/* global LEFT_HAND, RIGHT_HAND, makeDispatcherModuleParameters, makeRunningValues, enableDispatcherModule,
|
||||||
* disableDispatcherModule */
|
* disableDispatcherModule, getEnabledModuleByName */
|
||||||
|
|
||||||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
|
|
||||||
|
@ -66,12 +66,26 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
100
|
100
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.isEditing = function () {
|
||||||
|
var inEditModeModule = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||||
|
? "RightHandInEditMode" : "LeftHandInEditMode");
|
||||||
|
if (inEditModeModule && inEditModeModule.isEditing) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var inVREditModeModule = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||||
|
? "RightHandInVREditMode" : "LeftHandInVREditMode");
|
||||||
|
if (inVREditModeModule && inVREditModeModule.isEditing) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
this.isNearTablet = function (controllerData) {
|
this.isNearTablet = function (controllerData) {
|
||||||
return HMD.tabletID && controllerData.nearbyOverlayIDs[this.hand].indexOf(HMD.tabletID) !== -1;
|
return HMD.tabletID && controllerData.nearbyOverlayIDs[this.hand].indexOf(HMD.tabletID) !== -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.isReady = function (controllerData) {
|
this.isReady = function (controllerData) {
|
||||||
if (this.isNearTablet(controllerData)) {
|
if (!this.isEditing() && this.isNearTablet(controllerData)) {
|
||||||
return makeRunningValues(true, [], []);
|
return makeRunningValues(true, [], []);
|
||||||
}
|
}
|
||||||
setTabletNearGrabbable(this.hand, false);
|
setTabletNearGrabbable(this.hand, false);
|
||||||
|
@ -79,7 +93,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.run = function (controllerData) {
|
this.run = function (controllerData) {
|
||||||
if (!this.isNearTablet(controllerData)) {
|
if (this.isEditing() || !this.isNearTablet(controllerData)) {
|
||||||
setTabletNearGrabbable(this.hand, false);
|
setTabletNearGrabbable(this.hand, false);
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
|
|
|
@ -639,6 +639,8 @@ SelectionDisplay = (function() {
|
||||||
ROLL: 2
|
ROLL: 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const INEDIT_STATUS_CHANNEL = "Hifi-InEdit-Status";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current space mode, this could have been a forced space mode since we do not support multi selection while in
|
* The current space mode, this could have been a forced space mode since we do not support multi selection while in
|
||||||
* local space mode.
|
* local space mode.
|
||||||
|
@ -985,6 +987,7 @@ SelectionDisplay = (function() {
|
||||||
that.triggerPressMapping = Controller.newMapping(Script.resolvePath('') + '-press');
|
that.triggerPressMapping = Controller.newMapping(Script.resolvePath('') + '-press');
|
||||||
that.triggeredHand = NO_HAND;
|
that.triggeredHand = NO_HAND;
|
||||||
that.pressedHand = NO_HAND;
|
that.pressedHand = NO_HAND;
|
||||||
|
that.editingHand = NO_HAND;
|
||||||
that.triggered = function() {
|
that.triggered = function() {
|
||||||
return that.triggeredHand !== NO_HAND;
|
return that.triggeredHand !== NO_HAND;
|
||||||
};
|
};
|
||||||
|
@ -1117,6 +1120,12 @@ SelectionDisplay = (function() {
|
||||||
activeTool = hitTool;
|
activeTool = hitTool;
|
||||||
that.clearDebugPickPlane();
|
that.clearDebugPickPlane();
|
||||||
if (activeTool.onBegin) {
|
if (activeTool.onBegin) {
|
||||||
|
that.editingHand = that.triggeredHand;
|
||||||
|
Messages.sendLocalMessage(INEDIT_STATUS_CHANNEL, JSON.stringify({
|
||||||
|
method: "editing",
|
||||||
|
hand: that.editingHand === Controller.Standard.LeftHand ? LEFT_HAND : RIGHT_HAND,
|
||||||
|
editing: true
|
||||||
|
}));
|
||||||
activeTool.onBegin(event, pickRay, results);
|
activeTool.onBegin(event, pickRay, results);
|
||||||
} else {
|
} else {
|
||||||
print("ERROR: entitySelectionTool.mousePressEvent - ActiveTool(" + activeTool.mode + ") missing onBegin");
|
print("ERROR: entitySelectionTool.mousePressEvent - ActiveTool(" + activeTool.mode + ") missing onBegin");
|
||||||
|
@ -1265,6 +1274,12 @@ SelectionDisplay = (function() {
|
||||||
if (wantDebug) {
|
if (wantDebug) {
|
||||||
print(" Triggering ActiveTool(" + activeTool.mode + ")'s onEnd");
|
print(" Triggering ActiveTool(" + activeTool.mode + ")'s onEnd");
|
||||||
}
|
}
|
||||||
|
Messages.sendLocalMessage(INEDIT_STATUS_CHANNEL, JSON.stringify({
|
||||||
|
method: "editing",
|
||||||
|
hand: that.editingHand === Controller.Standard.LeftHand ? LEFT_HAND : RIGHT_HAND,
|
||||||
|
editing: false
|
||||||
|
}));
|
||||||
|
that.editingHand = NO_HAND;
|
||||||
activeTool.onEnd(event);
|
activeTool.onEnd(event);
|
||||||
} else if (wantDebug) {
|
} else if (wantDebug) {
|
||||||
print(" ActiveTool(" + activeTool.mode + ")'s missing onEnd");
|
print(" ActiveTool(" + activeTool.mode + ")'s missing onEnd");
|
||||||
|
|
|
@ -251,11 +251,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getUIPositionAndRotation(hand) {
|
function getUIPosition(hand) {
|
||||||
return {
|
return MINI_POSITIONS[hand];
|
||||||
position: MINI_POSITIONS[hand],
|
|
||||||
rotation: MINI_ROTATIONS[hand]
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMiniTabletID() {
|
function getMiniTabletID() {
|
||||||
|
@ -493,7 +490,7 @@
|
||||||
create();
|
create();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getUIPositionAndRotation: getUIPositionAndRotation,
|
getUIPosition: getUIPosition,
|
||||||
getMiniTabletID: getMiniTabletID,
|
getMiniTabletID: getMiniTabletID,
|
||||||
getMiniTabletProperties: getMiniTabletProperties,
|
getMiniTabletProperties: getMiniTabletProperties,
|
||||||
isLaserPointingAt: isLaserPointingAt,
|
isLaserPointingAt: isLaserPointingAt,
|
||||||
|
@ -552,14 +549,23 @@
|
||||||
// Trigger values.
|
// Trigger values.
|
||||||
leftTriggerOn = 0,
|
leftTriggerOn = 0,
|
||||||
rightTriggerOn = 0,
|
rightTriggerOn = 0,
|
||||||
MAX_TRIGGER_ON_TIME = 100,
|
MAX_TRIGGER_ON_TIME = 400,
|
||||||
|
|
||||||
// Visibility.
|
// Visibility.
|
||||||
MAX_HAND_CAMERA_ANGLE = 30,
|
MAX_MEDIAL_FINGER_CAMERA_ANGLE = 25, // From palm normal along palm towards fingers.
|
||||||
MAX_CAMERA_HAND_ANGLE = 30,
|
MAX_MEDIAL_WRIST_CAMERA_ANGLE = 65, // From palm normal along palm towards wrist.
|
||||||
|
MAX_LATERAL_THUMB_CAMERA_ANGLE = 25, // From palm normal across palm towards of thumb.
|
||||||
|
MAX_LATERAL_PINKY_CAMERA_ANGLE = 25, // From palm normal across palm towards pinky.
|
||||||
DEGREES_180 = 180,
|
DEGREES_180 = 180,
|
||||||
MAX_HAND_CAMERA_ANGLE_COS = Math.cos(Math.PI * MAX_HAND_CAMERA_ANGLE / DEGREES_180),
|
DEGREES_TO_RADIANS = Math.PI / DEGREES_180,
|
||||||
MAX_CAMERA_HAND_ANGLE_COS = Math.cos(Math.PI * MAX_CAMERA_HAND_ANGLE / DEGREES_180),
|
MAX_MEDIAL_FINGER_CAMERA_ANGLE_RAD = DEGREES_TO_RADIANS * MAX_MEDIAL_FINGER_CAMERA_ANGLE,
|
||||||
|
MAX_MEDIAL_WRIST_CAMERA_ANGLE_RAD = DEGREES_TO_RADIANS * MAX_MEDIAL_WRIST_CAMERA_ANGLE,
|
||||||
|
MAX_LATERAL_THUMB_CAMERA_ANGLE_RAD = DEGREES_TO_RADIANS * MAX_LATERAL_THUMB_CAMERA_ANGLE,
|
||||||
|
MAX_LATERAL_PINKY_CAMERA_ANGLE_RAD = DEGREES_TO_RADIANS * MAX_LATERAL_PINKY_CAMERA_ANGLE,
|
||||||
|
MAX_CAMERA_MINI_ANGLE = 30,
|
||||||
|
MAX_CAMERA_MINI_ANGLE_COS = Math.cos(MAX_CAMERA_MINI_ANGLE * DEGREES_TO_RADIANS),
|
||||||
|
SHOWING_DELAY = 1000, // ms
|
||||||
|
lastInvisible = [0, 0],
|
||||||
HIDING_DELAY = 1000, // ms
|
HIDING_DELAY = 1000, // ms
|
||||||
lastVisible = [0, 0];
|
lastVisible = [0, 0];
|
||||||
|
|
||||||
|
@ -598,11 +604,18 @@
|
||||||
jointIndex,
|
jointIndex,
|
||||||
handPosition,
|
handPosition,
|
||||||
handOrientation,
|
handOrientation,
|
||||||
uiPositionAndOrientation,
|
|
||||||
miniPosition,
|
miniPosition,
|
||||||
miniOrientation,
|
|
||||||
miniToCameraDirection,
|
miniToCameraDirection,
|
||||||
cameraToHand;
|
normalHandVector,
|
||||||
|
medialHandVector,
|
||||||
|
lateralHandVector,
|
||||||
|
normalDot,
|
||||||
|
medialDot,
|
||||||
|
lateralDot,
|
||||||
|
medialAngle,
|
||||||
|
lateralAngle,
|
||||||
|
cameraToMini,
|
||||||
|
now;
|
||||||
|
|
||||||
// Shouldn't show mini tablet if hand isn't being controlled.
|
// Shouldn't show mini tablet if hand isn't being controlled.
|
||||||
pose = Controller.getPoseValue(hand === LEFT_HAND ? Controller.Standard.LeftHand : Controller.Standard.RightHand);
|
pose = Controller.getPoseValue(hand === LEFT_HAND ? Controller.Standard.LeftHand : Controller.Standard.RightHand);
|
||||||
|
@ -647,27 +660,48 @@
|
||||||
Vec3.multiplyQbyV(MyAvatar.orientation, MyAvatar.getAbsoluteJointTranslationInObjectFrame(jointIndex)));
|
Vec3.multiplyQbyV(MyAvatar.orientation, MyAvatar.getAbsoluteJointTranslationInObjectFrame(jointIndex)));
|
||||||
handOrientation =
|
handOrientation =
|
||||||
Quat.multiply(MyAvatar.orientation, MyAvatar.getAbsoluteJointRotationInObjectFrame(jointIndex));
|
Quat.multiply(MyAvatar.orientation, MyAvatar.getAbsoluteJointRotationInObjectFrame(jointIndex));
|
||||||
uiPositionAndOrientation = ui.getUIPositionAndRotation(hand);
|
var uiPosition = ui.getUIPosition(hand);
|
||||||
miniPosition = Vec3.sum(handPosition, Vec3.multiply(MyAvatar.sensorToWorldScale,
|
miniPosition = Vec3.sum(handPosition, Vec3.multiply(MyAvatar.sensorToWorldScale,
|
||||||
Vec3.multiplyQbyV(handOrientation, uiPositionAndOrientation.position)));
|
Vec3.multiplyQbyV(handOrientation, uiPosition)));
|
||||||
miniOrientation = Quat.multiply(handOrientation, uiPositionAndOrientation.rotation);
|
|
||||||
miniToCameraDirection = Vec3.normalize(Vec3.subtract(Camera.position, miniPosition));
|
miniToCameraDirection = Vec3.normalize(Vec3.subtract(Camera.position, miniPosition));
|
||||||
show = Vec3.dot(miniToCameraDirection, Quat.getForward(miniOrientation)) > MAX_HAND_CAMERA_ANGLE_COS;
|
|
||||||
show = show || (-Vec3.dot(miniToCameraDirection, Quat.getForward(handOrientation)) > MAX_HAND_CAMERA_ANGLE_COS);
|
// Mini tablet aimed toward camera?
|
||||||
cameraToHand = -Vec3.dot(miniToCameraDirection, Quat.getForward(Camera.orientation));
|
medialHandVector = Vec3.multiplyQbyV(handOrientation, Vec3.UNIT_Y);
|
||||||
show = show && (cameraToHand > MAX_CAMERA_HAND_ANGLE_COS);
|
lateralHandVector = Vec3.multiplyQbyV(handOrientation, hand === LEFT_HAND ? Vec3.UNIT_X : Vec3.UNIT_NEG_X);
|
||||||
|
normalHandVector = Vec3.multiplyQbyV(handOrientation, Vec3.UNIT_Z);
|
||||||
|
medialDot = Vec3.dot(medialHandVector, miniToCameraDirection);
|
||||||
|
lateralDot = Vec3.dot(lateralHandVector, miniToCameraDirection);
|
||||||
|
normalDot = Vec3.dot(normalHandVector, miniToCameraDirection);
|
||||||
|
medialAngle = Math.atan2(medialDot, normalDot);
|
||||||
|
lateralAngle = Math.atan2(lateralDot, normalDot);
|
||||||
|
show = -MAX_MEDIAL_WRIST_CAMERA_ANGLE_RAD <= medialAngle
|
||||||
|
&& medialAngle <= MAX_MEDIAL_FINGER_CAMERA_ANGLE_RAD
|
||||||
|
&& -MAX_LATERAL_THUMB_CAMERA_ANGLE_RAD <= lateralAngle
|
||||||
|
&& lateralAngle <= MAX_LATERAL_PINKY_CAMERA_ANGLE_RAD;
|
||||||
|
|
||||||
|
// Camera looking at mini tablet?
|
||||||
|
cameraToMini = -Vec3.dot(miniToCameraDirection, Quat.getForward(Camera.orientation));
|
||||||
|
show = show && (cameraToMini > MAX_CAMERA_MINI_ANGLE_COS);
|
||||||
|
|
||||||
|
// Delay showing for a while after it would otherwise be shown, unless it was showing on the other hand.
|
||||||
|
now = Date.now();
|
||||||
|
if (show) {
|
||||||
|
show = now - lastInvisible[hand] >= SHOWING_DELAY || now - lastVisible[otherHand(hand)] <= HIDING_DELAY;
|
||||||
|
} else {
|
||||||
|
lastInvisible[hand] = now;
|
||||||
|
}
|
||||||
|
|
||||||
// Persist showing for a while after it would otherwise be hidden.
|
// Persist showing for a while after it would otherwise be hidden.
|
||||||
if (show) {
|
if (show) {
|
||||||
lastVisible[hand] = Date.now();
|
lastVisible[hand] = now;
|
||||||
} else {
|
} else {
|
||||||
show = Date.now() - lastVisible[hand] <= HIDING_DELAY;
|
show = now - lastVisible[hand] <= HIDING_DELAY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
show: show,
|
show: show,
|
||||||
cameraToHand: cameraToHand
|
cameraToMini: cameraToMini
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,7 +724,7 @@
|
||||||
showRight = shouldShowMini(RIGHT_HAND);
|
showRight = shouldShowMini(RIGHT_HAND);
|
||||||
if (showLeft.show && showRight.show) {
|
if (showLeft.show && showRight.show) {
|
||||||
// Both hands would be pointing at camera; show the one the camera is gazing at.
|
// Both hands would be pointing at camera; show the one the camera is gazing at.
|
||||||
if (showLeft.cameraToHand > showRight.cameraToHand) {
|
if (showLeft.cameraToMini > showRight.cameraToMini) {
|
||||||
setState(MINI_SHOWING, LEFT_HAND);
|
setState(MINI_SHOWING, LEFT_HAND);
|
||||||
} else {
|
} else {
|
||||||
setState(MINI_SHOWING, RIGHT_HAND);
|
setState(MINI_SHOWING, RIGHT_HAND);
|
||||||
|
@ -752,7 +786,7 @@
|
||||||
showLeft = shouldShowMini(LEFT_HAND);
|
showLeft = shouldShowMini(LEFT_HAND);
|
||||||
showRight = shouldShowMini(RIGHT_HAND);
|
showRight = shouldShowMini(RIGHT_HAND);
|
||||||
if (showLeft.show && showRight.show) {
|
if (showLeft.show && showRight.show) {
|
||||||
if (showLeft.cameraToHand > showRight.cameraToHand) {
|
if (showLeft.cameraToMini > showRight.cameraToMini) {
|
||||||
if (miniHand !== LEFT_HAND) {
|
if (miniHand !== LEFT_HAND) {
|
||||||
setState(MINI_HIDING);
|
setState(MINI_HIDING);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue