followNormal, fixin stuff

This commit is contained in:
SamGondelman 2018-07-19 17:59:40 -07:00
parent 956c1511b6
commit 763e6465a2
18 changed files with 91 additions and 55 deletions

View file

@ -48,7 +48,7 @@ void OtherAvatar::createOrb() {
_otherAvatarOrbMeshPlaceholder->setPulseMin(0.5); _otherAvatarOrbMeshPlaceholder->setPulseMin(0.5);
_otherAvatarOrbMeshPlaceholder->setPulseMax(1.0); _otherAvatarOrbMeshPlaceholder->setPulseMax(1.0);
_otherAvatarOrbMeshPlaceholder->setColorPulse(1.0); _otherAvatarOrbMeshPlaceholder->setColorPulse(1.0);
_otherAvatarOrbMeshPlaceholder->setIgnoreRayIntersection(true); _otherAvatarOrbMeshPlaceholder->setIgnorePickIntersection(true);
_otherAvatarOrbMeshPlaceholder->setDrawInFront(false); _otherAvatarOrbMeshPlaceholder->setDrawInFront(false);
_otherAvatarOrbMeshPlaceholderID = qApp->getOverlays().addOverlay(_otherAvatarOrbMeshPlaceholder); _otherAvatarOrbMeshPlaceholderID = qApp->getOverlays().addOverlay(_otherAvatarOrbMeshPlaceholder);
// Position focus // Position focus

View file

@ -10,8 +10,8 @@
#include "avatar/AvatarManager.h" #include "avatar/AvatarManager.h"
JointParabolaPick::JointParabolaPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, 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) : float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, PickFilter& filter, float maxDistance, bool enabled) :
ParabolaPick(speed, accelerationAxis, rotateWithAvatar, filter, maxDistance, enabled), ParabolaPick(speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled),
_jointName(jointName), _jointName(jointName),
_posOffset(posOffset), _posOffset(posOffset),
_dirOffset(dirOffset) _dirOffset(dirOffset)

View file

@ -14,7 +14,7 @@ class JointParabolaPick : public ParabolaPick {
public: public:
JointParabolaPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, 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; PickParabola getMathematicalPick() const override;

View file

@ -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) { 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); QVariant endVariant = vec3toVariant(end);
if (!getPathID().isNull()) { if (!getPathID().isNull()) {
QVariantMap pathProps; QVariantMap pathProps;

View file

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

View file

@ -10,8 +10,8 @@
#include "Application.h" #include "Application.h"
#include "display-plugins/CompositorHelper.h" #include "display-plugins/CompositorHelper.h"
MouseParabolaPick::MouseParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) : MouseParabolaPick::MouseParabolaPick(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)
{ {
} }

View file

@ -13,7 +13,7 @@
class MouseParabolaPick : public ParabolaPick { class MouseParabolaPick : public ParabolaPick {
public: 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; PickParabola getMathematicalPick() const override;

View file

@ -52,6 +52,8 @@ PickResultPointer ParabolaPick::getHUDIntersection(const PickParabola& pick) {
} }
glm::vec3 ParabolaPick::getAcceleration() const { glm::vec3 ParabolaPick::getAcceleration() const {
// TODO: use rotateWithAvatar if (_rotateAccelerationWithAvatar) {
return DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldOrientation() * _accelerationAxis;
}
return _accelerationAxis; return _accelerationAxis;
} }

View file

@ -74,8 +74,8 @@ public:
class ParabolaPick : public Pick<PickParabola> { class ParabolaPick : public Pick<PickParabola> {
public: public:
ParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) : ParabolaPick(float speed, const glm::vec3& accelerationAxis, bool rotateAccelerationWithAvatar, const PickFilter& filter, float maxDistance, bool enabled) :
Pick(filter, maxDistance, enabled), _speed(speed), _accelerationAxis(accelerationAxis), _rotateWithAvatar(rotateWithAvatar) {} Pick(filter, maxDistance, enabled), _speed(speed), _accelerationAxis(accelerationAxis), _rotateAccelerationWithAvatar(rotateAccelerationWithAvatar) {}
PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override { return std::make_shared<ParabolaPickResult>(pickVariant); } PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override { return std::make_shared<ParabolaPickResult>(pickVariant); }
PickResultPointer getEntityIntersection(const PickParabola& pick) override; PickResultPointer getEntityIntersection(const PickParabola& pick) override;
@ -86,7 +86,7 @@ public:
protected: protected:
float _speed; float _speed;
glm::vec3 _accelerationAxis; glm::vec3 _accelerationAxis;
bool _rotateWithAvatar; bool _rotateAccelerationWithAvatar;
glm::vec3 getAcceleration() const; glm::vec3 getAcceleration() const;
}; };

View file

@ -51,6 +51,7 @@ void ParabolaPointer::editRenderStatePath(const std::string& state, const QVaria
} }
if (pathMap["width"].isValid()) { if (pathMap["width"].isValid()) {
width = pathMap["width"].toFloat(); width = pathMap["width"].toFloat();
renderState->setPathWidth(width);
} }
if (pathMap["isVisibleInSecondaryCamera"].isValid()) { if (pathMap["isVisibleInSecondaryCamera"].isValid()) {
isVisibleInSecondaryCamera = pathMap["isVisibleInSecondaryCamera"].toBool(); isVisibleInSecondaryCamera = pathMap["isVisibleInSecondaryCamera"].toBool();
@ -112,6 +113,7 @@ ParabolaPointer::RenderState::RenderState(const OverlayID& startID, const Overla
render::Transaction transaction; render::Transaction transaction;
auto scene = qApp->getMain3DScene(); auto scene = qApp->getMain3DScene();
_pathID = scene->allocateID(); _pathID = scene->allocateID();
_pathWidth = pathWidth;
if (render::Item::isValidID(_pathID)) { if (render::Item::isValidID(_pathID)) {
auto renderItem = std::make_shared<ParabolaRenderItem>(pathColor, pathAlpha, pathWidth, isVisibleInSecondaryCamera, pathEnabled); auto renderItem = std::make_shared<ParabolaRenderItem>(pathColor, pathAlpha, pathWidth, isVisibleInSecondaryCamera, pathEnabled);
// TODO: update bounds properly // 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) { 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<ParabolaPickResult>(pickResult); auto parabolaPickResult = std::static_pointer_cast<ParabolaPickResult>(pickResult);
if (parabolaPickResult && render::Item::isValidID(_pathID)) { if (parabolaPickResult && render::Item::isValidID(_pathID)) {
render::Transaction transaction; 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 velocity = parabola.velocity;
glm::vec3 acceleration = parabola.acceleration; glm::vec3 acceleration = parabola.acceleration;
float parabolicDistance = distance > 0.0f ? distance : parabolaPickResult->parabolicDistance; float parabolicDistance = distance > 0.0f ? distance : parabolaPickResult->parabolicDistance;
transaction.updateItem<ParabolaRenderItem>(_pathID, [origin, velocity, acceleration, parabolicDistance](ParabolaRenderItem& item) { float width = scaleWithAvatar ? getPathWidth() * DependencyManager::get<AvatarManager>()->getMyAvatar()->getSensorToWorldScale() : getPathWidth();
transaction.updateItem<ParabolaRenderItem>(_pathID, [origin, velocity, acceleration, parabolicDistance, width](ParabolaRenderItem& item) {
item.setVisible(true); item.setVisible(true);
item.setOrigin(origin); item.setOrigin(origin);
item.setVelocity(velocity); item.setVelocity(velocity);
item.setAcceleration(acceleration); item.setAcceleration(acceleration);
item.setParabolicDistance(parabolicDistance); item.setParabolicDistance(parabolicDistance);
item.setWidth(width);
item.updateUniformBuffer(); item.updateUniformBuffer();
}); });
scene->enqueueTransaction(transaction); scene->enqueueTransaction(transaction);
@ -364,6 +368,7 @@ void ParabolaPointer::RenderState::ParabolaRenderItem::render(RenderArgs* args)
batch.setUniformBuffer(0, _uniformBuffer); batch.setUniformBuffer(0, _uniformBuffer);
// TODO: variable number of sections, depending on ? (acceleration?, parabolicDistance?)
const int NUM_SECTIONS = 25; // must match value in parabola.slv const int NUM_SECTIONS = 25; // must match value in parabola.slv
// We draw 2 * n + 2 vertices for a triangle strip // We draw 2 * n + 2 vertices for a triangle strip
batch.draw(gpu::TRIANGLE_STRIP, 2 * NUM_SECTIONS + 2, 0); batch.draw(gpu::TRIANGLE_STRIP, 2 * NUM_SECTIONS + 2, 0);

View file

@ -75,15 +75,19 @@ public:
RenderState(const OverlayID& startID, const OverlayID& endID, const glm::vec3& pathColor, float pathAlpha, float pathWidth, RenderState(const OverlayID& startID, const OverlayID& endID, const glm::vec3& pathColor, float pathAlpha, float pathWidth,
bool isVisibleInSecondaryCamera, bool pathEnabled); bool isVisibleInSecondaryCamera, bool pathEnabled);
void setPathWidth(float width) { _pathWidth = width; }
float getPathWidth() const { return _pathWidth; }
void cleanup() override; void cleanup() override;
void disable() 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; bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult) override;
void editParabola(const glm::vec3& color, float alpha, float width, bool isVisibleInSecondaryCamera, bool enabled); void editParabola(const glm::vec3& color, float alpha, float width, bool isVisibleInSecondaryCamera, bool enabled);
private: private:
int _pathID; int _pathID;
float _pathWidth;
}; };
ParabolaPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates, bool hover, const PointerTriggers& triggers, ParabolaPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates, bool hover, const PointerTriggers& triggers,

View file

@ -149,7 +149,8 @@ void PathPointer::updateVisuals(const PickResultPointer& pickResult) {
(type != IntersectionType::NONE || _pathLength > 0.0f)) { (type != IntersectionType::NONE || _pathLength > 0.0f)) {
glm::vec3 origin = getPickOrigin(pickResult); glm::vec3 origin = getPickOrigin(pickResult);
glm::vec3 end = getPickEnd(pickResult, _pathLength); 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); _followNormal, _pathLength, pickResult);
if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) {
_defaultRenderStates[_currentRenderState].second->disable(); _defaultRenderStates[_currentRenderState].second->disable();
@ -160,7 +161,7 @@ void PathPointer::updateVisuals(const PickResultPointer& pickResult) {
} }
glm::vec3 origin = getPickOrigin(pickResult); glm::vec3 origin = getPickOrigin(pickResult);
glm::vec3 end = getPickEnd(pickResult, _defaultRenderStates[_currentRenderState].first); 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); _faceAvatar, _followNormal, _defaultRenderStates[_currentRenderState].first, pickResult);
} else if (!_currentRenderState.empty()) { } else if (!_currentRenderState.empty()) {
if (_renderStates.find(_currentRenderState) != _renderStates.end()) { 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) { bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult) {
if (!getStartID().isNull()) { if (!getStartID().isNull()) {
QVariantMap startProps; QVariantMap startProps;
@ -290,7 +291,6 @@ void StartEndRenderState::update(const glm::vec3& origin, const glm::vec3& end,
if (!getEndID().isNull()) { if (!getEndID().isNull()) {
QVariantMap endProps; QVariantMap endProps;
glm::quat faceAvatarRotation = DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, 180.0f, 0.0f)));
glm::vec3 dim = vec3FromVariant(qApp->getOverlays().getProperty(getEndID(), "dimensions").value); glm::vec3 dim = vec3FromVariant(qApp->getOverlays().getProperty(getEndID(), "dimensions").value);
if (distanceScaleEnd) { if (distanceScaleEnd) {
dim = getEndDim() * glm::distance(origin, end); 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<AvatarManager>()->getMyAvatar()->getSensorToWorldScale(); dim = getEndDim() * DependencyManager::get<AvatarManager>()->getMyAvatar()->getSensorToWorldScale();
endProps.insert("dimensions", vec3toVariant(dim)); endProps.insert("dimensions", vec3toVariant(dim));
} }
if (centerEndY) {
endProps.insert("position", vec3toVariant(end)); glm::quat normalQuat = Quat().lookAtSimple(Vectors::ZERO, surfaceNormal);
} else { normalQuat = normalQuat * glm::quat(glm::vec3(-M_PI_2, 0, 0));
glm::vec3 currentUpVector = faceAvatarRotation * Vectors::UP; glm::vec3 avatarUp = DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldOrientation() * 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 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) { if (faceAvatar) {
endProps.insert("rotation", quatToVariant(faceAvatarRotation)); 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;
} 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;
}
} }
endProps.insert("rotation", quatToVariant(rotation));
endProps.insert("visible", true); endProps.insert("visible", true);
endProps.insert("ignoreRayIntersection", doesEndIgnoreRays()); endProps.insert("ignoreRayIntersection", doesEndIgnoreRays());
qApp->getOverlays().editOverlay(getEndID(), endProps); qApp->getOverlays().editOverlay(getEndID(), endProps);

View file

@ -44,7 +44,7 @@ public:
virtual void cleanup(); virtual void cleanup();
virtual void disable(); 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); bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult);
protected: protected:

View file

@ -184,9 +184,9 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti
accelerationAxis = vec3FromVariant(propMap["accelerationAxis"]); accelerationAxis = vec3FromVariant(propMap["accelerationAxis"]);
} }
bool rotateWithAvatar = true; bool rotateAccelerationWithAvatar = true;
if (propMap["rotateWithAvatar"].isValid()) { if (propMap["rotateAccelerationWithAvatar"].isValid()) {
rotateWithAvatar = propMap["rotateWithAvatar"].toBool(); rotateAccelerationWithAvatar = propMap["rotateAccelerationWithAvatar"].toBool();
} }
if (propMap["joint"].isValid()) { if (propMap["joint"].isValid()) {
@ -205,10 +205,10 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti
} }
return DependencyManager::get<PickManager>()->addPick(PickQuery::Parabola, std::make_shared<JointParabolaPick>(jointName, posOffset, dirOffset, return DependencyManager::get<PickManager>()->addPick(PickQuery::Parabola, std::make_shared<JointParabolaPick>(jointName, posOffset, dirOffset,
speed, accelerationAxis, rotateWithAvatar, filter, maxDistance, enabled)); speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled));
} else { } else {
return DependencyManager::get<PickManager>()->addPick(PickQuery::Parabola, std::make_shared<MouseParabolaPick>(speed, accelerationAxis, rotateWithAvatar, filter, maxDistance, enabled)); return DependencyManager::get<PickManager>()->addPick(PickQuery::Parabola, std::make_shared<MouseParabolaPick>(speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled));
} }
} else if (propMap["position"].isValid()) { } else if (propMap["position"].isValid()) {
glm::vec3 position = vec3FromVariant(propMap["position"]); glm::vec3 position = vec3FromVariant(propMap["position"]);
@ -218,7 +218,7 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti
direction = vec3FromVariant(propMap["direction"]); direction = vec3FromVariant(propMap["direction"]);
} }
return DependencyManager::get<PickManager>()->addPick(PickQuery::Parabola, std::make_shared<StaticParabolaPick>(position, direction, speed, accelerationAxis, rotateWithAvatar, filter, maxDistance, enabled)); return DependencyManager::get<PickManager>()->addPick(PickQuery::Parabola, std::make_shared<StaticParabolaPick>(position, direction, speed, accelerationAxis, rotateAccelerationWithAvatar, filter, maxDistance, enabled));
} }
return PickManager::INVALID_PICK_ID; return PickManager::INVALID_PICK_ID;

View file

@ -7,9 +7,9 @@
// //
#include "StaticParabolaPick.h" #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) : 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) _position(position), _velocity(speed * direction)
{ {
} }

View file

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

View file

@ -840,8 +840,9 @@ bool findParabolaRectangleIntersection(const glm::vec3& origin, const glm::vec3&
float c = origin.z; float c = origin.z;
glm::vec2 possibleDistances = { FLT_MAX, FLT_MAX }; glm::vec2 possibleDistances = { FLT_MAX, FLT_MAX };
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) { if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
checkPossibleParabolicIntersectionWithZPlane(possibleDistances.x, minDistance, origin, velocity, acceleration, localCorner, dimensions); for (int i = 0; i < 2; i++) {
checkPossibleParabolicIntersectionWithZPlane(possibleDistances.y, minDistance, origin, velocity, acceleration, localCorner, dimensions); checkPossibleParabolicIntersectionWithZPlane(possibleDistances[i], minDistance, origin, velocity, acceleration, localCorner, dimensions);
}
} }
} }
if (minDistance < FLT_MAX) { if (minDistance < FLT_MAX) {
@ -941,7 +942,8 @@ void checkPossibleParabolicIntersectionWithTriangle(float t, float& minDistance,
// Check that the point is within all three sides // Check that the point is within all three sides
glm::vec3 point = origin + velocity * t + 0.5f * acceleration * t * t; 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(v2 - v1, point - v1)) > 0.0f &&
glm::dot(normal, glm::cross(point - v0, v2 - v0)) > 0.0f) { glm::dot(normal, glm::cross(point - v0, v2 - v0)) > 0.0f) {
minDistance = t; minDistance = t;
@ -981,10 +983,10 @@ bool findParabolaTriangleIntersection(const glm::vec3& origin, const glm::vec3&
float c = localOrigin.z; float c = localOrigin.z;
glm::vec2 possibleDistances = { FLT_MAX, FLT_MAX }; glm::vec2 possibleDistances = { FLT_MAX, FLT_MAX };
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) { if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
checkPossibleParabolicIntersectionWithTriangle(possibleDistances.x, minDistance, origin, velocity, acceleration, for (int i = 0; i < 2; i++) {
localVelocity, localAcceleration, normal, v0, v1, v2, allowBackface); checkPossibleParabolicIntersectionWithTriangle(possibleDistances[i], minDistance, origin, velocity, acceleration,
checkPossibleParabolicIntersectionWithTriangle(possibleDistances.y, minDistance, origin, velocity, acceleration, localVelocity, localAcceleration, normal, v0, v1, v2, allowBackface);
localVelocity, localAcceleration, normal, v0, v1, v2, allowBackface); }
} }
} }
if (minDistance < FLT_MAX) { if (minDistance < FLT_MAX) {
@ -1374,8 +1376,8 @@ bool findParabolaAABoxIntersection(const glm::vec3& origin, const glm::vec3& vel
{ // min { // min
c = origin[i] - corner[i]; c = origin[i] - corner[i];
possibleDistances = { FLT_MAX, FLT_MAX }; possibleDistances = { FLT_MAX, FLT_MAX };
bool hit = false;
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) { if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
bool hit = false;
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
if (parabolaVelocityAtT(velocity[i], acceleration[i], possibleDistances[j]) < 0.0f) { if (parabolaVelocityAtT(velocity[i], acceleration[i], possibleDistances[j]) < 0.0f) {
checkPossibleParabolicIntersection(possibleDistances[j], i, minDistance, origin, velocity, acceleration, corner, scale, hit); 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 { // max
c = origin[i] - (corner[i] + scale[i]); c = origin[i] - (corner[i] + scale[i]);
possibleDistances = { FLT_MAX, FLT_MAX }; possibleDistances = { FLT_MAX, FLT_MAX };
bool hit = false;
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) { if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
bool hit = false;
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
if (parabolaVelocityAtT(velocity[i], acceleration[i], possibleDistances[j]) > 0.0f) { if (parabolaVelocityAtT(velocity[i], acceleration[i], possibleDistances[j]) > 0.0f) {
checkPossibleParabolicIntersection(possibleDistances[j], i, minDistance, origin, velocity, acceleration, corner, scale, hit); checkPossibleParabolicIntersection(possibleDistances[j], i, minDistance, origin, velocity, acceleration, corner, scale, hit);

View file

@ -80,19 +80,19 @@ Script.include("/~/system/libraries/controllers.js");
type: "model", type: "model",
url: TOO_CLOSE_MODEL_URL, url: TOO_CLOSE_MODEL_URL,
dimensions: TARGET_MODEL_DIMENSIONS, dimensions: TARGET_MODEL_DIMENSIONS,
ignoreParabolaIntersection: true ignorePickIntersection: true
}; };
var teleportEnd = { var teleportEnd = {
type: "model", type: "model",
url: TARGET_MODEL_URL, url: TARGET_MODEL_URL,
dimensions: TARGET_MODEL_DIMENSIONS, dimensions: TARGET_MODEL_DIMENSIONS,
ignoreParabolaIntersection: true ignorePickIntersection: true
}; };
var seatEnd = { var seatEnd = {
type: "model", type: "model",
url: SEAT_MODEL_URL, url: SEAT_MODEL_URL,
dimensions: TARGET_MODEL_DIMENSIONS, dimensions: TARGET_MODEL_DIMENSIONS,
ignoreParabolaIntersection: true ignorePickIntersection: true
}; };
@ -149,6 +149,7 @@ Script.include("/~/system/libraries/controllers.js");
followNormal: true, followNormal: true,
speed: speed, speed: speed,
accelerationAxis: accelerationAxis, accelerationAxis: accelerationAxis,
rotateAccelerationWithAvatar: true,
renderStates: teleportRenderStates, renderStates: teleportRenderStates,
defaultRenderStates: teleportDefaultRenderStates defaultRenderStates: teleportDefaultRenderStates
}); });
@ -161,6 +162,7 @@ Script.include("/~/system/libraries/controllers.js");
followNormal: true, followNormal: true,
speed: speed, speed: speed,
accelerationAxis: accelerationAxis, accelerationAxis: accelerationAxis,
rotateAccelerationWithAvatar: true,
renderStates: teleportRenderStates renderStates: teleportRenderStates
}); });
this.teleportParabolaHeadVisible = Pointers.createPointer(PickType.Parabola, { this.teleportParabolaHeadVisible = Pointers.createPointer(PickType.Parabola, {
@ -172,6 +174,7 @@ Script.include("/~/system/libraries/controllers.js");
followNormal: true, followNormal: true,
speed: speed, speed: speed,
accelerationAxis: accelerationAxis, accelerationAxis: accelerationAxis,
rotateAccelerationWithAvatar: true,
renderStates: teleportRenderStates, renderStates: teleportRenderStates,
defaultRenderStates: teleportDefaultRenderStates defaultRenderStates: teleportDefaultRenderStates
}); });
@ -184,6 +187,7 @@ Script.include("/~/system/libraries/controllers.js");
followNormal: true, followNormal: true,
speed: speed, speed: speed,
accelerationAxis: accelerationAxis, accelerationAxis: accelerationAxis,
rotateAccelerationWithAvatar: true,
renderStates: teleportRenderStates 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 // 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 // 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. // you can't teleport there.
var MAX_ANGLE_FROM_UP_TO_TELEPORT = 70; var MAX_ANGLE_FROM_UP_TO_TELEPORT = 70;
function getTeleportTargetType(result) { function getTeleportTargetType(result) {
@ -426,11 +430,9 @@ Script.include("/~/system/libraries/controllers.js");
} }
var surfaceNormal = result.surfaceNormal; var surfaceNormal = result.surfaceNormal;
var adj = Math.sqrt(surfaceNormal.x * surfaceNormal.x + surfaceNormal.z * surfaceNormal.z); var angle = Math.abs(Math.acos(Vec3.dot(surfaceNormal, Quat.getUp(MyAvatar.orientation)))) * (180.0 / Math.PI);
var angleUp = Math.atan2(surfaceNormal.y, adj) * (180 / Math.PI);
if (angleUp < (90 - MAX_ANGLE_FROM_UP_TO_TELEPORT) || if (angle > MAX_ANGLE_FROM_UP_TO_TELEPORT ||
angleUp > (90 + MAX_ANGLE_FROM_UP_TO_TELEPORT) ||
Vec3.distance(MyAvatar.position, result.intersection) <= TELEPORT_CANCEL_RANGE * MyAvatar.sensorToWorldScale) { Vec3.distance(MyAvatar.position, result.intersection) <= TELEPORT_CANCEL_RANGE * MyAvatar.sensorToWorldScale) {
return TARGET.INVALID; return TARGET.INVALID;
} else { } else {