HifiExperimentsallow configurable delaya5b32a62 years agoHistory
117 lines · 5.5 KB · C
RawDownload
////  Created by Sam Gondelman 7/11/2017//  Copyright 2017 High Fidelity, Inc.////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html//#ifndef hifi_RayPick_h#define hifi_RayPick_h #include <RegisteredMetaTypes.h>#include <Pick.h> class EntityItemID; class RayPickResult : public PickResult {public:    RayPickResult() {}    RayPickResult(const QVariantMap& pickVariant) : PickResult(pickVariant) {}    RayPickResult(const IntersectionType type, const QUuid& objectID, float distance, const glm::vec3& intersection, const PickRay& searchRay, const glm::vec3& surfaceNormal = glm::vec3(NAN), const QVariantMap& extraInfo = QVariantMap()) :        PickResult(searchRay.toVariantMap()), extraInfo(extraInfo), objectID(objectID), intersection(intersection), surfaceNormal(surfaceNormal), type(type), distance(distance), intersects(type != NONE) {    }     RayPickResult(const RayPickResult& rayPickResult) : PickResult(rayPickResult.pickVariant) {        type = rayPickResult.type;        intersects = rayPickResult.intersects;        objectID = rayPickResult.objectID;        distance = rayPickResult.distance;        intersection = rayPickResult.intersection;        surfaceNormal = rayPickResult.surfaceNormal;        extraInfo = rayPickResult.extraInfo;    }     QVariantMap extraInfo;    QUuid objectID;    glm::vec3 intersection { NAN };    glm::vec3 surfaceNormal { NAN };    IntersectionType type { NONE };    float distance { FLT_MAX };    bool intersects { false };     /*@jsdoc     * An intersection result for a ray pick.     *     * @typedef {object} RayPickResult     * @property {IntersectionType} type - The intersection type.     * @property {boolean} intersects - <code>true</code> if there's a valid intersection, <code>false</code> if there isn't.     * @property {Uuid} objectID - The ID of the intersected object. <code>null</code> for HUD or invalid intersections.     * @property {number} distance - The distance from the ray origin to the intersection point.     * @property {Vec3} intersection - The intersection point in world coordinates.     * @property {Vec3} surfaceNormal - The surface normal at the intersected point. All <code>NaN</code>s if <code>type ==      *     Picks.INTERSECTED_HUD</code>.     * @property {SubmeshIntersection} extraInfo - Additional intersection details for model objects, otherwise     *     <code>{ }</code>.     * @property {PickRay} searchRay - The pick ray that was used. Valid even if there is no intersection.     */    virtual QVariantMap toVariantMap() const override {        QVariantMap toReturn;        toReturn["type"] = type;        toReturn["intersects"] = intersects;        toReturn["objectID"] = objectID;        toReturn["distance"] = distance;        toReturn["intersection"] = vec3toVariant(intersection);        toReturn["surfaceNormal"] = vec3toVariant(surfaceNormal);        toReturn["searchRay"] = PickResult::toVariantMap();        toReturn["extraInfo"] = extraInfo;        return toReturn;    }     bool doesIntersect() const override { return intersects; }    bool checkOrFilterAgainstMaxDistance(float maxDistance) override { return distance < maxDistance; }     PickResultPointer compareAndProcessNewResult(const PickResultPointer& newRes) override {        auto newRayRes = std::static_pointer_cast<RayPickResult>(newRes);        if (newRayRes->distance < distance) {            return std::make_shared<RayPickResult>(*newRayRes);        } else {            return std::make_shared<RayPickResult>(*this);        }    } }; class RayPick : public Pick<PickRay> { public:    RayPick(glm::vec3 position, glm::vec3 direction, const PickFilter& filter, float maxDistance, float delayHalf, bool enabled) :        Pick(PickRay(position, direction), filter, maxDistance, enabled), _delayHalf(delayHalf) {}     PickType getType() const override { return PickType::Ray; }     PickRay getMathematicalPick() const override;     PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override { return std::make_shared<RayPickResult>(pickVariant); }    PickResultPointer getEntityIntersection(const PickRay& pick) override;    PickResultPointer getAvatarIntersection(const PickRay& pick) override;    PickResultPointer getHUDIntersection(const PickRay& pick) override;    Transform getResultTransform() const override;     void setDelay(float delay) override;     // These are helper functions for projecting and intersecting rays    static glm::vec3 intersectRayWithEntityXYPlane(const QUuid& entityID, const glm::vec3& origin, const glm::vec3& direction);    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);     float _delayHalf { 0.0f };    mutable float _prevUpdate { 0.0f };    mutable glm::vec3 _prevDirection { NAN };}; #endif // hifi_RayPick_h