improve model picking performance, scale parabola v/a with avatar, improve followNormal behavior, turn off followNormal on teleport, remove 1 m no teleport spot

This commit is contained in:
SamGondelman 2018-07-25 15:19:25 -07:00
parent fbcddf1445
commit 9b41cb5554
18 changed files with 94 additions and 88 deletions

View file

@ -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 rotateAccelerationWithAvatar, PickFilter& filter, float maxDistance, bool enabled) :
ParabolaPick(speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled),
float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, bool scaleWithAvatar, PickFilter& filter, float maxDistance, bool enabled) :
ParabolaPick(speed, accelerationAxis, rotateAccelerationWithAvatar, scaleWithAvatar, filter, maxDistance, enabled),
_jointName(jointName),
_posOffset(posOffset),
_dirOffset(dirOffset)
@ -36,7 +36,7 @@ PickParabola JointParabolaPick::getMathematicalPick() const {
pos = pos + (rot * (myAvatar->getSensorToWorldScale() * _posOffset));
glm::vec3 dir = rot * glm::normalize(_dirOffset);
return PickParabola(pos, _speed * dir, getAcceleration());
return PickParabola(pos, getSpeed() * dir, getAcceleration());
}
return PickParabola();

View file

@ -14,7 +14,8 @@ 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 rotateAccelerationWithAvatar, PickFilter& filter, float maxDistance = 0.0f, bool enabled = false);
float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, bool scaleWithAvatar,
PickFilter& filter, float maxDistance = 0.0f, bool enabled = false);
PickParabola getMathematicalPick() const override;

View file

@ -105,8 +105,8 @@ void LaserPointer::RenderState::disable() {
}
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, surfaceNormal, scaleWithAvatar, distanceScaleEnd, centerEndY, faceAvatar, followNormal, distance, pickResult);
bool faceAvatar, bool followNormal, float followNormalStrength, float distance, const PickResultPointer& pickResult) {
StartEndRenderState::update(origin, end, surfaceNormal, scaleWithAvatar, distanceScaleEnd, centerEndY, faceAvatar, followNormal, followNormalStrength, distance, pickResult);
QVariant endVariant = vec3toVariant(end);
if (!getPathID().isNull()) {
QVariantMap pathProps;

View file

@ -30,7 +30,7 @@ public:
void cleanup() override;
void disable() override;
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;
bool faceAvatar, bool followNormal, float followNormalStrength, float distance, const PickResultPointer& pickResult) override;
private:
OverlayID _pathID;

View file

@ -10,8 +10,9 @@
#include "Application.h"
#include "display-plugins/CompositorHelper.h"
MouseParabolaPick::MouseParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) :
ParabolaPick(speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled)
MouseParabolaPick::MouseParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar,
bool scaleWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) :
ParabolaPick(speed, accelerationAxis, rotateAccelerationWithAvatar, scaleWithAvatar, filter, maxDistance, enabled)
{
}
@ -20,7 +21,7 @@ PickParabola MouseParabolaPick::getMathematicalPick() const {
if (position.isValid()) {
QVariantMap posMap = position.toMap();
PickRay pickRay = qApp->getCamera().computePickRay(posMap["x"].toFloat(), posMap["y"].toFloat());
return PickParabola(pickRay.origin, _speed * pickRay.direction, getAcceleration());
return PickParabola(pickRay.origin, getSpeed() * pickRay.direction, getAcceleration());
}
return PickParabola();

View file

@ -13,7 +13,8 @@
class MouseParabolaPick : public ParabolaPick {
public:
MouseParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, const PickFilter& filter, float maxDistance = 0.0f, bool enabled = false);
MouseParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, bool scaleWithAvatar,
const PickFilter& filter, float maxDistance = 0.0f, bool enabled = false);
PickParabola getMathematicalPick() const override;

View file

@ -51,9 +51,14 @@ PickResultPointer ParabolaPick::getHUDIntersection(const PickParabola& pick) {
return std::make_shared<ParabolaPickResult>(IntersectionType::HUD, QUuid(), glm::distance(pick.origin, hudRes), parabolicDistance, hudRes, pick);
}
float ParabolaPick::getSpeed() const {
return _scaleWithAvatar ? DependencyManager::get<AvatarManager>()->getMyAvatar()->getSensorToWorldScale() * _speed : _speed;
}
glm::vec3 ParabolaPick::getAcceleration() const {
float scale = _scaleWithAvatar ? DependencyManager::get<AvatarManager>()->getMyAvatar()->getSensorToWorldScale() : 1.0f;
if (_rotateAccelerationWithAvatar) {
return DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldOrientation() * _accelerationAxis;
return scale * DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldOrientation() * _accelerationAxis;
}
return _accelerationAxis;
return scale * _accelerationAxis;
}

View file

@ -74,8 +74,9 @@ public:
class ParabolaPick : public Pick<PickParabola> {
public:
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) {}
ParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, bool scaleWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) :
Pick(filter, maxDistance, enabled), _speed(speed), _accelerationAxis(accelerationAxis), _rotateAccelerationWithAvatar(rotateAccelerationWithAvatar),
_scaleWithAvatar(scaleWithAvatar) {}
PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override { return std::make_shared<ParabolaPickResult>(pickVariant); }
PickResultPointer getEntityIntersection(const PickParabola& pick) override;
@ -87,7 +88,9 @@ protected:
float _speed;
glm::vec3 _accelerationAxis;
bool _rotateAccelerationWithAvatar;
bool _scaleWithAvatar;
float getSpeed() const;
glm::vec3 getAcceleration() const;
};

View file

@ -163,8 +163,8 @@ void ParabolaPointer::RenderState::editParabola(const glm::vec3& color, float al
}
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, surfaceNormal, scaleWithAvatar, distanceScaleEnd, centerEndY, faceAvatar, followNormal, distance, pickResult);
bool faceAvatar, bool followNormal, float followNormalStrength, float distance, const PickResultPointer& pickResult) {
StartEndRenderState::update(origin, end, surfaceNormal, scaleWithAvatar, distanceScaleEnd, centerEndY, faceAvatar, followNormal, followNormalStrength, distance, pickResult);
auto parabolaPickResult = std::static_pointer_cast<ParabolaPickResult>(pickResult);
if (parabolaPickResult && render::Item::isValidID(_pathID)) {
render::Transaction transaction;

View file

@ -84,7 +84,7 @@ public:
void cleanup() override;
void disable() override;
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;
bool faceAvatar, bool followNormal, float followNormalStrength, float distance, const PickResultPointer& pickResult) override;
void editParabola(const glm::vec3& color, float alpha, float width, bool isVisibleInSecondaryCamera, bool enabled);

View file

@ -149,18 +149,8 @@ void PathPointer::updateVisuals(const PickResultPointer& pickResult) {
glm::vec3 origin = getPickOrigin(pickResult);
glm::vec3 end = getPickEnd(pickResult, _pathLength);
glm::vec3 surfaceNormal = getPickedObjectNormal(pickResult);
if (_followNormal && _followNormalStrength > 0.0f && _followNormalStrength < 1.0f) {
if (glm::any(glm::isnan(_avgNormal))) {
_avgNormal = surfaceNormal;
} else {
glm::quat a = Quat().lookAtSimple(glm::vec3(0.0f), _avgNormal);
glm::quat b = Quat().lookAtSimple(glm::vec3(0.0f), surfaceNormal);
surfaceNormal = glm::normalize(glm::slerp(a, b, _followNormalStrength) * Vectors::FRONT);
_avgNormal = surfaceNormal;
}
}
_renderStates[_currentRenderState]->update(origin, end, surfaceNormal, _scaleWithAvatar, _distanceScaleEnd, _centerEndY, _faceAvatar,
_followNormal, _pathLength, pickResult);
_followNormal, _followNormalStrength, _pathLength, pickResult);
if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
_defaultRenderStates[_currentRenderState].second->disable();
}
@ -171,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, Vectors::UP, _scaleWithAvatar, _distanceScaleEnd, _centerEndY,
_faceAvatar, _followNormal, _defaultRenderStates[_currentRenderState].first, pickResult);
_faceAvatar, _followNormal, _followNormalStrength, _defaultRenderStates[_currentRenderState].first, pickResult);
} else if (!_currentRenderState.empty()) {
if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
_renderStates[_currentRenderState]->disable();
@ -286,7 +276,7 @@ void StartEndRenderState::disable() {
}
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) {
bool faceAvatar, bool followNormal, float followNormalStrength, float distance, const PickResultPointer& pickResult) {
if (!getStartID().isNull()) {
QVariantMap startProps;
startProps.insert("position", vec3toVariant(origin));
@ -321,22 +311,29 @@ void StartEndRenderState::update(const glm::vec3& origin, const glm::vec3& end,
position = end + 0.5f * dim.y * avatarUp;
}
}
endProps.insert("position", vec3toVariant(position));
if (faceAvatar) {
if (followNormal) {
glm::quat lookAtWorld = Quat().lookAt(position, DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldPosition(), surfaceNormal);
glm::quat lookAtModel = glm::inverse(normalQuat) * lookAtWorld;
glm::quat lookAtFlatModel = Quat().cancelOutRollAndPitch(lookAtModel);
glm::quat lookAtFlatWorld = normalQuat * lookAtFlatModel;
rotation = lookAtFlatWorld;
glm::quat orientation = followNormal ? normalQuat : DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldOrientation();
glm::quat lookAtWorld = Quat().lookAt(position, DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldPosition(), surfaceNormal);
glm::quat lookAtModel = glm::inverse(orientation) * lookAtWorld;
glm::quat lookAtFlatModel = Quat().cancelOutRollAndPitch(lookAtModel);
glm::quat lookAtFlatWorld = orientation * lookAtFlatModel;
rotation = lookAtFlatWorld;
} else if (followNormal) {
rotation = normalQuat;
}
if (followNormal && followNormalStrength > 0.0f && followNormalStrength < 1.0f) {
if (!_avgEndRotInitialized) {
_avgEndRot = rotation;
_avgEndRotInitialized = true;
} else {
glm::quat lookAtWorld = Quat().lookAt(position, DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldPosition(), surfaceNormal);
glm::quat lookAtModel = glm::inverse(DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldOrientation()) * lookAtWorld;
glm::quat lookAtFlatModel = Quat().cancelOutRollAndPitch(lookAtModel);
glm::quat lookAtFlatWorld = DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldOrientation() * lookAtFlatModel;
rotation = lookAtFlatWorld;
rotation = glm::slerp(_avgEndRot, rotation, followNormalStrength);
if (!centerEndY) {
position = end + 0.5f * dim.y * (rotation * Vectors::UP);
}
_avgEndRot = rotation;
}
}
endProps.insert("position", vec3toVariant(position));
endProps.insert("rotation", quatToVariant(rotation));
endProps.insert("visible", true);
endProps.insert("ignoreRayIntersection", doesEndIgnoreRays());

View file

@ -45,7 +45,7 @@ public:
virtual void cleanup();
virtual void disable();
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);
bool faceAvatar, bool followNormal, float followNormalStrength, float distance, const PickResultPointer& pickResult);
protected:
OverlayID _startID;
@ -56,6 +56,9 @@ protected:
glm::vec3 _startDim;
glm::vec3 _endDim;
glm::quat _endRot;
glm::quat _avgEndRot;
bool _avgEndRotInitialized { false };
};
typedef std::unordered_map<std::string, std::shared_ptr<StartEndRenderState>> RenderStateMap;
@ -87,7 +90,6 @@ protected:
bool _faceAvatar;
bool _followNormal;
float _followNormalStrength;
glm::vec3 _avgNormal { NAN };
bool _centerEndY;
bool _lockEnd;
bool _distanceScaleEnd;

View file

@ -154,7 +154,8 @@ unsigned int PickScriptingInterface::createStylusPick(const QVariant& properties
* @property {Vec3} [direction=-Vec3.FRONT] Only for Static Parabola Picks. The world-space direction of the parabola segment.
* @property {number} [speed=1] The initial speed of the parabola, i.e. the initial speed of the projectile whose trajectory defines the parabola.
* @property {Vec3} [accelerationAxis=-Vec3.UP] The acceleration of the parabola, i.e. the acceleration of the projectile whose trajectory defines the parabola, both magnitude and direction.
* @property {boolean} [rotateWithAvatar=true] Whether or not the acceleration axis should rotate with your avatar's local Y axis.
* @property {boolean} [rotateAccelerationWithAvatar=true] Whether or not the acceleration axis should rotate with your avatar's local Y axis.
* @property {boolean} [scaleWithAvatar=false] If true, the velocity and acceleration of the Pick will scale linearly with your avatar.
*/
unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properties) {
QVariantMap propMap = properties.toMap();
@ -189,6 +190,11 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti
rotateAccelerationWithAvatar = propMap["rotateAccelerationWithAvatar"].toBool();
}
bool scaleWithAvatar = false;
if (propMap["scaleWithAvatar"].isValid()) {
scaleWithAvatar = propMap["scaleWithAvatar"].toBool();
}
if (propMap["joint"].isValid()) {
std::string jointName = propMap["joint"].toString().toStdString();
@ -205,10 +211,12 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti
}
return DependencyManager::get<PickManager>()->addPick(PickQuery::Parabola, std::make_shared<JointParabolaPick>(jointName, posOffset, dirOffset,
speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled));
speed, accelerationAxis, rotateAccelerationWithAvatar,
scaleWithAvatar, filter, maxDistance, enabled));
} else {
return DependencyManager::get<PickManager>()->addPick(PickQuery::Parabola, std::make_shared<MouseParabolaPick>(speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled));
return DependencyManager::get<PickManager>()->addPick(PickQuery::Parabola, std::make_shared<MouseParabolaPick>(speed, accelerationAxis, rotateAccelerationWithAvatar,
scaleWithAvatar, filter, maxDistance, enabled));
}
} else if (propMap["position"].isValid()) {
glm::vec3 position = vec3FromVariant(propMap["position"]);
@ -218,7 +226,9 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti
direction = vec3FromVariant(propMap["direction"]);
}
return DependencyManager::get<PickManager>()->addPick(PickQuery::Parabola, std::make_shared<StaticParabolaPick>(position, direction, speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled));
return DependencyManager::get<PickManager>()->addPick(PickQuery::Parabola, std::make_shared<StaticParabolaPick>(position, direction, speed, accelerationAxis,
rotateAccelerationWithAvatar, scaleWithAvatar,
filter, maxDistance, enabled));
}
return PickManager::INVALID_PICK_ID;

View file

@ -132,7 +132,7 @@ unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& prope
scaleWithAvatar = propertyMap["scaleWithAvatar"].toBool();
}
bool followNormal = true;
bool followNormal = false;
if (propertyMap["followNormal"].isValid()) {
followNormal = propertyMap["followNormal"].toBool();
}
@ -275,7 +275,7 @@ unsigned int PointerScriptingInterface::createParabolaPointer(const QVariant& pr
scaleWithAvatar = propertyMap["scaleWithAvatar"].toBool();
}
bool followNormal = true;
bool followNormal = false;
if (propertyMap["followNormal"].isValid()) {
followNormal = propertyMap["followNormal"].toBool();
}

View file

@ -7,13 +7,13 @@
//
#include "StaticParabolaPick.h"
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, rotateAccelerationWithAvatar, filter, maxDistance, enabled),
_position(position), _velocity(speed * direction)
StaticParabolaPick::StaticParabolaPick(const glm::vec3& position, const glm::vec3& direction, float speed, const glm::vec3& accelerationAxis,
bool scaleWithAvatar, bool rotateAccelerationWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) :
ParabolaPick(speed, accelerationAxis, rotateAccelerationWithAvatar, scaleWithAvatar, filter, maxDistance, enabled),
_position(position), _velocity(direction)
{
}
PickParabola StaticParabolaPick::getMathematicalPick() const {
return PickParabola(_position, _velocity, getAcceleration());
return PickParabola(_position, getSpeed() * _velocity, getAcceleration());
}

View file

@ -14,7 +14,7 @@ class StaticParabolaPick : public ParabolaPick {
public:
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);
bool scaleWithAvatar, const PickFilter& filter, float maxDistance = 0.0f, bool enabled = false);
PickParabola getMathematicalPick() const override;

View file

@ -135,7 +135,6 @@ bool TriangleSet::TriangleOctreeCell::findRayIntersectionInternal(const glm::vec
}
} else {
intersectedSomething = true;
// FIXME: this needs to set triangle to something or it will carry the previous value
bestDistance = distance;
}
@ -168,7 +167,6 @@ bool TriangleSet::TriangleOctreeCell::findParabolaIntersectionInternal(const glm
}
} else {
intersectedSomething = true;
// FIXME: this needs to set triangle to something or it will carry the previous value
bestDistance = parabolicDistance;
}
@ -263,29 +261,28 @@ bool TriangleSet::TriangleOctreeCell::findRayIntersection(const glm::vec3& origi
bool intersects = false;
float boxDistance = FLT_MAX;
// if the ray intersects our bounding box, then continue
// if the pick intersects our bounding box, then continue
if (getBounds().findRayIntersection(origin, direction, boxDistance, bestLocalFace, bestLocalNormal)) {
// if the intersection with our bounding box, is greater than the current best distance (the distance passed in)
// then we know that none of our triangles can represent a better intersection and we can return
if (bestLocalDistance > distance) {
if (boxDistance > distance) {
return false;
}
bestLocalDistance = distance;
float childDistance = distance;
BoxFace childFace;
Triangle childTriangle;
// if we're not yet at the max depth, then check which child the triangle fits in
if (_depth < MAX_DEPTH) {
float bestChildDistance = FLT_MAX;
for (auto& child : _children) {
// check each child, if there's an intersection, it will return some distance that we need
// to compare against the other results, because there might be multiple intersections and
// we will always choose the best (shortest) intersection
float childDistance = bestChildDistance;
BoxFace childFace;
Triangle childTriangle;
if (child.second.findRayIntersection(origin, direction, childDistance, childFace, childTriangle, precision, trianglesTouched)) {
if (childDistance < bestLocalDistance) {
bestLocalDistance = childDistance;
bestChildDistance = childDistance;
bestLocalFace = childFace;
bestLocalTriangle = childTriangle;
intersects = true;
@ -298,7 +295,7 @@ bool TriangleSet::TriangleOctreeCell::findRayIntersection(const glm::vec3& origi
BoxFace internalFace;
Triangle internalTriangle;
if (findRayIntersectionInternal(origin, direction, internalDistance, internalFace, internalTriangle, precision, trianglesTouched, allowBackface)) {
if (internalDistance < childDistance) {
if (internalDistance < bestLocalDistance) {
bestLocalDistance = internalDistance;
bestLocalFace = internalFace;
bestLocalTriangle = internalTriangle;
@ -329,29 +326,28 @@ bool TriangleSet::TriangleOctreeCell::findParabolaIntersection(const glm::vec3&
bool intersects = false;
float boxDistance = FLT_MAX;
// if the ray intersects our bounding box, then continue
// if the pick intersects our bounding box, then continue
if (getBounds().findParabolaIntersection(origin, velocity, acceleration, boxDistance, bestLocalFace, bestLocalNormal)) {
// if the intersection with our bounding box, is greater than the current best distance (the distance passed in)
// then we know that none of our triangles can represent a better intersection and we can return
if (bestLocalDistance > parabolicDistance) {
if (boxDistance > parabolicDistance) {
return false;
}
bestLocalDistance = parabolicDistance;
float childDistance = parabolicDistance;
BoxFace childFace;
Triangle childTriangle;
// if we're not yet at the max depth, then check which child the triangle fits in
if (_depth < MAX_DEPTH) {
float bestChildDistance = FLT_MAX;
for (auto& child : _children) {
// check each child, if there's an intersection, it will return some distance that we need
// to compare against the other results, because there might be multiple intersections and
// we will always choose the best (shortest) intersection
float childDistance = bestChildDistance;
BoxFace childFace;
Triangle childTriangle;
if (child.second.findParabolaIntersection(origin, velocity, acceleration, childDistance, childFace, childTriangle, precision, trianglesTouched)) {
if (childDistance < bestLocalDistance) {
bestLocalDistance = childDistance;
bestChildDistance = childDistance;
bestLocalFace = childFace;
bestLocalTriangle = childTriangle;
intersects = true;
@ -364,7 +360,7 @@ bool TriangleSet::TriangleOctreeCell::findParabolaIntersection(const glm::vec3&
BoxFace internalFace;
Triangle internalTriangle;
if (findParabolaIntersectionInternal(origin, velocity, acceleration, internalDistance, internalFace, internalTriangle, precision, trianglesTouched, allowBackface)) {
if (internalDistance < childDistance) {
if (internalDistance < bestLocalDistance) {
bestLocalDistance = internalDistance;
bestLocalFace = internalFace;
bestLocalTriangle = internalTriangle;

View file

@ -49,7 +49,6 @@ Script.include("/~/system/libraries/controllers.js");
blue: 73
};
var TELEPORT_CANCEL_RANGE = 1;
var COOL_IN_DURATION = 300;
var handInfo = {
@ -146,8 +145,6 @@ Script.include("/~/system/libraries/controllers.js");
faceAvatar: true,
scaleWithAvatar: true,
centerEndY: false,
followNormal: true,
followNormalStrength: 0.1,
speed: speed,
accelerationAxis: accelerationAxis,
rotateAccelerationWithAvatar: true,
@ -161,8 +158,6 @@ Script.include("/~/system/libraries/controllers.js");
faceAvatar: true,
scaleWithAvatar: true,
centerEndY: false,
followNormal: true,
followNormalStrength: 0.1,
speed: speed,
accelerationAxis: accelerationAxis,
rotateAccelerationWithAvatar: true,
@ -175,8 +170,6 @@ Script.include("/~/system/libraries/controllers.js");
faceAvatar: true,
scaleWithAvatar: true,
centerEndY: false,
followNormal: true,
followNormalStrength: 0.1,
speed: speed,
accelerationAxis: accelerationAxis,
rotateAccelerationWithAvatar: true,
@ -190,8 +183,6 @@ Script.include("/~/system/libraries/controllers.js");
faceAvatar: true,
scaleWithAvatar: true,
centerEndY: false,
followNormal: true,
followNormalStrength: 0.1,
speed: speed,
accelerationAxis: accelerationAxis,
rotateAccelerationWithAvatar: true,
@ -440,8 +431,7 @@ Script.include("/~/system/libraries/controllers.js");
var surfaceNormal = result.surfaceNormal;
var angle = Math.acos(Vec3.dot(surfaceNormal, Quat.getUp(MyAvatar.orientation))) * (180.0 / Math.PI);
if (angle > MAX_ANGLE_FROM_UP_TO_TELEPORT ||
Vec3.distance(MyAvatar.position, result.intersection) <= TELEPORT_CANCEL_RANGE * MyAvatar.sensorToWorldScale) {
if (angle > MAX_ANGLE_FROM_UP_TO_TELEPORT) {
return TARGET.INVALID;
} else {
return TARGET.SURFACE;