示例#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;
}
示例#2
0
文件: Pane.cpp 项目: kristofe/RiftRay
///@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;
}
// Check for hits against floor plane
bool Scene::RayIntersects(
    const float* pRayOrigin,
    const float* pRayDirection,
    float* pTParameter, // [inout]
    float* pHitLocation, // [inout]
    float* pHitNormal // [inout]
    ) const
{
    const glm::vec3 origin3 = glm::make_vec3(pRayOrigin);
    const glm::vec3 dir3 = glm::make_vec3(pRayDirection);

    const glm::vec3 minPt(-10.f, 0.f, -10.f);
    const glm::vec3 maxPt( 10.f, 0.f,  10.f);

    std::vector<glm::vec3> pts;
    pts.push_back(glm::vec3(minPt.x, minPt.y, minPt.z));
    pts.push_back(glm::vec3(minPt.x, minPt.y, maxPt.z));
    pts.push_back(glm::vec3(maxPt.x, minPt.y, maxPt.z));
    pts.push_back(glm::vec3(maxPt.x, minPt.y, minPt.z));

    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 cartesianpos(0.f);
    if (hit1)
    {
        // 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.
        // X coordinate of retval1 appears to be the t parameter of the intersection point along dir3.
        // Fill out the x coord with the barycentric identity then convert using simple weighted sum.
        if (retval1.x < 0.f) // Hit behind origin
            return false;
        *pTParameter = retval1.x;
        const float bary_x = 1.f - retval1.y - retval1.z;
        cartesianpos = 
               bary_x * pts[0] +
            retval1.y * pts[1] +
            retval1.z * pts[2];
    }
    else if (hit2)
    {
        if (retval2.x < 0.f) // Hit behind origin
            return false;
        *pTParameter = retval2.x;
        const float bary_x = 1.f - retval2.y - retval2.z;
        cartesianpos = 
               bary_x * pts[0] +
            retval2.y * pts[2] +
            retval2.z * pts[3];
    }

    const glm::vec3 hitPos = origin3 + *pTParameter * dir3;
    pHitLocation[0] = hitPos.x;
    pHitLocation[1] = hitPos.y;
    pHitLocation[2] = hitPos.z;

    pHitNormal[0] = 0.f;
    pHitNormal[1] = 1.f;
    pHitNormal[2] = 0.f;

    return true;
}
示例#4
0
///@param [out] planePtOut Intersection point on plane in local normalized coordinates
///@param [out] tParamOut T parameter value along intersection ray
///@return true if ray hits pane quad, false otherwise
bool HudQuad::GetPaneRayIntersectionCoordinates(
    const glm::mat4& quadPoseMatrix, ///< [in] Quad's pose in world space
    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_showQuadInWorld == false)
        return false;

    // Standard Oculus quad layer coordinates
    glm::vec3 pts[] = {
        glm::vec3(-.5f*m_quadSize.x, -.5f*m_quadSize.y, 0.f),
        glm::vec3( .5f*m_quadSize.x, -.5f*m_quadSize.y, 0.f),
        glm::vec3( .5f*m_quadSize.x,  .5f*m_quadSize.y, 0.f),
        glm::vec3(-.5f*m_quadSize.x,  .5f*m_quadSize.y, 0.f),
    };
    for (int i = 0; i < 4; ++i)
    {
        glm::vec4 p4 = glm::vec4(pts[i], 1.f);
        p4 = quadPoseMatrix * p4;
        pts[i] = glm::vec3(p4);
    }

    glm::vec3 retval1(0.f);
    glm::vec3 retval2(0.f);
    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.f);
    glm::vec3 cartesianpos(0.f);
    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.f - hitval.y - hitval.z) * pts[0] +
            hitval.y * pts[1] +
            hitval.z * pts[2];
    }
    else if (hit2)
    {
        hitval = retval2;
        cartesianpos =
            (1.f - 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;
    tParamOut = tParam;
    if (tParam < 0.f)
        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.f - glm::dot(v2 / len, vh) // y coord flipped by convention
        );

    return true;
}