Example #1
0
///@param [out] planePt Intersection point on plane in local normalized coordinates
///@return true if ray hits pane quad, false otherwise
bool Pane::GetPaneRayIntersectionCoordinates(
    glm::vec3 origin3, ///< [in] Ray origin
    glm::vec3 dir3, ///< [in] Ray direction(normalized)
    glm::vec2& planePtOut, ///< [out] Intersection point in XY plane coordinates
    float& tParamOut) ///< [out] t parameter of ray intersection (ro + t*dt)
{
    if (m_visible == false)
        return false;

    const std::vector<glm::vec3> pts = GetTransformedPanePoints();
    glm::vec3 retval1(0.0f);
    glm::vec3 retval2(0.0f);
    const bool hit1 = glm::intersectLineTriangle(origin3, dir3, pts[0], pts[1], pts[2], retval1);
    const bool hit2 = glm::intersectLineTriangle(origin3, dir3, pts[0], pts[2], pts[3], retval2);
    if ( !(hit1||hit2) )
        return false;

    glm::vec3 hitval(0.0f);
    glm::vec3 cartesianpos(0.0f);
    if (hit1)
    {
        hitval = retval1;
        // At this point, retval1 or retval2 contains hit data returned from glm::intersectLineTriangle.
        // This does not appear to be raw - y and z appear to be barycentric coordinates.
        // Fill out the x coord with the barycentric identity then convert using simple weighted sum.
        cartesianpos = 
            (1.0f - hitval.y - hitval.z) * pts[0] +
            hitval.y * pts[1] +
            hitval.z * pts[2];
    }
    else if (hit2)
    {
        hitval = retval2;
        cartesianpos = 
            (1.0f - hitval.y - hitval.z) * pts[0] +
            hitval.y * pts[2] +
            hitval.z * pts[3];
    }

    // Store the t param along controller ray of the hit in the Transformation
    // Did you know that x stores the t param val? I couldn't find this in docs anywhere.
    const float tParam = hitval.x;
    m_tx.m_controllerTParamAtClick = tParam;
    tParamOut = tParam;
    if (tParam < 0.0f)
        return false; // Behind the origin

    const glm::vec3 v1 = pts[1] - pts[0]; // x axis
    const glm::vec3 v2 = pts[3] - pts[0]; // y axis
    const float len = glm::length(v1); // v2 length should be equal
    const glm::vec3 vh = (cartesianpos - pts[0]) / len;
    planePtOut = glm::vec2(
               glm::dot(v1/len, vh),
        1.0f - glm::dot(v2/len, vh) // y coord flipped by convention
        );

    return true;
}
Example #2
0
///@param [out] planePt Intersection point on plane in local normalized coordinates
///@return true if ray hits pane quad, false otherwise
bool Pane::GetPaneRayIntersectionCoordinates(glm::vec3 origin3, glm::vec3 dir3, glm::vec2& planePt)
{
    std::vector<glm::vec3> pts = GetTransformedPanePoints();
    glm::vec3 retval1(0.0f);
    glm::vec3 retval2(0.0f);
    const bool hit1 = glm::intersectLineTriangle(origin3, dir3, pts[0], pts[1], pts[2], retval1);
    const bool hit2 = glm::intersectLineTriangle(origin3, dir3, pts[0], pts[2], pts[3], retval2);
    if ( !(hit1||hit2) )
        return false;

    glm::vec3 hitval(0.0f);
    glm::vec3 cartesianpos(0.0f);
    if (hit1)
    {
        hitval = retval1;
        // At this point, retval1 or retval2 contains hit data returned from glm::intersectLineTriangle.
        // This does not appear to be raw - y and z appear to be barycentric coordinates.
        // Fill out the x coord with the barycentric identity then convert using simple weighted sum.
        hitval.x = 1.0f - hitval.y - hitval.z;
        cartesianpos = 
            hitval.x * pts[0] +
            hitval.y * pts[1] +
            hitval.z * pts[2];
    }
    else if (hit2)
    {
        hitval = retval2;
        hitval.x = 1.0f - hitval.y - hitval.z;
        cartesianpos = 
            hitval.x * pts[0] +
            hitval.y * pts[2] +
            hitval.z * pts[3];
    }

    // Store the t param along controller ray of the hit in the Transformation
    if (m_tx.m_controllerTParamAtClick <= 0.0f)
    {
        const glm::vec3 originToHitPt = cartesianpos - origin3;
        const float tParam = glm::length(originToHitPt);
        m_tx.m_controllerTParamAtClick = tParam;
    }

    const glm::vec3 v1 = pts[1] - pts[0]; // x axis
    const glm::vec3 v2 = pts[3] - pts[0]; // y axis
    const float len = glm::length(v1); // v2 length should be equal
    const glm::vec3 vh = (cartesianpos - pts[0]) / len;
    planePt = glm::vec2(
               glm::dot(v1/len, vh),
        1.0f - glm::dot(v2/len, vh) // y coord flipped by convention
        );

    return true;
}