diff --git a/interface/src/avatar/OtherAvatar.cpp b/interface/src/avatar/OtherAvatar.cpp index 5e51658128..2061df6004 100644 --- a/interface/src/avatar/OtherAvatar.cpp +++ b/interface/src/avatar/OtherAvatar.cpp @@ -48,7 +48,7 @@ void OtherAvatar::createOrb() { _otherAvatarOrbMeshPlaceholder->setPulseMin(0.5); _otherAvatarOrbMeshPlaceholder->setPulseMax(1.0); _otherAvatarOrbMeshPlaceholder->setColorPulse(1.0); - _otherAvatarOrbMeshPlaceholder->setIgnoreRayIntersection(true); + _otherAvatarOrbMeshPlaceholder->setIgnorePickIntersection(true); _otherAvatarOrbMeshPlaceholder->setDrawInFront(false); _otherAvatarOrbMeshPlaceholderID = qApp->getOverlays().addOverlay(_otherAvatarOrbMeshPlaceholder); // Position focus diff --git a/interface/src/raypick/JointParabolaPick.cpp b/interface/src/raypick/JointParabolaPick.cpp index 771cbe6185..071187c082 100644 --- a/interface/src/raypick/JointParabolaPick.cpp +++ b/interface/src/raypick/JointParabolaPick.cpp @@ -10,8 +10,8 @@ #include "avatar/AvatarManager.h" JointParabolaPick::JointParabolaPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, - float speed, const glm::vec3& accelerationAxis, bool rotateWithAvatar, PickFilter& filter, float maxDistance, bool enabled) : - ParabolaPick(speed, accelerationAxis, rotateWithAvatar, filter, maxDistance, enabled), + float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, PickFilter& filter, float maxDistance, bool enabled) : + ParabolaPick(speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled), _jointName(jointName), _posOffset(posOffset), _dirOffset(dirOffset) diff --git a/interface/src/raypick/JointParabolaPick.h b/interface/src/raypick/JointParabolaPick.h index d8b4457d7f..6c03d7b8f7 100644 --- a/interface/src/raypick/JointParabolaPick.h +++ b/interface/src/raypick/JointParabolaPick.h @@ -14,7 +14,7 @@ class JointParabolaPick : public ParabolaPick { public: JointParabolaPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, - float speed, const glm::vec3& accelerationAxis, bool rotateWithAvatar, PickFilter& filter, float maxDistance = 0.0f, bool enabled = false); + float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, PickFilter& filter, float maxDistance = 0.0f, bool enabled = false); PickParabola getMathematicalPick() const override; diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index 16bb4e25e1..4c47a9f4de 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -103,9 +103,9 @@ void LaserPointer::RenderState::disable() { } } -void LaserPointer::RenderState::update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, +void LaserPointer::RenderState::update(const glm::vec3& origin, const glm::vec3& end, const glm::vec3& surfaceNormal, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult) { - StartEndRenderState::update(origin, end, scaleWithAvatar, distanceScaleEnd, centerEndY, faceAvatar, followNormal, distance, pickResult); + StartEndRenderState::update(origin, end, surfaceNormal, scaleWithAvatar, distanceScaleEnd, centerEndY, faceAvatar, followNormal, distance, pickResult); QVariant endVariant = vec3toVariant(end); if (!getPathID().isNull()) { QVariantMap pathProps; diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index 5030c90186..a320e272d1 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -29,7 +29,7 @@ public: void cleanup() override; void disable() override; - void update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, + void update(const glm::vec3& origin, const glm::vec3& end, const glm::vec3& surfaceNormal, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult) override; private: diff --git a/interface/src/raypick/MouseParabolaPick.cpp b/interface/src/raypick/MouseParabolaPick.cpp index 450c792913..769819c6b3 100644 --- a/interface/src/raypick/MouseParabolaPick.cpp +++ b/interface/src/raypick/MouseParabolaPick.cpp @@ -10,8 +10,8 @@ #include "Application.h" #include "display-plugins/CompositorHelper.h" -MouseParabolaPick::MouseParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) : - ParabolaPick(speed, accelerationAxis, rotateWithAvatar, filter, maxDistance, enabled) +MouseParabolaPick::MouseParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) : + ParabolaPick(speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled) { } diff --git a/interface/src/raypick/MouseParabolaPick.h b/interface/src/raypick/MouseParabolaPick.h index ad03997c09..8c02606d49 100644 --- a/interface/src/raypick/MouseParabolaPick.h +++ b/interface/src/raypick/MouseParabolaPick.h @@ -13,7 +13,7 @@ class MouseParabolaPick : public ParabolaPick { public: - MouseParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateWithAvatar, const PickFilter& filter, float maxDistance = 0.0f, bool enabled = false); + MouseParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, const PickFilter& filter, float maxDistance = 0.0f, bool enabled = false); PickParabola getMathematicalPick() const override; diff --git a/interface/src/raypick/ParabolaPick.cpp b/interface/src/raypick/ParabolaPick.cpp index 8dd0ad3aed..3d1b1c410d 100644 --- a/interface/src/raypick/ParabolaPick.cpp +++ b/interface/src/raypick/ParabolaPick.cpp @@ -52,6 +52,8 @@ PickResultPointer ParabolaPick::getHUDIntersection(const PickParabola& pick) { } glm::vec3 ParabolaPick::getAcceleration() const { - // TODO: use rotateWithAvatar + if (_rotateAccelerationWithAvatar) { + return DependencyManager::get()->getMyAvatar()->getWorldOrientation() * _accelerationAxis; + } return _accelerationAxis; } \ No newline at end of file diff --git a/interface/src/raypick/ParabolaPick.h b/interface/src/raypick/ParabolaPick.h index 289f6e468a..86dfc5a644 100644 --- a/interface/src/raypick/ParabolaPick.h +++ b/interface/src/raypick/ParabolaPick.h @@ -74,8 +74,8 @@ public: class ParabolaPick : public Pick { public: - ParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) : - Pick(filter, maxDistance, enabled), _speed(speed), _accelerationAxis(accelerationAxis), _rotateWithAvatar(rotateWithAvatar) {} + ParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) : + Pick(filter, maxDistance, enabled), _speed(speed), _accelerationAxis(accelerationAxis), _rotateAccelerationWithAvatar(rotateAccelerationWithAvatar) {} PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override { return std::make_shared(pickVariant); } PickResultPointer getEntityIntersection(const PickParabola& pick) override; @@ -86,7 +86,7 @@ public: protected: float _speed; glm::vec3 _accelerationAxis; - bool _rotateWithAvatar; + bool _rotateAccelerationWithAvatar; glm::vec3 getAcceleration() const; }; diff --git a/interface/src/raypick/ParabolaPointer.cpp b/interface/src/raypick/ParabolaPointer.cpp index aee5b8cfa1..42612ef46d 100644 --- a/interface/src/raypick/ParabolaPointer.cpp +++ b/interface/src/raypick/ParabolaPointer.cpp @@ -51,6 +51,7 @@ void ParabolaPointer::editRenderStatePath(const std::string& state, const QVaria } if (pathMap["width"].isValid()) { width = pathMap["width"].toFloat(); + renderState->setPathWidth(width); } if (pathMap["isVisibleInSecondaryCamera"].isValid()) { isVisibleInSecondaryCamera = pathMap["isVisibleInSecondaryCamera"].toBool(); @@ -112,6 +113,7 @@ ParabolaPointer::RenderState::RenderState(const OverlayID& startID, const Overla render::Transaction transaction; auto scene = qApp->getMain3DScene(); _pathID = scene->allocateID(); + _pathWidth = pathWidth; if (render::Item::isValidID(_pathID)) { auto renderItem = std::make_shared(pathColor, pathAlpha, pathWidth, isVisibleInSecondaryCamera, pathEnabled); // TODO: update bounds properly @@ -160,9 +162,9 @@ void ParabolaPointer::RenderState::editParabola(const glm::vec3& color, float al } } -void ParabolaPointer::RenderState::update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, +void ParabolaPointer::RenderState::update(const glm::vec3& origin, const glm::vec3& end, const glm::vec3& surfaceNormal, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult) { - StartEndRenderState::update(origin, end, scaleWithAvatar, distanceScaleEnd, centerEndY, faceAvatar, followNormal, distance, pickResult); + StartEndRenderState::update(origin, end, surfaceNormal, scaleWithAvatar, distanceScaleEnd, centerEndY, faceAvatar, followNormal, distance, pickResult); auto parabolaPickResult = std::static_pointer_cast(pickResult); if (parabolaPickResult && render::Item::isValidID(_pathID)) { render::Transaction transaction; @@ -172,12 +174,14 @@ void ParabolaPointer::RenderState::update(const glm::vec3& origin, const glm::ve glm::vec3 velocity = parabola.velocity; glm::vec3 acceleration = parabola.acceleration; float parabolicDistance = distance > 0.0f ? distance : parabolaPickResult->parabolicDistance; - transaction.updateItem(_pathID, [origin, velocity, acceleration, parabolicDistance](ParabolaRenderItem& item) { + float width = scaleWithAvatar ? getPathWidth() * DependencyManager::get()->getMyAvatar()->getSensorToWorldScale() : getPathWidth(); + transaction.updateItem(_pathID, [origin, velocity, acceleration, parabolicDistance, width](ParabolaRenderItem& item) { item.setVisible(true); item.setOrigin(origin); item.setVelocity(velocity); item.setAcceleration(acceleration); item.setParabolicDistance(parabolicDistance); + item.setWidth(width); item.updateUniformBuffer(); }); scene->enqueueTransaction(transaction); @@ -364,6 +368,7 @@ void ParabolaPointer::RenderState::ParabolaRenderItem::render(RenderArgs* args) batch.setUniformBuffer(0, _uniformBuffer); + // TODO: variable number of sections, depending on ? (acceleration?, parabolicDistance?) const int NUM_SECTIONS = 25; // must match value in parabola.slv // We draw 2 * n + 2 vertices for a triangle strip batch.draw(gpu::TRIANGLE_STRIP, 2 * NUM_SECTIONS + 2, 0); diff --git a/interface/src/raypick/ParabolaPointer.h b/interface/src/raypick/ParabolaPointer.h index 827134eaf5..4a4a27e8fc 100644 --- a/interface/src/raypick/ParabolaPointer.h +++ b/interface/src/raypick/ParabolaPointer.h @@ -75,15 +75,19 @@ public: RenderState(const OverlayID& startID, const OverlayID& endID, const glm::vec3& pathColor, float pathAlpha, float pathWidth, bool isVisibleInSecondaryCamera, bool pathEnabled); + void setPathWidth(float width) { _pathWidth = width; } + float getPathWidth() const { return _pathWidth; } + void cleanup() override; void disable() override; - void update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, + void update(const glm::vec3& origin, const glm::vec3& end, const glm::vec3& surfaceNormal, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult) override; void editParabola(const glm::vec3& color, float alpha, float width, bool isVisibleInSecondaryCamera, bool enabled); private: int _pathID; + float _pathWidth; }; ParabolaPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates, bool hover, const PointerTriggers& triggers, diff --git a/interface/src/raypick/PathPointer.cpp b/interface/src/raypick/PathPointer.cpp index 1582b62ab2..664e124ea0 100644 --- a/interface/src/raypick/PathPointer.cpp +++ b/interface/src/raypick/PathPointer.cpp @@ -149,7 +149,8 @@ void PathPointer::updateVisuals(const PickResultPointer& pickResult) { (type != IntersectionType::NONE || _pathLength > 0.0f)) { glm::vec3 origin = getPickOrigin(pickResult); glm::vec3 end = getPickEnd(pickResult, _pathLength); - _renderStates[_currentRenderState]->update(origin, end, _scaleWithAvatar, _distanceScaleEnd, _centerEndY, _faceAvatar, + glm::vec3 surfaceNormal = getPickedObjectNormal(pickResult); + _renderStates[_currentRenderState]->update(origin, end, surfaceNormal, _scaleWithAvatar, _distanceScaleEnd, _centerEndY, _faceAvatar, _followNormal, _pathLength, pickResult); if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { _defaultRenderStates[_currentRenderState].second->disable(); @@ -160,7 +161,7 @@ void PathPointer::updateVisuals(const PickResultPointer& pickResult) { } glm::vec3 origin = getPickOrigin(pickResult); glm::vec3 end = getPickEnd(pickResult, _defaultRenderStates[_currentRenderState].first); - _defaultRenderStates[_currentRenderState].second->update(origin, end, _scaleWithAvatar, _distanceScaleEnd, _centerEndY, + _defaultRenderStates[_currentRenderState].second->update(origin, end, Vectors::UP, _scaleWithAvatar, _distanceScaleEnd, _centerEndY, _faceAvatar, _followNormal, _defaultRenderStates[_currentRenderState].first, pickResult); } else if (!_currentRenderState.empty()) { if (_renderStates.find(_currentRenderState) != _renderStates.end()) { @@ -275,7 +276,7 @@ void StartEndRenderState::disable() { } } -void StartEndRenderState::update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, +void StartEndRenderState::update(const glm::vec3& origin, const glm::vec3& end, const glm::vec3& surfaceNormal, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult) { if (!getStartID().isNull()) { QVariantMap startProps; @@ -290,7 +291,6 @@ void StartEndRenderState::update(const glm::vec3& origin, const glm::vec3& end, if (!getEndID().isNull()) { QVariantMap endProps; - glm::quat faceAvatarRotation = DependencyManager::get()->getMyAvatar()->getWorldOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, 180.0f, 0.0f))); glm::vec3 dim = vec3FromVariant(qApp->getOverlays().getProperty(getEndID(), "dimensions").value); if (distanceScaleEnd) { dim = getEndDim() * glm::distance(origin, end); @@ -299,15 +299,36 @@ void StartEndRenderState::update(const glm::vec3& origin, const glm::vec3& end, dim = getEndDim() * DependencyManager::get()->getMyAvatar()->getSensorToWorldScale(); endProps.insert("dimensions", vec3toVariant(dim)); } - if (centerEndY) { - endProps.insert("position", vec3toVariant(end)); - } else { - glm::vec3 currentUpVector = faceAvatarRotation * Vectors::UP; - endProps.insert("position", vec3toVariant(end + glm::vec3(currentUpVector.x * 0.5f * dim.y, currentUpVector.y * 0.5f * dim.y, currentUpVector.z * 0.5f * dim.y))); + + glm::quat normalQuat = Quat().lookAtSimple(Vectors::ZERO, surfaceNormal); + normalQuat = normalQuat * glm::quat(glm::vec3(-M_PI_2, 0, 0)); + glm::vec3 avatarUp = DependencyManager::get()->getMyAvatar()->getWorldOrientation() * Vectors::UP; + glm::quat rotation = glm::rotation(Vectors::UP, avatarUp); + glm::vec3 position = end; + if (!centerEndY) { + if (followNormal) { + position = end + 0.5f * dim.y * surfaceNormal; + } else { + position = end + 0.5f * dim.y * avatarUp; + } } + endProps.insert("position", vec3toVariant(position)); if (faceAvatar) { - endProps.insert("rotation", quatToVariant(faceAvatarRotation)); + if (followNormal) { + glm::quat lookAtWorld = Quat().lookAt(position, DependencyManager::get()->getMyAvatar()->getWorldPosition(), surfaceNormal); + glm::quat lookAtModel = glm::inverse(normalQuat) * lookAtWorld; + glm::quat lookAtFlatModel = Quat().cancelOutRollAndPitch(lookAtModel); + glm::quat lookAtFlatWorld = normalQuat * lookAtFlatModel; + rotation = lookAtFlatWorld; + } else { + glm::quat lookAtWorld = Quat().lookAt(position, DependencyManager::get()->getMyAvatar()->getWorldPosition(), surfaceNormal); + glm::quat lookAtModel = glm::inverse(DependencyManager::get()->getMyAvatar()->getWorldOrientation()) * lookAtWorld; + glm::quat lookAtFlatModel = Quat().cancelOutRollAndPitch(lookAtModel); + glm::quat lookAtFlatWorld = DependencyManager::get()->getMyAvatar()->getWorldOrientation() * lookAtFlatModel; + rotation = lookAtFlatWorld; + } } + endProps.insert("rotation", quatToVariant(rotation)); endProps.insert("visible", true); endProps.insert("ignoreRayIntersection", doesEndIgnoreRays()); qApp->getOverlays().editOverlay(getEndID(), endProps); diff --git a/interface/src/raypick/PathPointer.h b/interface/src/raypick/PathPointer.h index ff40f47646..1e85ad7a92 100644 --- a/interface/src/raypick/PathPointer.h +++ b/interface/src/raypick/PathPointer.h @@ -44,7 +44,7 @@ public: virtual void cleanup(); virtual void disable(); - virtual void update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, + virtual void update(const glm::vec3& origin, const glm::vec3& end, const glm::vec3& surfaceNormal, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult); protected: diff --git a/interface/src/raypick/PickScriptingInterface.cpp b/interface/src/raypick/PickScriptingInterface.cpp index 8475126f28..ac1fa05c1e 100644 --- a/interface/src/raypick/PickScriptingInterface.cpp +++ b/interface/src/raypick/PickScriptingInterface.cpp @@ -184,9 +184,9 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti accelerationAxis = vec3FromVariant(propMap["accelerationAxis"]); } - bool rotateWithAvatar = true; - if (propMap["rotateWithAvatar"].isValid()) { - rotateWithAvatar = propMap["rotateWithAvatar"].toBool(); + bool rotateAccelerationWithAvatar = true; + if (propMap["rotateAccelerationWithAvatar"].isValid()) { + rotateAccelerationWithAvatar = propMap["rotateAccelerationWithAvatar"].toBool(); } if (propMap["joint"].isValid()) { @@ -205,10 +205,10 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti } return DependencyManager::get()->addPick(PickQuery::Parabola, std::make_shared(jointName, posOffset, dirOffset, - speed, accelerationAxis, rotateWithAvatar, filter, maxDistance, enabled)); + speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled)); } else { - return DependencyManager::get()->addPick(PickQuery::Parabola, std::make_shared(speed, accelerationAxis, rotateWithAvatar, filter, maxDistance, enabled)); + return DependencyManager::get()->addPick(PickQuery::Parabola, std::make_shared(speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled)); } } else if (propMap["position"].isValid()) { glm::vec3 position = vec3FromVariant(propMap["position"]); @@ -218,7 +218,7 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti direction = vec3FromVariant(propMap["direction"]); } - return DependencyManager::get()->addPick(PickQuery::Parabola, std::make_shared(position, direction, speed, accelerationAxis, rotateWithAvatar, filter, maxDistance, enabled)); + return DependencyManager::get()->addPick(PickQuery::Parabola, std::make_shared(position, direction, speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled)); } return PickManager::INVALID_PICK_ID; diff --git a/interface/src/raypick/StaticParabolaPick.cpp b/interface/src/raypick/StaticParabolaPick.cpp index 57b6aeccc7..2cf8501980 100644 --- a/interface/src/raypick/StaticParabolaPick.cpp +++ b/interface/src/raypick/StaticParabolaPick.cpp @@ -7,9 +7,9 @@ // #include "StaticParabolaPick.h" -StaticParabolaPick::StaticParabolaPick(const glm::vec3& position, const glm::vec3& direction, float speed, const glm::vec3& accelerationAxis, bool rotateWithAvatar, +StaticParabolaPick::StaticParabolaPick(const glm::vec3& position, const glm::vec3& direction, float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) : - ParabolaPick(speed, accelerationAxis, rotateWithAvatar, filter, maxDistance, enabled), + ParabolaPick(speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled), _position(position), _velocity(speed * direction) { } diff --git a/interface/src/raypick/StaticParabolaPick.h b/interface/src/raypick/StaticParabolaPick.h index 676b012b41..e0d6a2a3fa 100644 --- a/interface/src/raypick/StaticParabolaPick.h +++ b/interface/src/raypick/StaticParabolaPick.h @@ -13,7 +13,7 @@ class StaticParabolaPick : public ParabolaPick { public: - StaticParabolaPick(const glm::vec3& position, const glm::vec3& direction, float speed, const glm::vec3& accelerationAxis, bool rotateWithAvatar, + StaticParabolaPick(const glm::vec3& position, const glm::vec3& direction, float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, const PickFilter& filter, float maxDistance = 0.0f, bool enabled = false); PickParabola getMathematicalPick() const override; diff --git a/libraries/shared/src/GeometryUtil.cpp b/libraries/shared/src/GeometryUtil.cpp index 1d470c42c3..f34473a5d8 100644 --- a/libraries/shared/src/GeometryUtil.cpp +++ b/libraries/shared/src/GeometryUtil.cpp @@ -840,8 +840,9 @@ bool findParabolaRectangleIntersection(const glm::vec3& origin, const glm::vec3& float c = origin.z; glm::vec2 possibleDistances = { FLT_MAX, FLT_MAX }; if (computeRealQuadraticRoots(a, b, c, possibleDistances)) { - checkPossibleParabolicIntersectionWithZPlane(possibleDistances.x, minDistance, origin, velocity, acceleration, localCorner, dimensions); - checkPossibleParabolicIntersectionWithZPlane(possibleDistances.y, minDistance, origin, velocity, acceleration, localCorner, dimensions); + for (int i = 0; i < 2; i++) { + checkPossibleParabolicIntersectionWithZPlane(possibleDistances[i], minDistance, origin, velocity, acceleration, localCorner, dimensions); + } } } if (minDistance < FLT_MAX) { @@ -941,7 +942,8 @@ void checkPossibleParabolicIntersectionWithTriangle(float t, float& minDistance, // Check that the point is within all three sides glm::vec3 point = origin + velocity * t + 0.5f * acceleration * t * t; - if (glm::dot(normal, glm::cross(point - v1, v0 - v1)) > 0.0f && + if (t < minDistance && t > 0.0f && + glm::dot(normal, glm::cross(point - v1, v0 - v1)) > 0.0f && glm::dot(normal, glm::cross(v2 - v1, point - v1)) > 0.0f && glm::dot(normal, glm::cross(point - v0, v2 - v0)) > 0.0f) { minDistance = t; @@ -981,10 +983,10 @@ bool findParabolaTriangleIntersection(const glm::vec3& origin, const glm::vec3& float c = localOrigin.z; glm::vec2 possibleDistances = { FLT_MAX, FLT_MAX }; if (computeRealQuadraticRoots(a, b, c, possibleDistances)) { - checkPossibleParabolicIntersectionWithTriangle(possibleDistances.x, minDistance, origin, velocity, acceleration, - localVelocity, localAcceleration, normal, v0, v1, v2, allowBackface); - checkPossibleParabolicIntersectionWithTriangle(possibleDistances.y, minDistance, origin, velocity, acceleration, - localVelocity, localAcceleration, normal, v0, v1, v2, allowBackface); + for (int i = 0; i < 2; i++) { + checkPossibleParabolicIntersectionWithTriangle(possibleDistances[i], minDistance, origin, velocity, acceleration, + localVelocity, localAcceleration, normal, v0, v1, v2, allowBackface); + } } } if (minDistance < FLT_MAX) { @@ -1374,8 +1376,8 @@ bool findParabolaAABoxIntersection(const glm::vec3& origin, const glm::vec3& vel { // min c = origin[i] - corner[i]; possibleDistances = { FLT_MAX, FLT_MAX }; - bool hit = false; if (computeRealQuadraticRoots(a, b, c, possibleDistances)) { + bool hit = false; for (int j = 0; j < 2; j++) { if (parabolaVelocityAtT(velocity[i], acceleration[i], possibleDistances[j]) < 0.0f) { checkPossibleParabolicIntersection(possibleDistances[j], i, minDistance, origin, velocity, acceleration, corner, scale, hit); @@ -1391,8 +1393,8 @@ bool findParabolaAABoxIntersection(const glm::vec3& origin, const glm::vec3& vel { // max c = origin[i] - (corner[i] + scale[i]); possibleDistances = { FLT_MAX, FLT_MAX }; - bool hit = false; if (computeRealQuadraticRoots(a, b, c, possibleDistances)) { + bool hit = false; for (int j = 0; j < 2; j++) { if (parabolaVelocityAtT(velocity[i], acceleration[i], possibleDistances[j]) > 0.0f) { checkPossibleParabolicIntersection(possibleDistances[j], i, minDistance, origin, velocity, acceleration, corner, scale, hit); diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index 12e3f6ab3a..55162ae3e9 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -80,19 +80,19 @@ Script.include("/~/system/libraries/controllers.js"); type: "model", url: TOO_CLOSE_MODEL_URL, dimensions: TARGET_MODEL_DIMENSIONS, - ignoreParabolaIntersection: true + ignorePickIntersection: true }; var teleportEnd = { type: "model", url: TARGET_MODEL_URL, dimensions: TARGET_MODEL_DIMENSIONS, - ignoreParabolaIntersection: true + ignorePickIntersection: true }; var seatEnd = { type: "model", url: SEAT_MODEL_URL, dimensions: TARGET_MODEL_DIMENSIONS, - ignoreParabolaIntersection: true + ignorePickIntersection: true }; @@ -149,6 +149,7 @@ Script.include("/~/system/libraries/controllers.js"); followNormal: true, speed: speed, accelerationAxis: accelerationAxis, + rotateAccelerationWithAvatar: true, renderStates: teleportRenderStates, defaultRenderStates: teleportDefaultRenderStates }); @@ -161,6 +162,7 @@ Script.include("/~/system/libraries/controllers.js"); followNormal: true, speed: speed, accelerationAxis: accelerationAxis, + rotateAccelerationWithAvatar: true, renderStates: teleportRenderStates }); this.teleportParabolaHeadVisible = Pointers.createPointer(PickType.Parabola, { @@ -172,6 +174,7 @@ Script.include("/~/system/libraries/controllers.js"); followNormal: true, speed: speed, accelerationAxis: accelerationAxis, + rotateAccelerationWithAvatar: true, renderStates: teleportRenderStates, defaultRenderStates: teleportDefaultRenderStates }); @@ -184,6 +187,7 @@ Script.include("/~/system/libraries/controllers.js"); followNormal: true, speed: speed, accelerationAxis: accelerationAxis, + rotateAccelerationWithAvatar: true, renderStates: teleportRenderStates }); @@ -402,7 +406,7 @@ Script.include("/~/system/libraries/controllers.js"); } // 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 + // than MAX_ANGLE_FROM_UP_TO_TELEPORT degrees from your avatar's up, then // you can't teleport there. var MAX_ANGLE_FROM_UP_TO_TELEPORT = 70; function getTeleportTargetType(result) { @@ -426,11 +430,9 @@ Script.include("/~/system/libraries/controllers.js"); } var surfaceNormal = result.surfaceNormal; - var adj = Math.sqrt(surfaceNormal.x * surfaceNormal.x + surfaceNormal.z * surfaceNormal.z); - var angleUp = Math.atan2(surfaceNormal.y, adj) * (180 / Math.PI); + var angle = Math.abs(Math.acos(Vec3.dot(surfaceNormal, Quat.getUp(MyAvatar.orientation)))) * (180.0 / Math.PI); - if (angleUp < (90 - MAX_ANGLE_FROM_UP_TO_TELEPORT) || - angleUp > (90 + MAX_ANGLE_FROM_UP_TO_TELEPORT) || + if (angle > MAX_ANGLE_FROM_UP_TO_TELEPORT || Vec3.distance(MyAvatar.position, result.intersection) <= TELEPORT_CANCEL_RANGE * MyAvatar.sensorToWorldScale) { return TARGET.INVALID; } else {