mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 14:47:41 +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
|
# ignore files for various dev environments
|
||||||
TAGS
|
TAGS
|
||||||
*.swp
|
*.sw[po]
|
||||||
|
|
||||||
# ignore node files for the console
|
# ignore node files for the console
|
||||||
node_modules
|
node_modules
|
||||||
|
|
|
@ -591,17 +591,17 @@ void EntityTreeRenderer::deleteReleasedModels() {
|
||||||
|
|
||||||
RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
||||||
bool precisionPicking, const QVector<EntityItemID>& entityIdsToInclude,
|
bool precisionPicking, const QVector<EntityItemID>& entityIdsToInclude,
|
||||||
const QVector<EntityItemID>& entityIdsToDiscard) {
|
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly) {
|
||||||
RayToEntityIntersectionResult result;
|
RayToEntityIntersectionResult result;
|
||||||
if (_tree) {
|
if (_tree) {
|
||||||
EntityTreePointer entityTree = std::static_pointer_cast<EntityTree>(_tree);
|
EntityTreePointer entityTree = std::static_pointer_cast<EntityTree>(_tree);
|
||||||
|
|
||||||
OctreeElementPointer element;
|
OctreeElementPointer element;
|
||||||
EntityItemPointer intersectedEntity = NULL;
|
EntityItemPointer intersectedEntity = NULL;
|
||||||
result.intersects = entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance,
|
result.intersects = entityTree->findRayIntersection(ray.origin, ray.direction,
|
||||||
result.face, result.surfaceNormal, entityIdsToInclude, entityIdsToDiscard,
|
entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly, precisionPicking,
|
||||||
(void**)&intersectedEntity, lockType, &result.accurate,
|
element, result.distance, result.face, result.surfaceNormal,
|
||||||
precisionPicking);
|
(void**)&intersectedEntity, lockType, &result.accurate);
|
||||||
if (result.intersects && intersectedEntity) {
|
if (result.intersects && intersectedEntity) {
|
||||||
result.entityID = intersectedEntity->getEntityItemID();
|
result.entityID = intersectedEntity->getEntityItemID();
|
||||||
result.properties = intersectedEntity->getProperties();
|
result.properties = intersectedEntity->getProperties();
|
||||||
|
|
|
@ -149,7 +149,8 @@ private:
|
||||||
QList<ModelPointer> _releasedModels;
|
QList<ModelPointer> _releasedModels;
|
||||||
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
||||||
bool precisionPicking, const QVector<EntityItemID>& entityIdsToInclude = QVector<EntityItemID>(),
|
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 _currentHoverOverEntityID;
|
||||||
EntityItemID _currentClickingOnEntityID;
|
EntityItemID _currentClickingOnEntityID;
|
||||||
|
|
|
@ -624,11 +624,11 @@ QVector<QUuid> EntityScriptingInterface::findEntitiesInFrustum(QVariantMap frust
|
||||||
}
|
}
|
||||||
|
|
||||||
RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray, bool precisionPicking,
|
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> entitiesToInclude = qVectorEntityItemIDFromScriptValue(entityIdsToInclude);
|
||||||
QVector<EntityItemID> entitiesToDiscard = qVectorEntityItemIDFromScriptValue(entityIdsToDiscard);
|
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
|
// 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,
|
RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionWorker(const PickRay& ray,
|
||||||
Octree::lockType lockType,
|
Octree::lockType lockType, bool precisionPicking, const QVector<EntityItemID>& entityIdsToInclude,
|
||||||
bool precisionPicking, const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIdsToDiscard) {
|
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly) {
|
||||||
|
|
||||||
|
|
||||||
RayToEntityIntersectionResult result;
|
RayToEntityIntersectionResult result;
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
OctreeElementPointer element;
|
OctreeElementPointer element;
|
||||||
EntityItemPointer intersectedEntity = NULL;
|
EntityItemPointer intersectedEntity = NULL;
|
||||||
result.intersects = _entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
|
result.intersects = _entityTree->findRayIntersection(ray.origin, ray.direction,
|
||||||
result.surfaceNormal, entityIdsToInclude, entityIdsToDiscard, (void**)&intersectedEntity, lockType, &result.accurate,
|
entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly, precisionPicking,
|
||||||
precisionPicking);
|
element, result.distance, result.face, result.surfaceNormal,
|
||||||
|
(void**)&intersectedEntity, lockType, &result.accurate);
|
||||||
if (result.intersects && intersectedEntity) {
|
if (result.intersects && intersectedEntity) {
|
||||||
result.entityID = intersectedEntity->getEntityItemID();
|
result.entityID = intersectedEntity->getEntityItemID();
|
||||||
result.properties = intersectedEntity->getProperties();
|
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
|
/// 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
|
/// may be inaccurate if the engine is unable to access the visible entities, in which case result.accurate
|
||||||
/// will be false.
|
/// 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
|
/// If the scripting context has visible entities, this will determine a ray intersection, and will block in
|
||||||
/// order to return an accurate result
|
/// 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
|
/// 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,
|
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;
|
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
|
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) :
|
EntityTree::EntityTree(bool shouldReaverage) :
|
||||||
Octree(shouldReaverage),
|
Octree(shouldReaverage),
|
||||||
_fbxService(NULL),
|
_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
|
// if this element doesn't contain the point, then none of its children can contain the point, so stop searching
|
||||||
return false;
|
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) {
|
bool findRayIntersectionOp(OctreeElementPointer element, void* extraData) {
|
||||||
RayArgs* args = static_cast<RayArgs*>(extraData);
|
RayArgs* args = static_cast<RayArgs*>(extraData);
|
||||||
bool keepSearching = true;
|
bool keepSearching = true;
|
||||||
EntityTreeElementPointer entityTreeElementPointer = std::dynamic_pointer_cast<EntityTreeElement>(element);
|
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->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;
|
args->found = true;
|
||||||
}
|
}
|
||||||
return keepSearching;
|
return keepSearching;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool EntityTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
OctreeElementPointer& element, float& distance,
|
QVector<EntityItemID> entityIdsToInclude, QVector<EntityItemID> entityIdsToDiscard,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIdsToDiscard, void** intersectedObject,
|
bool visibleOnly, bool collidableOnly, bool precisionPicking,
|
||||||
Octree::lockType lockType, bool* accurateResult, bool precisionPicking) {
|
OctreeElementPointer& element, float& distance,
|
||||||
RayArgs args = { origin, direction, element, distance, face, surfaceNormal, entityIdsToInclude, entityIdsToDiscard, intersectedObject, false, precisionPicking };
|
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;
|
distance = FLT_MAX;
|
||||||
|
|
||||||
bool requireLock = lockType == Octree::Lock;
|
bool requireLock = lockType == Octree::Lock;
|
||||||
|
|
|
@ -31,6 +31,7 @@ using ModelWeakPointer = std::weak_ptr<Model>;
|
||||||
|
|
||||||
class EntitySimulation;
|
class EntitySimulation;
|
||||||
|
|
||||||
|
|
||||||
class NewlyCreatedEntityHook {
|
class NewlyCreatedEntityHook {
|
||||||
public:
|
public:
|
||||||
virtual void entityCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode) = 0;
|
virtual void entityCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode) = 0;
|
||||||
|
@ -89,13 +90,11 @@ public:
|
||||||
const SharedNodePointer& senderNode) override;
|
const SharedNodePointer& senderNode) override;
|
||||||
|
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
OctreeElementPointer& node, float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
QVector<EntityItemID> entityIdsToInclude, QVector<EntityItemID> entityIdsToDiscard,
|
||||||
const QVector<EntityItemID>& entityIdsToInclude = QVector<EntityItemID>(),
|
bool visibleOnly, bool collidableOnly, bool precisionPicking,
|
||||||
const QVector<EntityItemID>& entityIdsToDiscard = QVector<EntityItemID>(),
|
OctreeElementPointer& node, float& distance,
|
||||||
void** intersectedObject = NULL,
|
BoxFace& face, glm::vec3& surfaceNormal, void** intersectedObject = NULL,
|
||||||
Octree::lockType lockType = Octree::TryLock,
|
Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
|
||||||
bool* accurateResult = NULL,
|
|
||||||
bool precisionPicking = false);
|
|
||||||
|
|
||||||
virtual bool rootElementHasData() const override { return true; }
|
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 EntityTreeElement::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude,
|
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.
|
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 (_cube.contains(origin) || distanceToElementCube < distance) {
|
||||||
|
|
||||||
if (findDetailedRayIntersection(origin, direction, keepSearching, element, distanceToElementDetails,
|
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) {
|
if (distanceToElementDetails < distance) {
|
||||||
distance = distanceToElementDetails;
|
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,
|
bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching,
|
||||||
OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
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...
|
// only called if we do intersect our bounding cube, but find if we actually intersect with entities...
|
||||||
int entityNumber = 0;
|
int entityNumber = 0;
|
||||||
bool somethingIntersected = false;
|
bool somethingIntersected = false;
|
||||||
forEachEntity([&](EntityItemPointer entity) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,7 +643,7 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
|
||||||
if (localDistance < distance && entity->getType() != EntityTypes::ParticleEffect) {
|
if (localDistance < distance && entity->getType() != EntityTypes::ParticleEffect) {
|
||||||
distance = localDistance;
|
distance = localDistance;
|
||||||
face = localFace;
|
face = localFace;
|
||||||
surfaceNormal = localSurfaceNormal;
|
surfaceNormal = glm::vec3(rotation * glm::vec4(localSurfaceNormal, 1.0f));
|
||||||
*intersectedObject = (void*)entity.get();
|
*intersectedObject = (void*)entity.get();
|
||||||
somethingIntersected = true;
|
somethingIntersected = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,12 +147,12 @@ public:
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& node, float& distance,
|
bool& keepSearching, OctreeElementPointer& node, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude,
|
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);
|
void** intersectedObject = NULL, bool precisionPicking = false);
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude,
|
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);
|
void** intersectedObject, bool precisionPicking, float distanceToElementCube);
|
||||||
virtual bool findSpherePenetration(const glm::vec3& center, float radius,
|
virtual bool findSpherePenetration(const glm::vec3& center, float radius,
|
||||||
glm::vec3& penetration, void** penetratedObject) const override;
|
glm::vec3& penetration, void** penetratedObject) const override;
|
||||||
|
|
|
@ -142,6 +142,7 @@ function ifAvatarMovedGoActive() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MAIN CONTROL
|
// MAIN CONTROL
|
||||||
|
var isEnabled = true;
|
||||||
var wasMuted, isAway;
|
var wasMuted, isAway;
|
||||||
var wasOverlaysVisible = Menu.isOptionChecked("Overlays");
|
var wasOverlaysVisible = Menu.isOptionChecked("Overlays");
|
||||||
var eventMappingName = "io.highfidelity.away"; // goActive on hand controller button events, too.
|
var eventMappingName = "io.highfidelity.away"; // goActive on hand controller button events, too.
|
||||||
|
@ -159,7 +160,7 @@ function safeGetHMDMounted() {
|
||||||
var wasHmdMounted = safeGetHMDMounted();
|
var wasHmdMounted = safeGetHMDMounted();
|
||||||
|
|
||||||
function goAway() {
|
function goAway() {
|
||||||
if (isAway) {
|
if (!isEnabled || isAway) {
|
||||||
return;
|
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(maybeMoveOverlay);
|
||||||
|
|
||||||
Script.update.connect(maybeGoAway);
|
Script.update.connect(maybeGoAway);
|
||||||
|
|
|
@ -344,7 +344,7 @@ function entityHasActions(entityID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function findRayIntersection(pickRay, precise, include, exclude) {
|
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);
|
var overlays = Overlays.findRayIntersection(pickRay);
|
||||||
if (!overlays.intersects || (entities.intersects && (entities.distance <= overlays.distance))) {
|
if (!overlays.intersects || (entities.intersects && (entities.distance <= overlays.distance))) {
|
||||||
return entities;
|
return entities;
|
||||||
|
@ -1158,9 +1158,9 @@ function MyController(hand) {
|
||||||
|
|
||||||
var intersection;
|
var intersection;
|
||||||
if (USE_BLACKLIST === true && blacklist.length !== 0) {
|
if (USE_BLACKLIST === true && blacklist.length !== 0) {
|
||||||
intersection = findRayIntersection(pickRay, true, [], blacklist);
|
intersection = findRayIntersection(pickRay, true, [], blacklist, true);
|
||||||
} else {
|
} else {
|
||||||
intersection = findRayIntersection(pickRay, true);
|
intersection = findRayIntersection(pickRay, true, [], [], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intersection.intersects) {
|
if (intersection.intersects) {
|
||||||
|
@ -1608,7 +1608,6 @@ function MyController(hand) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.distanceHoldingEnter = function() {
|
this.distanceHoldingEnter = function() {
|
||||||
Messages.sendLocalMessage('Hifi-Teleport-Disabler', 'both');
|
|
||||||
this.clearEquipHaptics();
|
this.clearEquipHaptics();
|
||||||
this.grabPointSphereOff();
|
this.grabPointSphereOff();
|
||||||
|
|
||||||
|
@ -1872,12 +1871,6 @@ function MyController(hand) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.nearGrabbingEnter = function() {
|
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.grabPointSphereOff();
|
||||||
this.lineOff();
|
this.lineOff();
|
||||||
this.overlayLineOff();
|
this.overlayLineOff();
|
||||||
|
@ -2215,7 +2208,7 @@ function MyController(hand) {
|
||||||
|
|
||||||
var now = Date.now();
|
var now = Date.now();
|
||||||
if (now - this.lastPickTime > MSECS_PER_SEC / PICKS_PER_SECOND_PER_HAND) {
|
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) {
|
if (intersection.accurate || intersection.overlayID) {
|
||||||
this.lastPickTime = now;
|
this.lastPickTime = now;
|
||||||
if (intersection.entityID != this.grabbedEntity) {
|
if (intersection.entityID != this.grabbedEntity) {
|
||||||
|
@ -2343,7 +2336,6 @@ function MyController(hand) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.release = function() {
|
this.release = function() {
|
||||||
Messages.sendLocalMessage('Hifi-Teleport-Disabler', 'none');
|
|
||||||
this.turnOffVisualizations();
|
this.turnOffVisualizations();
|
||||||
|
|
||||||
var noVelocity = false;
|
var noVelocity = false;
|
||||||
|
@ -2714,6 +2706,20 @@ var handleHandMessages = function(channel, message, sender) {
|
||||||
}
|
}
|
||||||
handToDisable = message;
|
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') {
|
} else if (channel === 'Hifi-Hand-Grab') {
|
||||||
try {
|
try {
|
||||||
data = JSON.parse(message);
|
data = JSON.parse(message);
|
||||||
|
|
|
@ -279,7 +279,7 @@ function Teleporter() {
|
||||||
var location = Vec3.sum(rightPickRay.origin, Vec3.multiply(rightPickRay.direction, 50));
|
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 (rightIntersection.intersects) {
|
||||||
if (this.tooClose === true) {
|
if (this.tooClose === true) {
|
||||||
|
@ -342,7 +342,7 @@ function Teleporter() {
|
||||||
var location = Vec3.sum(MyAvatar.position, Vec3.multiply(leftPickRay.direction, 50));
|
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) {
|
if (leftIntersection.intersects) {
|
||||||
|
|
||||||
|
@ -459,7 +459,7 @@ function Teleporter() {
|
||||||
z: intersection.intersection.z
|
z: intersection.intersection.z
|
||||||
};
|
};
|
||||||
|
|
||||||
this.tooClose = isTooCloseToTeleport(position);
|
this.tooClose = isValidTeleportLocation(position, intersection.surfaceNormal);
|
||||||
var towardUs = Quat.fromPitchYawRollDegrees(0, euler.y, 0);
|
var towardUs = Quat.fromPitchYawRollDegrees(0, euler.y, 0);
|
||||||
|
|
||||||
Overlays.editOverlay(this.targetOverlay, {
|
Overlays.editOverlay(this.targetOverlay, {
|
||||||
|
@ -480,7 +480,7 @@ function Teleporter() {
|
||||||
z: intersection.intersection.z
|
z: intersection.intersection.z
|
||||||
};
|
};
|
||||||
|
|
||||||
this.tooClose = isTooCloseToTeleport(position);
|
this.tooClose = isValidTeleportLocation(position, intersection.surfaceNormal);
|
||||||
var towardUs = Quat.fromPitchYawRollDegrees(0, euler.y, 0);
|
var towardUs = Quat.fromPitchYawRollDegrees(0, euler.y, 0);
|
||||||
|
|
||||||
Overlays.editOverlay(this.cancelOverlay, {
|
Overlays.editOverlay(this.cancelOverlay, {
|
||||||
|
@ -509,7 +509,12 @@ function Teleporter() {
|
||||||
var offset = getAvatarFootOffset();
|
var offset = getAvatarFootOffset();
|
||||||
this.intersection.intersection.y += offset;
|
this.intersection.intersection.y += offset;
|
||||||
this.exitTeleportMode();
|
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) {
|
// When determininig whether you can teleport to a location, the normal of the
|
||||||
return Vec3.distance(MyAvatar.position, position) <= TELEPORT_CANCEL_RANGE;
|
// 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() {
|
function registerMappings() {
|
||||||
|
|
Loading…
Reference in a new issue