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