mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Merge pull request #8735 from huffman/feat/teleport-improvements
Update teleport.js to ignore invisible or collisionless objects and disallow teleporting to certain surfaces
This commit is contained in:
commit
ed2571704f
12 changed files with 130 additions and 72 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -45,7 +45,7 @@ gvr-interface/libs/*
|
|||
|
||||
# ignore files for various dev environments
|
||||
TAGS
|
||||
*.swp
|
||||
*.sw[po]
|
||||
|
||||
# ignore node files for the console
|
||||
node_modules
|
||||
|
|
|
@ -591,17 +591,17 @@ void EntityTreeRenderer::deleteReleasedModels() {
|
|||
|
||||
RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
||||
bool precisionPicking, const QVector<EntityItemID>& entityIdsToInclude,
|
||||
const QVector<EntityItemID>& entityIdsToDiscard) {
|
||||
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly) {
|
||||
RayToEntityIntersectionResult result;
|
||||
if (_tree) {
|
||||
EntityTreePointer entityTree = std::static_pointer_cast<EntityTree>(_tree);
|
||||
|
||||
OctreeElementPointer element;
|
||||
EntityItemPointer intersectedEntity = NULL;
|
||||
result.intersects = entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance,
|
||||
result.face, result.surfaceNormal, entityIdsToInclude, entityIdsToDiscard,
|
||||
(void**)&intersectedEntity, lockType, &result.accurate,
|
||||
precisionPicking);
|
||||
result.intersects = entityTree->findRayIntersection(ray.origin, ray.direction,
|
||||
entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly, precisionPicking,
|
||||
element, result.distance, result.face, result.surfaceNormal,
|
||||
(void**)&intersectedEntity, lockType, &result.accurate);
|
||||
if (result.intersects && intersectedEntity) {
|
||||
result.entityID = intersectedEntity->getEntityItemID();
|
||||
result.properties = intersectedEntity->getProperties();
|
||||
|
|
|
@ -149,7 +149,8 @@ private:
|
|||
QList<ModelPointer> _releasedModels;
|
||||
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
||||
bool precisionPicking, const QVector<EntityItemID>& entityIdsToInclude = QVector<EntityItemID>(),
|
||||
const QVector<EntityItemID>& entityIdsToDiscard = QVector<EntityItemID>());
|
||||
const QVector<EntityItemID>& entityIdsToDiscard = QVector<EntityItemID>(), bool visibleOnly=false,
|
||||
bool collidableOnly = false);
|
||||
|
||||
EntityItemID _currentHoverOverEntityID;
|
||||
EntityItemID _currentClickingOnEntityID;
|
||||
|
|
|
@ -624,11 +624,11 @@ QVector<QUuid> EntityScriptingInterface::findEntitiesInFrustum(QVariantMap frust
|
|||
}
|
||||
|
||||
RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray, bool precisionPicking,
|
||||
const QScriptValue& entityIdsToInclude, const QScriptValue& entityIdsToDiscard) {
|
||||
const QScriptValue& entityIdsToInclude, const QScriptValue& entityIdsToDiscard, bool visibleOnly, bool collidableOnly) {
|
||||
|
||||
QVector<EntityItemID> entitiesToInclude = qVectorEntityItemIDFromScriptValue(entityIdsToInclude);
|
||||
QVector<EntityItemID> entitiesToDiscard = qVectorEntityItemIDFromScriptValue(entityIdsToDiscard);
|
||||
return findRayIntersectionWorker(ray, Octree::Lock, precisionPicking, entitiesToInclude, entitiesToDiscard);
|
||||
return findRayIntersectionWorker(ray, Octree::Lock, precisionPicking, entitiesToInclude, entitiesToDiscard, visibleOnly, collidableOnly);
|
||||
}
|
||||
|
||||
// FIXME - we should remove this API and encourage all users to use findRayIntersection() instead. We've changed
|
||||
|
@ -643,17 +643,18 @@ RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionBlock
|
|||
}
|
||||
|
||||
RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionWorker(const PickRay& ray,
|
||||
Octree::lockType lockType,
|
||||
bool precisionPicking, const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIdsToDiscard) {
|
||||
Octree::lockType lockType, bool precisionPicking, const QVector<EntityItemID>& entityIdsToInclude,
|
||||
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly) {
|
||||
|
||||
|
||||
RayToEntityIntersectionResult result;
|
||||
if (_entityTree) {
|
||||
OctreeElementPointer element;
|
||||
EntityItemPointer intersectedEntity = NULL;
|
||||
result.intersects = _entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
|
||||
result.surfaceNormal, entityIdsToInclude, entityIdsToDiscard, (void**)&intersectedEntity, lockType, &result.accurate,
|
||||
precisionPicking);
|
||||
result.intersects = _entityTree->findRayIntersection(ray.origin, ray.direction,
|
||||
entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly, precisionPicking,
|
||||
element, result.distance, result.face, result.surfaceNormal,
|
||||
(void**)&intersectedEntity, lockType, &result.accurate);
|
||||
if (result.intersects && intersectedEntity) {
|
||||
result.entityID = intersectedEntity->getEntityItemID();
|
||||
result.properties = intersectedEntity->getProperties();
|
||||
|
|
|
@ -143,7 +143,9 @@ public slots:
|
|||
/// If the scripting context has visible entities, this will determine a ray intersection, the results
|
||||
/// may be inaccurate if the engine is unable to access the visible entities, in which case result.accurate
|
||||
/// will be false.
|
||||
Q_INVOKABLE RayToEntityIntersectionResult findRayIntersection(const PickRay& ray, bool precisionPicking = false, const QScriptValue& entityIdsToInclude = QScriptValue(), const QScriptValue& entityIdsToDiscard = QScriptValue());
|
||||
Q_INVOKABLE RayToEntityIntersectionResult findRayIntersection(const PickRay& ray, bool precisionPicking = false,
|
||||
const QScriptValue& entityIdsToInclude = QScriptValue(), const QScriptValue& entityIdsToDiscard = QScriptValue(),
|
||||
bool visibleOnly = false, bool collidableOnly = false);
|
||||
|
||||
/// If the scripting context has visible entities, this will determine a ray intersection, and will block in
|
||||
/// order to return an accurate result
|
||||
|
@ -257,7 +259,8 @@ private:
|
|||
|
||||
/// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode
|
||||
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
||||
bool precisionPicking, const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIdsToDiscard);
|
||||
bool precisionPicking, const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIdsToDiscard,
|
||||
bool visibleOnly = false, bool collidableOnly = false);
|
||||
|
||||
EntityTreePointer _entityTree;
|
||||
|
||||
|
|
|
@ -29,6 +29,28 @@ static const quint64 DELETED_ENTITIES_EXTRA_USECS_TO_CONSIDER = USECS_PER_MSEC *
|
|||
const float EntityTree::DEFAULT_MAX_TMP_ENTITY_LIFETIME = 60 * 60; // 1 hour
|
||||
|
||||
|
||||
// combines the ray cast arguments into a single object
|
||||
class RayArgs {
|
||||
public:
|
||||
// Inputs
|
||||
glm::vec3 origin;
|
||||
glm::vec3 direction;
|
||||
const QVector<EntityItemID>& entityIdsToInclude;
|
||||
const QVector<EntityItemID>& entityIdsToDiscard;
|
||||
bool visibleOnly;
|
||||
bool collidableOnly;
|
||||
bool precisionPicking;
|
||||
|
||||
// Outputs
|
||||
OctreeElementPointer& element;
|
||||
float& distance;
|
||||
BoxFace& face;
|
||||
glm::vec3& surfaceNormal;
|
||||
void** intersectedObject;
|
||||
bool found;
|
||||
};
|
||||
|
||||
|
||||
EntityTree::EntityTree(bool shouldReaverage) :
|
||||
Octree(shouldReaverage),
|
||||
_fbxService(NULL),
|
||||
|
@ -538,40 +560,28 @@ bool EntityTree::findNearPointOperation(OctreeElementPointer element, void* extr
|
|||
// if this element doesn't contain the point, then none of its children can contain the point, so stop searching
|
||||
return false;
|
||||
}
|
||||
// combines the ray cast arguments into a single object
|
||||
class RayArgs {
|
||||
public:
|
||||
glm::vec3 origin;
|
||||
glm::vec3 direction;
|
||||
OctreeElementPointer& element;
|
||||
float& distance;
|
||||
BoxFace& face;
|
||||
glm::vec3& surfaceNormal;
|
||||
const QVector<EntityItemID>& entityIdsToInclude;
|
||||
const QVector<EntityItemID>& entityIdsToDiscard;
|
||||
void** intersectedObject;
|
||||
bool found;
|
||||
bool precisionPicking;
|
||||
};
|
||||
|
||||
|
||||
bool findRayIntersectionOp(OctreeElementPointer element, void* extraData) {
|
||||
RayArgs* args = static_cast<RayArgs*>(extraData);
|
||||
bool keepSearching = true;
|
||||
EntityTreeElementPointer entityTreeElementPointer = std::dynamic_pointer_cast<EntityTreeElement>(element);
|
||||
if (entityTreeElementPointer ->findRayIntersection(args->origin, args->direction, keepSearching,
|
||||
if (entityTreeElementPointer->findRayIntersection(args->origin, args->direction, keepSearching,
|
||||
args->element, args->distance, args->face, args->surfaceNormal, args->entityIdsToInclude,
|
||||
args->entityIdsToDiscard, args->intersectedObject, args->precisionPicking)) {
|
||||
args->entityIdsToDiscard, args->visibleOnly, args->collidableOnly, args->intersectedObject, args->precisionPicking)) {
|
||||
args->found = true;
|
||||
}
|
||||
return keepSearching;
|
||||
}
|
||||
|
||||
bool EntityTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
OctreeElementPointer& element, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIdsToDiscard, void** intersectedObject,
|
||||
Octree::lockType lockType, bool* accurateResult, bool precisionPicking) {
|
||||
RayArgs args = { origin, direction, element, distance, face, surfaceNormal, entityIdsToInclude, entityIdsToDiscard, intersectedObject, false, precisionPicking };
|
||||
QVector<EntityItemID> entityIdsToInclude, QVector<EntityItemID> entityIdsToDiscard,
|
||||
bool visibleOnly, bool collidableOnly, bool precisionPicking,
|
||||
OctreeElementPointer& element, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal, void** intersectedObject,
|
||||
Octree::lockType lockType, bool* accurateResult) {
|
||||
RayArgs args = { origin, direction, entityIdsToInclude, entityIdsToDiscard,
|
||||
visibleOnly, collidableOnly, precisionPicking,
|
||||
element, distance, face, surfaceNormal, intersectedObject, false };
|
||||
distance = FLT_MAX;
|
||||
|
||||
bool requireLock = lockType == Octree::Lock;
|
||||
|
|
|
@ -31,6 +31,7 @@ using ModelWeakPointer = std::weak_ptr<Model>;
|
|||
|
||||
class EntitySimulation;
|
||||
|
||||
|
||||
class NewlyCreatedEntityHook {
|
||||
public:
|
||||
virtual void entityCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode) = 0;
|
||||
|
@ -89,13 +90,11 @@ public:
|
|||
const SharedNodePointer& senderNode) override;
|
||||
|
||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
OctreeElementPointer& node, float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
||||
const QVector<EntityItemID>& entityIdsToInclude = QVector<EntityItemID>(),
|
||||
const QVector<EntityItemID>& entityIdsToDiscard = QVector<EntityItemID>(),
|
||||
void** intersectedObject = NULL,
|
||||
Octree::lockType lockType = Octree::TryLock,
|
||||
bool* accurateResult = NULL,
|
||||
bool precisionPicking = false);
|
||||
QVector<EntityItemID> entityIdsToInclude, QVector<EntityItemID> entityIdsToDiscard,
|
||||
bool visibleOnly, bool collidableOnly, bool precisionPicking,
|
||||
OctreeElementPointer& node, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal, void** intersectedObject = NULL,
|
||||
Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
|
||||
|
||||
virtual bool rootElementHasData() const override { return true; }
|
||||
|
||||
|
|
|
@ -534,7 +534,8 @@ bool EntityTreeElement::bestFitBounds(const glm::vec3& minPoint, const glm::vec3
|
|||
bool EntityTreeElement::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude,
|
||||
const QVector<EntityItemID>& entityIdsToDiscard, void** intersectedObject, bool precisionPicking) {
|
||||
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly,
|
||||
void** intersectedObject, bool precisionPicking) {
|
||||
|
||||
keepSearching = true; // assume that we will continue searching after this.
|
||||
|
||||
|
@ -559,7 +560,8 @@ bool EntityTreeElement::findRayIntersection(const glm::vec3& origin, const glm::
|
|||
if (_cube.contains(origin) || distanceToElementCube < distance) {
|
||||
|
||||
if (findDetailedRayIntersection(origin, direction, keepSearching, element, distanceToElementDetails,
|
||||
face, localSurfaceNormal, entityIdsToInclude, entityIdsToDiscard, intersectedObject, precisionPicking, distanceToElementCube)) {
|
||||
face, localSurfaceNormal, entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly,
|
||||
intersectedObject, precisionPicking, distanceToElementCube)) {
|
||||
|
||||
if (distanceToElementDetails < distance) {
|
||||
distance = distanceToElementDetails;
|
||||
|
@ -574,13 +576,16 @@ bool EntityTreeElement::findRayIntersection(const glm::vec3& origin, const glm::
|
|||
|
||||
bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching,
|
||||
OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
||||
const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIDsToDiscard, void** intersectedObject, bool precisionPicking, float distanceToElementCube) {
|
||||
const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIDsToDiscard,
|
||||
bool visibleOnly, bool collidableOnly, void** intersectedObject, bool precisionPicking, float distanceToElementCube) {
|
||||
|
||||
// only called if we do intersect our bounding cube, but find if we actually intersect with entities...
|
||||
int entityNumber = 0;
|
||||
bool somethingIntersected = false;
|
||||
forEachEntity([&](EntityItemPointer entity) {
|
||||
if ( (entityIdsToInclude.size() > 0 && !entityIdsToInclude.contains(entity->getID())) || (entityIDsToDiscard.size() > 0 && entityIDsToDiscard.contains(entity->getID())) ) {
|
||||
if ( (visibleOnly && !entity->isVisible()) || (collidableOnly && (entity->getCollisionless() || entity->getShapeType() == SHAPE_TYPE_NONE))
|
||||
|| (entityIdsToInclude.size() > 0 && !entityIdsToInclude.contains(entity->getID()))
|
||||
|| (entityIDsToDiscard.size() > 0 && entityIDsToDiscard.contains(entity->getID())) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -638,7 +643,7 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
|
|||
if (localDistance < distance && entity->getType() != EntityTypes::ParticleEffect) {
|
||||
distance = localDistance;
|
||||
face = localFace;
|
||||
surfaceNormal = localSurfaceNormal;
|
||||
surfaceNormal = glm::vec3(rotation * glm::vec4(localSurfaceNormal, 1.0f));
|
||||
*intersectedObject = (void*)entity.get();
|
||||
somethingIntersected = true;
|
||||
}
|
||||
|
|
|
@ -147,12 +147,12 @@ public:
|
|||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElementPointer& node, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude,
|
||||
const QVector<EntityItemID>& entityIdsToDiscard,
|
||||
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly = false, bool collidableOnly = false,
|
||||
void** intersectedObject = NULL, bool precisionPicking = false);
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude,
|
||||
const QVector<EntityItemID>& entityIdsToDiscard,
|
||||
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly,
|
||||
void** intersectedObject, bool precisionPicking, float distanceToElementCube);
|
||||
virtual bool findSpherePenetration(const glm::vec3& center, float radius,
|
||||
glm::vec3& penetration, void** penetratedObject) const override;
|
||||
|
|
|
@ -142,6 +142,7 @@ function ifAvatarMovedGoActive() {
|
|||
}
|
||||
|
||||
// MAIN CONTROL
|
||||
var isEnabled = true;
|
||||
var wasMuted, isAway;
|
||||
var wasOverlaysVisible = Menu.isOptionChecked("Overlays");
|
||||
var eventMappingName = "io.highfidelity.away"; // goActive on hand controller button events, too.
|
||||
|
@ -159,7 +160,7 @@ function safeGetHMDMounted() {
|
|||
var wasHmdMounted = safeGetHMDMounted();
|
||||
|
||||
function goAway() {
|
||||
if (isAway) {
|
||||
if (!isEnabled || isAway) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -274,6 +275,24 @@ function maybeGoAway() {
|
|||
}
|
||||
}
|
||||
|
||||
function setEnabled(value) {
|
||||
print("setting away enabled: ", value);
|
||||
if (!value) {
|
||||
goActive();
|
||||
}
|
||||
isEnabled = value;
|
||||
}
|
||||
|
||||
var CHANNEL_AWAY_ENABLE = "Hifi-Away-Enable";
|
||||
var handleMessage = function(channel, message, sender) {
|
||||
print("Got away message");
|
||||
if (channel == CHANNEL_AWAY_ENABLE) {
|
||||
setEnabled(message == 'enable');
|
||||
}
|
||||
}
|
||||
Messages.subscribe(CHANNEL_AWAY_ENABLE);
|
||||
Messages.messageReceived.connect(handleMessage);
|
||||
|
||||
Script.update.connect(maybeMoveOverlay);
|
||||
|
||||
Script.update.connect(maybeGoAway);
|
||||
|
|
|
@ -344,7 +344,7 @@ function entityHasActions(entityID) {
|
|||
}
|
||||
|
||||
function findRayIntersection(pickRay, precise, include, exclude) {
|
||||
var entities = Entities.findRayIntersection(pickRay, precise, include, exclude);
|
||||
var entities = Entities.findRayIntersection(pickRay, precise, include, exclude, true);
|
||||
var overlays = Overlays.findRayIntersection(pickRay);
|
||||
if (!overlays.intersects || (entities.intersects && (entities.distance <= overlays.distance))) {
|
||||
return entities;
|
||||
|
@ -1158,9 +1158,9 @@ function MyController(hand) {
|
|||
|
||||
var intersection;
|
||||
if (USE_BLACKLIST === true && blacklist.length !== 0) {
|
||||
intersection = findRayIntersection(pickRay, true, [], blacklist);
|
||||
intersection = findRayIntersection(pickRay, true, [], blacklist, true);
|
||||
} else {
|
||||
intersection = findRayIntersection(pickRay, true);
|
||||
intersection = findRayIntersection(pickRay, true, [], [], true);
|
||||
}
|
||||
|
||||
if (intersection.intersects) {
|
||||
|
@ -1608,7 +1608,6 @@ function MyController(hand) {
|
|||
};
|
||||
|
||||
this.distanceHoldingEnter = function() {
|
||||
Messages.sendLocalMessage('Hifi-Teleport-Disabler', 'both');
|
||||
this.clearEquipHaptics();
|
||||
this.grabPointSphereOff();
|
||||
|
||||
|
@ -1872,12 +1871,6 @@ function MyController(hand) {
|
|||
};
|
||||
|
||||
this.nearGrabbingEnter = function() {
|
||||
if (this.hand === 0) {
|
||||
Messages.sendLocalMessage('Hifi-Teleport-Disabler', 'left');
|
||||
}
|
||||
if (this.hand === 1) {
|
||||
Messages.sendLocalMessage('Hifi-Teleport-Disabler', 'right');
|
||||
}
|
||||
this.grabPointSphereOff();
|
||||
this.lineOff();
|
||||
this.overlayLineOff();
|
||||
|
@ -2215,7 +2208,7 @@ function MyController(hand) {
|
|||
|
||||
var now = Date.now();
|
||||
if (now - this.lastPickTime > MSECS_PER_SEC / PICKS_PER_SECOND_PER_HAND) {
|
||||
var intersection = findRayIntersection(pickRay, true);
|
||||
var intersection = findRayIntersection(pickRay, true, [], [], true);
|
||||
if (intersection.accurate || intersection.overlayID) {
|
||||
this.lastPickTime = now;
|
||||
if (intersection.entityID != this.grabbedEntity) {
|
||||
|
@ -2343,7 +2336,6 @@ function MyController(hand) {
|
|||
};
|
||||
|
||||
this.release = function() {
|
||||
Messages.sendLocalMessage('Hifi-Teleport-Disabler', 'none');
|
||||
this.turnOffVisualizations();
|
||||
|
||||
var noVelocity = false;
|
||||
|
@ -2714,6 +2706,20 @@ var handleHandMessages = function(channel, message, sender) {
|
|||
}
|
||||
handToDisable = message;
|
||||
}
|
||||
} else if (channel === 'Hifi-Grab-Disable') {
|
||||
data = JSON.parse(message);
|
||||
if (data.holdEnabled !== undefined) {
|
||||
print("holdEnabled: ", data.holdEnabled);
|
||||
holdEnabled = data.holdEnabled;
|
||||
}
|
||||
if (data.nearGrabEnabled !== undefined) {
|
||||
print("nearGrabEnabled: ", data.nearGrabEnabled);
|
||||
nearGrabEnabled = data.nearGrabEnabled;
|
||||
}
|
||||
if (data.farGrabEnabled !== undefined) {
|
||||
print("farGrabEnabled: ", data.farGrabEnabled);
|
||||
farGrabEnabled = data.farGrabEnabled;
|
||||
}
|
||||
} else if (channel === 'Hifi-Hand-Grab') {
|
||||
try {
|
||||
data = JSON.parse(message);
|
||||
|
|
|
@ -279,7 +279,7 @@ function Teleporter() {
|
|||
var location = Vec3.sum(rightPickRay.origin, Vec3.multiply(rightPickRay.direction, 50));
|
||||
|
||||
|
||||
var rightIntersection = Entities.findRayIntersection(teleporter.rightPickRay, true, [], [this.targetEntity]);
|
||||
var rightIntersection = Entities.findRayIntersection(teleporter.rightPickRay, true, [], [this.targetEntity], true, true);
|
||||
|
||||
if (rightIntersection.intersects) {
|
||||
if (this.tooClose === true) {
|
||||
|
@ -342,7 +342,7 @@ function Teleporter() {
|
|||
var location = Vec3.sum(MyAvatar.position, Vec3.multiply(leftPickRay.direction, 50));
|
||||
|
||||
|
||||
var leftIntersection = Entities.findRayIntersection(teleporter.leftPickRay, true, [], [this.targetEntity]);
|
||||
var leftIntersection = Entities.findRayIntersection(teleporter.leftPickRay, true, [], [this.targetEntity], true, true);
|
||||
|
||||
if (leftIntersection.intersects) {
|
||||
|
||||
|
@ -459,7 +459,7 @@ function Teleporter() {
|
|||
z: intersection.intersection.z
|
||||
};
|
||||
|
||||
this.tooClose = isTooCloseToTeleport(position);
|
||||
this.tooClose = isValidTeleportLocation(position, intersection.surfaceNormal);
|
||||
var towardUs = Quat.fromPitchYawRollDegrees(0, euler.y, 0);
|
||||
|
||||
Overlays.editOverlay(this.targetOverlay, {
|
||||
|
@ -480,7 +480,7 @@ function Teleporter() {
|
|||
z: intersection.intersection.z
|
||||
};
|
||||
|
||||
this.tooClose = isTooCloseToTeleport(position);
|
||||
this.tooClose = isValidTeleportLocation(position, intersection.surfaceNormal);
|
||||
var towardUs = Quat.fromPitchYawRollDegrees(0, euler.y, 0);
|
||||
|
||||
Overlays.editOverlay(this.cancelOverlay, {
|
||||
|
@ -509,7 +509,12 @@ function Teleporter() {
|
|||
var offset = getAvatarFootOffset();
|
||||
this.intersection.intersection.y += offset;
|
||||
this.exitTeleportMode();
|
||||
this.smoothArrival();
|
||||
// Disable smooth arrival, possibly temporarily
|
||||
//this.smoothArrival();
|
||||
MyAvatar.position = _this.intersection.intersection;
|
||||
_this.deleteTargetOverlay();
|
||||
_this.deleteCancelOverlay();
|
||||
HMD.centerUI();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -627,8 +632,17 @@ function isMoving() {
|
|||
}
|
||||
};
|
||||
|
||||
function isTooCloseToTeleport(position) {
|
||||
return Vec3.distance(MyAvatar.position, position) <= TELEPORT_CANCEL_RANGE;
|
||||
// When determininig whether you can teleport to a location, the normal of the
|
||||
// point that is being intersected with is looked at. If this normal is more
|
||||
// than MAX_ANGLE_FROM_UP_TO_TELEPORT degrees from <0, 1, 0> (straight up), then
|
||||
// you can't teleport there.
|
||||
var MAX_ANGLE_FROM_UP_TO_TELEPORT = 70;
|
||||
function isValidTeleportLocation(position, surfaceNormal) {
|
||||
var adj = Math.sqrt(surfaceNormal.x * surfaceNormal.x + surfaceNormal.z * surfaceNormal.z);
|
||||
var angleUp = Math.atan2(surfaceNormal.y, adj) * (180 / Math.PI);
|
||||
return angleUp < (90 - MAX_ANGLE_FROM_UP_TO_TELEPORT) ||
|
||||
angleUp > (90 + MAX_ANGLE_FROM_UP_TO_TELEPORT) ||
|
||||
Vec3.distance(MyAvatar.position, position) <= TELEPORT_CANCEL_RANGE;
|
||||
};
|
||||
|
||||
function registerMappings() {
|
||||
|
|
Loading…
Reference in a new issue