Merge pull request #15121 from danteruiz/fix-stylus-gizmo

Case 21603: Tablet x button is nearly impossible to hit with stylus
This commit is contained in:
Shannon Romano 2019-03-07 16:03:13 -08:00 committed by GitHub
commit 45ab5efcef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 40 additions and 6 deletions

View file

@ -89,6 +89,8 @@ glm::vec3 RayPick::intersectRayWithEntityXYPlane(const QUuid& entityID, const gl
return intersectRayWithXYPlane(origin, direction, props.getPosition(), props.getRotation(), props.getRegistrationPoint());
}
glm::vec2 RayPick::projectOntoXYPlane(const glm::vec3& worldPos, const glm::vec3& position, const glm::quat& rotation, const glm::vec3& dimensions, const glm::vec3& registrationPoint, bool unNormalized) {
glm::quat invRot = glm::inverse(rotation);
glm::vec3 localPos = invRot * (worldPos - position);
@ -102,6 +104,19 @@ glm::vec2 RayPick::projectOntoXYPlane(const glm::vec3& worldPos, const glm::vec3
return pos2D;
}
glm::vec2 RayPick::projectOntoXZPlane(const glm::vec3& worldPos, const glm::vec3& position, const glm::quat& rotation, const glm::vec3& dimensions, const glm::vec3& registrationPoint, bool unNormalized) {
glm::quat invRot = glm::inverse(rotation);
glm::vec3 localPos = invRot * (worldPos - position);
glm::vec3 normalizedPos = (localPos / dimensions) + registrationPoint;
glm::vec2 pos2D = glm::vec2(normalizedPos.x, (1.0f - normalizedPos.z));
if (unNormalized) {
pos2D *= glm::vec2(dimensions.x, dimensions.z);
}
return pos2D;
}
glm::vec2 RayPick::projectOntoEntityXYPlane(const QUuid& entityID, const glm::vec3& worldPos, bool unNormalized) {
EntityPropertyFlags desiredProperties;
desiredProperties += PROP_POSITION;

View file

@ -86,6 +86,7 @@ public:
static glm::vec2 projectOntoEntityXYPlane(const QUuid& entityID, const glm::vec3& worldPos, bool unNormalized = true);
static glm::vec2 projectOntoXYPlane(const glm::vec3& worldPos, const glm::vec3& position, const glm::quat& rotation, const glm::vec3& dimensions, const glm::vec3& registrationPoint, bool unNormalized);
static glm::vec2 projectOntoXZPlane(const glm::vec3& worldPos, const glm::vec3& position, const glm::quat& rotation, const glm::vec3& dimensions, const glm::vec3& registrationPoint, bool unNoemalized);
private:
static glm::vec3 intersectRayWithXYPlane(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& point, const glm::quat& rotation, const glm::vec3& registration);

View file

@ -155,15 +155,33 @@ PickResultPointer StylusPick::getEntityIntersection(const StylusTip& pick) {
const auto entityRotation = entity->getWorldOrientation();
const auto entityPosition = entity->getWorldPosition();
const auto entityType = entity->getType();
glm::vec3 normal;
glm::vec3 normal = entityRotation * Vectors::UNIT_Z;
// TODO: Use the xz projection method for Sphere and Quad.
if (entityType == EntityTypes::Gizmo) {
normal = entityRotation * Vectors::UNIT_Y;
} else {
normal = entityRotation * Vectors::UNIT_Z;
}
float distance = glm::dot(pick.position - entityPosition, normal);
if (distance < nearestTarget.distance) {
const auto entityDimensions = entity->getScaledDimensions();
const auto entityRegistrationPoint = entity->getRegistrationPoint();
glm::vec3 intersection = pick.position - (normal * distance);
glm::vec2 pos2D = RayPick::projectOntoXYPlane(intersection, entityPosition, entityRotation,
entityDimensions, entityRegistrationPoint, false);
glm::vec2 pos2D;
auto entityType = entity->getType();
if (entityType == EntityTypes::Gizmo) {
pos2D = RayPick::projectOntoXZPlane(intersection, entityPosition, entityRotation,
entityDimensions, entityRegistrationPoint, false);
} else {
pos2D = RayPick::projectOntoXYPlane(intersection, entityPosition, entityRotation,
entityDimensions, entityRegistrationPoint, false);
}
if (pos2D == glm::clamp(pos2D, glm::vec2(0), glm::vec2(1))) {
IntersectionType type = IntersectionType::ENTITY;
if (getFilter().doesPickLocalEntities()) {

View file

@ -85,7 +85,7 @@ public:
void setUnscaledDimensions(const glm::vec3& value) override;
bool shouldBePhysical() const override { return !isDead(); }
bool supportsDetailedIntersection() const override;
bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
OctreeElementPointer& element, float& distance,

View file

@ -176,7 +176,7 @@ WebTablet = function (url, width, dpi, hand, location, visible) {
this.homeButtonID = Overlays.addOverlay("circle3d", {
name: "homeButton",
localPosition: { x: HOME_BUTTON_X_OFFSET, y: HOME_BUTTON_Y_OFFSET, z: -HOME_BUTTON_Z_OFFSET },
localRotation: { x: 0, y: 1, z: 0, w: 0},
localRotation: Quat.fromVec3Degrees({ x: 180, y: 180, z: 0}),
dimensions: { x: homeButtonDim, y: homeButtonDim, z: homeButtonDim },
solid: true,
alpha: 0.0,
@ -189,7 +189,7 @@ WebTablet = function (url, width, dpi, hand, location, visible) {
this.homeButtonHighlightID = Overlays.addOverlay("circle3d", {
name: "homeButtonHighlight",
localPosition: { x: -HOME_BUTTON_X_OFFSET, y: HOME_BUTTON_Y_OFFSET, z: -HOME_BUTTON_Z_OFFSET },
localRotation: { x: 0, y: 1, z: 0, w: 0},
localRotation: Quat.fromVec3Degrees({ x: 180, y: 180, z: 0}),
dimensions: { x: homeButtonDim, y: homeButtonDim, z: homeButtonDim },
color: {red: 255, green: 255, blue: 255},
solid: true,