///@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; }
///@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; }
///@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; }