This commit is contained in:
SamGondelman 2017-11-10 13:22:38 -08:00
parent 5a78c9ebfe
commit cbf0543646
6 changed files with 64 additions and 35 deletions

View file

@ -289,7 +289,7 @@ RenderState LaserPointer::buildRenderState(const QVariantMap& propMap) {
return RenderState(startID, pathID, endID);
}
PointerEvent LaserPointer::buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult) const {
PointerEvent LaserPointer::buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult, bool hover) const {
QUuid pickedID;
glm::vec3 intersection, surfaceNormal, direction, origin;
auto rayPickResult = std::static_pointer_cast<RayPickResult>(pickResult);

View file

@ -70,7 +70,7 @@ public:
static RenderState buildRenderState(const QVariantMap& propMap);
protected:
PointerEvent buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult) const override;
PointerEvent buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult, bool hover = true) const override;
PickedObject getHoveredObject(const PickResultPointer& pickResult) override;
Pointer::Buttons getPressedButtons() override;

View file

@ -17,8 +17,6 @@
#include "PickScriptingInterface.h"
#include <pointers/PickManager.h>
using namespace controller;
// TODO: make these configurable per pointer
static const float WEB_STYLUS_LENGTH = 0.2f;
@ -30,6 +28,10 @@ static const float TABLET_MAX_TOUCH_DISTANCE = 0.01f;
static const float HOVER_HYSTERESIS = 0.01f;
static const float TOUCH_HYSTERESIS = 0.02f;
static const float STYLUS_MOVE_DELAY = 0.33f * USECS_PER_SECOND;
static const float TOUCH_PRESS_TO_MOVE_DEADSPOT = 0.0481f;
static const float TOUCH_PRESS_TO_MOVE_DEADSPOT_SQUARED = TOUCH_PRESS_TO_MOVE_DEADSPOT * TOUCH_PRESS_TO_MOVE_DEADSPOT;
StylusPointer::StylusPointer(const QVariant& props, const OverlayID& stylusOverlay, bool hover, bool enabled) :
Pointer(DependencyManager::get<PickScriptingInterface>()->createStylusPick(props), enabled, hover),
_stylusOverlay(stylusOverlay)
@ -115,16 +117,10 @@ bool StylusPointer::shouldTrigger(const PickResultPointer& pickResult) {
float distance = stylusPickResult->distance;
// If we're triggering on an object, recalculate the distance instead of using the pickResult
glm::vec3 origin = vec3FromVariant(stylusPickResult->pickVariant["position"]);
glm::vec3 direction = -_state.surfaceNormal;
if (!_state.triggeredObject.objectID.isNull() && stylusPickResult->objectID != _state.triggeredObject.objectID) {
glm::vec3 intersection;
glm::vec3 origin = vec3FromVariant(stylusPickResult->pickVariant["position"]);
glm::vec3 direction = -_state.surfaceNormal;
if (_state.triggeredObject.type == ENTITY) {
intersection = RayPick::intersectRayWithEntityXYPlane(_state.triggeredObject.objectID, origin, direction);
} else if (_state.triggeredObject.type == OVERLAY) {
intersection = RayPick::intersectRayWithOverlayXYPlane(_state.triggeredObject.objectID, origin, direction);
}
distance = glm::dot(intersection - origin, direction);
distance = glm::dot(findIntersection(_state.triggeredObject, origin, direction) - origin, direction);
}
float hysteresis = _state.triggering ? TOUCH_HYSTERESIS * sensorScaleFactor : 0.0f;
@ -132,6 +128,9 @@ bool StylusPointer::shouldTrigger(const PickResultPointer& pickResult) {
TABLET_MAX_TOUCH_DISTANCE * sensorScaleFactor, hysteresis)) {
if (_state.triggeredObject.objectID.isNull()) {
_state.triggeredObject = PickedObject(stylusPickResult->objectID, stylusPickResult->type);
_state.intersection = findIntersection(_state.triggeredObject, origin, direction);
_state.triggerPos2D = findPos2D(_state.triggeredObject, origin);
_state.triggerStartTime = usecTimestampNow();
_state.surfaceNormal = stylusPickResult->surfaceNormal;
_state.triggering = true;
}
@ -140,6 +139,9 @@ bool StylusPointer::shouldTrigger(const PickResultPointer& pickResult) {
}
_state.triggeredObject = PickedObject();
_state.intersection = glm::vec3(NAN);
_state.triggerPos2D = glm::vec2(NAN);
_state.triggerStartTime = 0;
_state.surfaceNormal = glm::vec3(NAN);
_state.triggering = false;
return false;
@ -159,34 +161,30 @@ Pointer::Buttons StylusPointer::getPressedButtons() {
return toReturn;
}
PointerEvent StylusPointer::buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult) const {
PointerEvent StylusPointer::buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult, bool hover) const {
QUuid pickedID;
glm::vec2 pos2D;
glm::vec3 intersection, surfaceNormal, direction, origin;
auto stylusPickResult = std::static_pointer_cast<StylusPickResult>(pickResult);
if (stylusPickResult) {
intersection = stylusPickResult->intersection;
surfaceNormal = _state.surfaceNormal;
surfaceNormal = hover ? stylusPickResult->surfaceNormal : _state.surfaceNormal;
const QVariantMap& stylusTip = stylusPickResult->pickVariant;
origin = vec3FromVariant(stylusTip["position"]);
direction = -_state.surfaceNormal;
direction = -surfaceNormal;
pos2D = findPos2D(target, origin);
pickedID = stylusPickResult->objectID;
}
if (pickedID != target.objectID) {
if (target.type == ENTITY) {
intersection = RayPick::intersectRayWithEntityXYPlane(target.objectID, origin, direction);
} else if (target.type == OVERLAY) {
intersection = RayPick::intersectRayWithOverlayXYPlane(target.objectID, origin, direction);
}
}
glm::vec2 pos2D;
if (target.type == ENTITY) {
pos2D = RayPick::projectOntoEntityXYPlane(target.objectID, origin);
} else if (target.type == OVERLAY) {
pos2D = RayPick::projectOntoOverlayXYPlane(target.objectID, origin);
} else if (target.type == HUD) {
pos2D = DependencyManager::get<PickManager>()->calculatePos2DFromHUD(origin);
// If we just started triggering and we haven't moved too much, don't update intersection and pos2D
if (!_state.triggeredObject.objectID.isNull() && usecTimestampNow() - _state.triggerStartTime < STYLUS_MOVE_DELAY &&
glm::distance2(pos2D, _state.triggerPos2D) < TOUCH_PRESS_TO_MOVE_DEADSPOT_SQUARED) {
pos2D = _state.triggerPos2D;
intersection = _state.intersection;
} else if (pickedID != target.objectID) {
intersection = findIntersection(target, origin, direction);
}
return PointerEvent(pos2D, intersection, surfaceNormal, direction);
}
@ -203,4 +201,28 @@ void StylusPointer::setRenderState(const std::string& state) {
} else if (state == "disabled") {
_renderState = DISABLED;
}
}
glm::vec3 StylusPointer::findIntersection(const PickedObject& pickedObject, const glm::vec3& origin, const glm::vec3& direction) {
switch (pickedObject.type) {
case ENTITY:
return RayPick::intersectRayWithEntityXYPlane(pickedObject.objectID, origin, direction);
case OVERLAY:
return RayPick::intersectRayWithOverlayXYPlane(pickedObject.objectID, origin, direction);
default:
return glm::vec3(NAN);
}
}
glm::vec2 StylusPointer::findPos2D(const PickedObject& pickedObject, const glm::vec3& origin) {
switch (pickedObject.type) {
case ENTITY:
return RayPick::projectOntoEntityXYPlane(pickedObject.objectID, origin);
case OVERLAY:
return RayPick::projectOntoOverlayXYPlane(pickedObject.objectID, origin);
case HUD:
return DependencyManager::get<PickManager>()->calculatePos2DFromHUD(origin);
default:
return glm::vec2(NAN);
}
}

View file

@ -41,7 +41,7 @@ protected:
bool shouldHover(const PickResultPointer& pickResult) override;
bool shouldTrigger(const PickResultPointer& pickResult) override;
PointerEvent buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult) const override;
PointerEvent buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult, bool hover = true) const override;
private:
void show(const StylusTip& tip);
@ -49,9 +49,13 @@ private:
struct TriggerState {
PickedObject triggeredObject;
glm::vec3 intersection { NAN };
glm::vec2 triggerPos2D { NAN };
glm::vec3 surfaceNormal { NAN };
bool hovering { false };
quint64 triggerStartTime { 0 };
bool triggering { false };
bool hovering { false };
};
TriggerState _state;
@ -67,6 +71,9 @@ private:
const OverlayID _stylusOverlay;
static bool isWithinBounds(float distance, float min, float max, float hysteresis);
static glm::vec3 findIntersection(const PickedObject& pickedObject, const glm::vec3& origin, const glm::vec3& direction);
static glm::vec2 findPos2D(const PickedObject& pickedObject, const glm::vec3& origin);
};
#endif // hifi_StylusPointer_h

View file

@ -199,7 +199,7 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const PickResultPoin
// Trigger continue
for (const std::string& button : sameButtons) {
PointerEvent triggeredEvent = buildPointerEvent(_triggeredObjects[button], pickResult);
PointerEvent triggeredEvent = buildPointerEvent(_triggeredObjects[button], pickResult, false);
triggeredEvent.setID(pointerID);
triggeredEvent.setType(PointerEvent::Move);
triggeredEvent.setButton(chooseButton(button));
@ -214,7 +214,7 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const PickResultPoin
// Trigger end
for (const std::string& button : _prevButtons) {
PointerEvent triggeredEvent = buildPointerEvent(_triggeredObjects[button], pickResult);
PointerEvent triggeredEvent = buildPointerEvent(_triggeredObjects[button], pickResult, false);
triggeredEvent.setID(pointerID);
triggeredEvent.setType(PointerEvent::Release);
triggeredEvent.setButton(chooseButton(button));

View file

@ -82,7 +82,7 @@ protected:
bool _enabled;
bool _hover;
virtual PointerEvent buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult) const = 0;
virtual PointerEvent buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult, bool hover = true) const = 0;
virtual PickedObject getHoveredObject(const PickResultPointer& pickResult) = 0;
virtual Buttons getPressedButtons() = 0;