// Intersection between 2 planes public bool Intersect( Plane _p, Ray _ray ) { // Check if both planes are coplanar if ( (float) System.Math.Abs( 1.0f - _p.n.Dot(n) ) < float.Epsilon ) return false; // Let's have fun! float3 I = new float3(); _ray.Pos.Set( 0, 0, 0 ); _ray.Aim = n; if ( !_p.Intersect( _ray, ref I ) ) return false; _ray.Aim = _p.n; if ( !_p.Intersect( _ray, ref I ) ) return false; _ray.Pos = I; _ray.Aim = I - _ray.Pos; if ( !Intersect( _ray, ref I ) ) return false; _ray.Pos = I; // We have at least one point belonging to both planes! _ray.Aim = n.Cross(_p.n).Normalized; return true; }
// Helpers // Intersection between a plane and a ray public bool Intersect( Ray _Ray, ref float3 _intersection ) { float fGradient = n.Dot( _Ray.Aim ); if ( (float) System.Math.Abs( fGradient ) < float.Epsilon ) return false; // It cannot hit! (or very far away at least!) _Ray.Length = (-d - _Ray.Pos.Dot(n)) / fGradient; _intersection = _Ray.GetHitPos(); return true; }
public bool IsOutsideHitBy( Ray _Ray ) { float fDistance; float3 HitPosition; // Left | right intersection if ( System.Math.Abs( _Ray.Aim.x ) > EPSILON ) { fDistance = ( _Ray.Aim.x > 0.0f ? m_Min.x - _Ray.Pos.x : m_Max.x - _Ray.Pos.x ) / _Ray.Aim.x; if ( fDistance >= 0.0f && fDistance <= _Ray.Length ) { HitPosition = _Ray.Pos + _Ray.Aim * fDistance; if ( HitPosition.y >= m_Min.y && HitPosition.y <= m_Max.y && HitPosition.z >= m_Min.z && HitPosition.z <= m_Max.z ) { _Ray.Length = fDistance; _Ray.Datum = _Ray.Aim.x > 0.0f ? 0 : 1; return true; } } else _Ray.Datum = 6; // We notify the caller it didn't hit because of distance } // Top | bottom intersection if ( System.Math.Abs( _Ray.Aim.y ) > EPSILON ) { fDistance = ( _Ray.Aim.y > 0.0f ? m_Min.y - _Ray.Pos.y : m_Max.y - _Ray.Pos.y ) / _Ray.Aim.y; if ( fDistance >= 0.0f && fDistance <= _Ray.Length ) { HitPosition = _Ray.Pos + _Ray.Aim * fDistance; if ( HitPosition.x >= m_Min.x && HitPosition.x <= m_Max.x && HitPosition.z >= m_Min.z && HitPosition.z <= m_Max.z ) { _Ray.Length = fDistance; _Ray.Datum = _Ray.Aim.y > 0.0f ? 2 : 3; return true; } } else _Ray.Datum = 6; // We notify the caller it didn't hit because of distance } // Front | back intersection if ( System.Math.Abs( _Ray.Aim.z ) > EPSILON ) { fDistance = ( _Ray.Aim.z > 0.0f ? m_Min.z - _Ray.Pos.z : m_Max.z - _Ray.Pos.z ) / _Ray.Aim.z; if ( fDistance >= 0.0f && fDistance <= _Ray.Length ) { HitPosition = _Ray.Pos + _Ray.Aim * fDistance; if ( HitPosition.x >= m_Min.x && HitPosition.x <= m_Max.x && HitPosition.y >= m_Min.y && HitPosition.y <= m_Max.y ) { _Ray.Length = fDistance; _Ray.Datum = _Ray.Aim.z > 0.0f ? 4 : 5; return true; } } else _Ray.Datum = 6; // We notify the caller it didn't hit because of distance } return false; }
// Intersection between 3 planes public bool Intersect( Plane _p0, Plane _p1, ref float3 _intersection ) { // Compute the intersection of 2 planes first, yielding a ray Ray Hit = new Ray(); if ( !_p0.Intersect( _p1, Hit ) ) return false; // Then compute the intersection of this ray with our plane return Intersect( Hit, ref _intersection ); }
public bool IsInsideHitBy( Ray _Ray ) { float fDistance; float3 HitPosition; // Left | right intersection if ( System.Math.Abs( _Ray.Aim.x ) > EPSILON ) { fDistance = ( _Ray.Aim.x < 0.0f ? m_Min.x - _Ray.Pos.x : m_Max.x - _Ray.Pos.x ) / _Ray.Aim.x; if ( fDistance >= 0.0f && fDistance <= _Ray.Length ) { HitPosition = _Ray.Pos + _Ray.Aim * fDistance; if ( HitPosition.y >= m_Min.y && HitPosition.y <= m_Max.y && HitPosition.z >= m_Min.z && HitPosition.z <= m_Max.z ) { _Ray.Length = fDistance; _Ray.Datum = _Ray.Aim.x > 0.0f ? 1 : 0; return true; } } } // Top | bottom intersection if ( System.Math.Abs( _Ray.Aim.y ) > EPSILON ) { fDistance = ( _Ray.Aim.y < 0.0f ? m_Min.y - _Ray.Pos.y : m_Max.y - _Ray.Pos.y ) / _Ray.Aim.y; if ( fDistance >= 0.0f && fDistance <= _Ray.Length ) { HitPosition = _Ray.Pos + _Ray.Aim * fDistance; if ( HitPosition.x >= m_Min.x && HitPosition.x <= m_Max.x && HitPosition.z >= m_Min.z && HitPosition.z <= m_Max.z ) { _Ray.Length = fDistance; _Ray.Datum = _Ray.Aim.y > 0.0f ? 3 : 2; return true; } } } // Front | back intersection if ( System.Math.Abs( _Ray.Aim.z ) > EPSILON ) { fDistance = ( _Ray.Aim.z < 0.0f ? m_Min.z - _Ray.Pos.z : m_Max.z - _Ray.Pos.z ) / _Ray.Aim.z; if ( fDistance >= 0.0f && fDistance <= _Ray.Length ) { HitPosition = _Ray.Pos + _Ray.Aim * fDistance; if ( HitPosition.x >= m_Min.x && HitPosition.x <= m_Max.x && HitPosition.y >= m_Min.y && HitPosition.y <= m_Max.y ) { _Ray.Length = fDistance; _Ray.Datum = _Ray.Aim.z > 0.0f ? 5 : 4; return true; } } } return false; }
public bool IsHitBy( Ray _Ray ) { // ********** TEST RAY INTERSECTION ********** bool bHitX = false, bHitY = false, bHitZ = false; float fDistX = float.MaxValue, fDistY = float.MaxValue, fDistZ = float.MaxValue; float3 HitPosition; // Left right intersection if ( System.Math.Abs( _Ray.Aim.x ) > EPSILON ) { fDistX = ( _Ray.Aim.x > 0.0f ? System.Math.Min( m_Max.x - _Ray.Pos.x, m_Min.x - _Ray.Pos.x ) : System.Math.Max( m_Max.x - _Ray.Pos.x, m_Min.x - _Ray.Pos.x ) ) / _Ray.Aim.x; if ( fDistX >= 0.0f ) { HitPosition = _Ray.Pos + _Ray.Aim * fDistX; if ( HitPosition.y >= m_Min.y && HitPosition.y <= m_Max.y && HitPosition.z >= m_Min.z && HitPosition.z <= m_Max.z ) bHitX = true; } } // Top bottom intersection if ( System.Math.Abs( _Ray.Aim.y ) > EPSILON ) { fDistY = ( _Ray.Aim.y > 0.0f ? System.Math.Min( m_Max.y - _Ray.Pos.y, m_Min.y - _Ray.Pos.y ) : System.Math.Max( m_Max.y - _Ray.Pos.y, m_Min.y - _Ray.Pos. y) ) / _Ray.Aim.y; if ( fDistY >= 0.0f ) { HitPosition = _Ray.Pos + _Ray.Aim * fDistY; if ( HitPosition.x >= m_Min.x && HitPosition.x <= m_Max.x && HitPosition.z >= m_Min.z && HitPosition.z <= m_Max.z ) bHitY = true; } } // Front back intersection if ( System.Math.Abs( _Ray.Aim.z ) > EPSILON ) { fDistZ = ( _Ray.Aim.z > 0.0f ? System.Math.Min( m_Max.z - _Ray.Pos.z, m_Min.z - _Ray.Pos.z ) : System.Math.Max( m_Max.z - _Ray.Pos.z, m_Min.z - _Ray.Pos.z ) ) / _Ray.Aim.z; if ( fDistZ >= 0.0f ) { HitPosition = _Ray.Pos + _Ray.Aim * fDistZ; if ( HitPosition.x >= m_Min.x && HitPosition.x <= m_Max.x && HitPosition.y >= m_Min.y && HitPosition.y <= m_Max.y ) bHitZ = true; } } if ( !bHitX && !bHitY && !bHitZ ) return false; if ( fDistX < fDistY ) { if ( fDistX < fDistZ ) { if ( fDistX > _Ray.Length ) return false; // Ray is too short! _Ray.Length = fDistX; _Ray.Datum = _Ray.Aim.x > 0.0f ? 1 : 0; } else { if ( fDistZ > _Ray.Length ) return false; // Ray is too short! _Ray.Length = fDistZ; _Ray.Datum = _Ray.Aim.z > 0.0f ? 5 : 4; } } else { if ( fDistY < fDistZ ) { if ( fDistY > _Ray.Length ) return false; // Ray is too short! _Ray.Length = fDistY; _Ray.Datum = _Ray.Aim.y > 0.0f ? 3 : 2; } else { if ( fDistZ > _Ray.Length ) return false; // Ray is too short! _Ray.Length = fDistZ; _Ray.Datum = _Ray.Aim.z > 0.0f ? 5 : 4; } } return true; }
public bool Intersect( Ray _Ray ) { // ********** TEST RAY INTERSECTION (ONLY THE FACT OF INTERSECTION IS IMPORTANT THIS TIME) ********** float fDistX = float.MaxValue, fDistY = float.MaxValue, fDistZ = float.MaxValue; float3 HitPosition; // Left right intersection if ( System.Math.Abs( _Ray.Aim.x ) > EPSILON ) { fDistX = ( _Ray.Aim.x > 0.0f ? System.Math.Min( m_Max.x - _Ray.Pos.x, m_Min.x - _Ray.Pos.x ) : System.Math.Max( m_Max.x - _Ray.Pos.x, m_Min.x - _Ray.Pos.x ) ) / _Ray.Aim.x; if ( fDistX >= 0.0f ) { HitPosition = _Ray.Pos + _Ray.Aim * fDistX; if ( HitPosition.y >= m_Min.y && HitPosition.y <= m_Max.y && HitPosition.z >= m_Min.z && HitPosition.z <= m_Max.z ) return true; } } // Top bottom intersection if ( System.Math.Abs( _Ray.Aim.y ) > EPSILON ) { fDistY = ( _Ray.Aim.y > 0.0f ? System.Math.Min( m_Max.y - _Ray.Pos.y, m_Min.y - _Ray.Pos.y ) : System.Math.Max( m_Max.y - _Ray.Pos.y, m_Min.y - _Ray.Pos. y) ) / _Ray.Aim.y; if ( fDistY >= 0.0f ) { HitPosition = _Ray.Pos + _Ray.Aim * fDistY; if ( HitPosition.x >= m_Min.x && HitPosition.x <= m_Max.x && HitPosition.z >= m_Min.z && HitPosition.z <= m_Max.z ) return true; } } // Front back intersection if ( System.Math.Abs( _Ray.Aim.z ) > EPSILON ) { fDistZ = ( _Ray.Aim.z > 0.0f ? System.Math.Min( m_Max.z - _Ray.Pos.z, m_Min.z - _Ray.Pos.z ) : System.Math.Max( m_Max.z - _Ray.Pos.z, m_Min.z - _Ray.Pos.z ) ) / _Ray.Aim.z; if ( fDistZ >= 0.0f ) { HitPosition = _Ray.Pos + _Ray.Aim * fDistZ; if ( HitPosition.x >= m_Min.x && HitPosition.x <= m_Max.x && HitPosition.y >= m_Min.y && HitPosition.y <= m_Max.y ) return true; } } return false; }
public Ray( Ray _Source ) { Set( _Source ); }
// Assignment operators public void Set( Ray _r ) { m_Pos = _r.m_Pos; m_Aim = _r.m_Aim; m_Length = _r.m_Length; m_MarchedLength = _r.m_MarchedLength; m_Datum = _r.m_Datum; }