void PlanarPortal::teleportPointThroughPlaneA( const Vector3s& xin, Vector3s& xout ) const { // Compute coordinates of x in A and invert them const scalar nA { m_portal_multiplier.x() * planeA().n().dot( planeA().x() - xin ) }; const scalar tA0{ m_portal_multiplier.y() * planeA().t0().dot( planeA().x() - xin ) }; const scalar tA1{ m_portal_multiplier.z() * planeA().t1().dot( planeA().x() - xin ) }; // Compute the inverted coordinates in B xout = planeB().x() + nA * planeB().n() + tA0 * planeB().t0() + tA1 * planeB().t1(); }
void PlanarPortal::teleportPointThroughPlaneB( const Vector2s& xin, Vector2s& xout ) const { // Compute the translated coordinates of x in B... const scalar nB{ planeB().n().dot( planeB().x() - xin ) }; scalar tB{ planeB().t().dot( m_dx * m_plane_b.t() + planeB().x() - xin ) }; // ...accounting for periodic boundaries const int repeat_x{ int( floor( ( tB + m_bounds ) / ( 2.0 * m_bounds ) ) ) }; tB -= 2.0 * repeat_x * m_bounds; assert( tB >= -m_bounds || !isLeesEdwards() ); assert( tB <= m_bounds || !isLeesEdwards() ); // Map the coordinates to the corresponding plane xout = planeA().x() + nB * planeA().n() + tB * planeA().t(); }
Vector2s PlanarPortal::getKinematicVelocityOfPoint( const Vector2s& x ) const { assert( planeA().distanceLessThanZero( x ) != planeB().distanceLessThanZero( x ) ); if( planeA().distanceLessThanZero( x ) ) { return -m_v * m_plane_a.t(); } else { return -m_v * m_plane_b.t(); } }
void rayPlaneCollisionTests() { vxVector planeA(-5, 0, 0); vxVector planeB(5, 0, 0); vxVector planeC(5, 5, 0); // hit going forward vxRay testRay(vxVector(0, 2.5, -5), vxVector(0, 0, 1)); assert(testRay.intersect(planeA, planeB, planeC).hit); // see if it hits even if the direction is backward vxRay infiniteHitRay(vxVector(0, 2.5, -5), vxVector(0, 0, -1)); assert(infiniteHitRay.intersect(planeA, planeB, planeC).hit); }
void PlanarPortal::teleportPointThroughPlaneB( const Vector2s& xin, Vector2s& xout ) const { // Compute coordinates of x in B and invert them const scalar nB{ planeB().n().dot( m_dx_b * m_plane_b.t() + planeB().x() - xin ) }; scalar tB{ planeB().t().dot( m_dx_b * m_plane_b.t() + planeB().x() - xin ) }; // Compute the inverted coordinates in B if( m_dx_a + tB < m_bounds_a(0) ) { while( m_dx_a + tB < m_bounds_a(0) ) { tB += m_bounds_a(1) - m_bounds_a(0); } } else if( m_dx_a + tB > m_bounds_a(1) ) { while( m_dx_a + tB > m_bounds_a(1) ) { tB += m_bounds_a(0) - m_bounds_a(1); } } assert( m_dx_a + tB >= m_bounds_a(0) ); assert( m_dx_a + tB <= m_bounds_a(1) ); xout = m_dx_a * m_plane_a.t() + planeA().x() + nB * planeA().n() + tB * planeA().t(); }
void PlanarPortal::teleportPointInsidePortal( const Vector2s& xin, Vector2s& xout ) const { assert( planeA().distanceLessThanZero( xin ) != planeB().distanceLessThanZero( xin ) ); // Teleporting form A to B if( planeA().distanceLessThanZero( xin ) ) { teleportPointThroughPlaneA( xin, xout ); } // Teleporting form B to A else { teleportPointThroughPlaneB( xin, xout ); } }
void PlanarPortal::teleportPointInsidePortal( const Vector3s& xin, Vector3s& xout ) const { // Point must be in one and only one side of the portal assert( ( planeA().distanceToPoint( xin ) < 0 ) != ( planeB().distanceToPoint( xin ) < 0 ) ); // Teleporting form A to B if( planeA().distanceToPoint( xin ) < 0 ) { teleportPointThroughPlaneA( xin, xout ); } // Teleporting form B to A else { teleportPointThroughPlaneB( xin, xout ); } }
bool PlanarPortal::sphereTouchesPortal( const Vector3s& x, const scalar& r, bool& intersecting_plane_idx ) const { const bool touches_plane_A{ planeA().distanceToPoint( x ) <= r }; const bool touches_plane_B{ planeB().distanceToPoint( x ) <= r }; if( touches_plane_A && touches_plane_B ) { std::cerr << "Unhandled case in PlanarPortal::sphereTouchesPortal. Sphere can't touch both planes of a portal at once." << std::endl; std::exit( EXIT_FAILURE ); } if( touches_plane_A ) { intersecting_plane_idx = 0; } if( touches_plane_B ) { intersecting_plane_idx = 1; } return touches_plane_A || touches_plane_B; }
bool PlanarPortal::pointInsidePortal( const Vector2s& x ) const { return planeA().distanceLessThanZero( x ) || planeB().distanceLessThanZero( x ); }
bool PlanarPortal::pointInsidePortal( const Vector2s& x ) const { return planeA().distanceLessThanZero( m_dx_a * m_plane_a.t(), x ) || planeB().distanceLessThanZero( m_dx_b * m_plane_b.t(), x ); }
bool PlanarPortal::pointInsidePortal( const Vector3s& x ) const { return ( planeA().distanceToPoint( x ) < 0 ) || ( planeB().distanceToPoint( x ) < 0 ); }