CollideAble implementations updated

This commit is contained in:
Dander7BD 2013-12-17 14:14:54 +01:00
parent 632570f66b
commit e8952dc739
10 changed files with 231 additions and 180 deletions

View File

@ -41,35 +41,48 @@ bool Box::Intersects( const ICollideable &target ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_universe: return true; case Type_universe: return true;
case Type_point: return Utility::Intersect( *this, *(Point*)&target ); case Type_point: return Utility::Intersect( *this, (const Point&)target );
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance ); case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target ); case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
case Type_plane: return Utility::Intersect( *this, *(Plane*)&target ); case Type_plane: return Utility::Intersect( *this, (const Plane&)target );
// case Type_triangle: return false; // TODO: : // case Type_triangle: return false; // TODO: :
case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)&target ); case Type_box_axis_aligned: return Utility::Intersect( *this, (const BoxAxisAligned&)target );
case Type_box: return Utility::Intersect( *this, *(Box*)&target ); case Type_box: return Utility::Intersect( *this, (const Box&)target );
// case Type_frustrum: return false; // TODO: : // case Type_frustrum: return false; // TODO: :
default: return false; default: return false;
} }
} }
bool Box::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const bool Box::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const
{ {
//! @todo TODO: implement stub properly switch( target.type )
return this->Intersects( target ); {
case Type_universe:
worldPointOfContact = this->center;
return true;
case Type_point: return Utility::Intersect( *this, (const Point&)target, worldPointOfContact );
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance, worldPointOfContact );
case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target, worldPointOfContact );
case Type_plane: return Utility::Intersect( *this, (const Plane&)target, worldPointOfContact );
// case Type_triangle: return false; // TODO: :
case Type_box_axis_aligned: return Utility::Intersect( *this, (const BoxAxisAligned&)target, worldPointOfContact );
case Type_box: return Utility::Intersect( *this, (const Box&)target, worldPointOfContact );
// case Type_frustrum: return false; // TODO: :
default: return false;
}
} }
bool Box::Contains( const ICollideable &target ) const bool Box::Contains( const ICollideable &target ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_point: return Utility::Intersect( *this, *(Point*)&target ); case Type_point: return Utility::Intersect( *this, (const Point&)target );
// case Type_sphere: return false; // TODO: //case Type_sphere: return false; // TODO:
// case Type_triangle: return false; // TODO: //case Type_triangle: return false; // TODO:
// case Type_box_axis_aligned: return false; // TODO: //case Type_box_axis_aligned: return false; // TODO:
// case Type_box: return false; // TODO: //case Type_box: return false; // TODO:
// case Type_frustrum: return false; // TODO: //case Type_frustrum: return false; // TODO:
default: return false; default: return false;
} }
} }

View File

@ -44,16 +44,16 @@ bool BoxAxisAligned::Intersects( const ICollideable &target ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_universe: return true; case Type_universe: return true;
case Type_point: return Utility::Intersect( *this, *(Point*)&target ); case Type_point: return Utility::Intersect( *this, (const Point&)target );
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance ); case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target ); case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
case Type_plane: return Utility::Intersect( *this, *(Plane*)&target ); case Type_plane: return Utility::Intersect( *this, (const Plane&)target );
// case Type_triangle: return false; // TODO: // case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)&target ); case Type_box_axis_aligned: return Utility::Intersect( *this, (const BoxAxisAligned&)target );
// case Type_box: return false; // TODO: // case Type_box: return false; // TODO:
// case Type_frustrum: return false; // TODO: // case Type_frustrum: return false; // TODO:
default: return false; default: return false;
} }
} }
@ -65,14 +65,15 @@ bool BoxAxisAligned::Intersects( const ICollideable &target, Float3 &worldPointO
bool BoxAxisAligned::Contains( const ICollideable &target ) const bool BoxAxisAligned::Contains( const ICollideable &target ) const
{ {
switch( target.type ) //switch( target.type )
{ //{
// case Type_point: return false; // TODO: ////case Type_point: return false; // TODO:
// case Type_sphere: return false; // TODO: ////case Type_sphere: return false; // TODO:
// case Type_triangle: return false; // TODO: ////case Type_triangle: return false; // TODO:
// case Type_box_axis_aligned: return false; // TODO: ////case Type_box_axis_aligned: return false; // TODO:
// case Type_box: return false; // TODO: ////case Type_box: return false; // TODO:
// case Type_frustrum: return false; // TODO: ////case Type_frustrum: return false; // TODO:
default: return false; //default: return false;
} //}
return false;
} }

View File

@ -198,23 +198,25 @@ void Frustrum::WriteToByte( unsigned int &nextIndex, unsigned char targetMem[] )
} }
::Utility::DynamicMemory::UniquePointer<ICollideable> Frustrum::Clone( ) const ::Utility::DynamicMemory::UniquePointer<ICollideable> Frustrum::Clone( ) const
{ return ::Utility::DynamicMemory::UniquePointer<ICollideable>( new Frustrum(*this) ); } {
return ::Utility::DynamicMemory::UniquePointer<ICollideable>( new Frustrum(*this) );
}
bool Frustrum::Intersects( const ICollideable &target ) const bool Frustrum::Intersects( const ICollideable &target ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_universe: return true; case Type_universe: return true;
case Type_point: return Utility::Intersect( *this, *(Point*)&target ); case Type_point: return Utility::Intersect( *this, (const Point&)target );
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance ); case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target ); case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
case Type_plane: return Utility::Intersect( *this, *(Plane*)&target ); case Type_plane: return Utility::Intersect( *this, (const Plane&)target );
// case Type_triangle: return false; // TODO: //case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)&target ); case Type_box_axis_aligned: return Utility::Intersect( *this, (const BoxAxisAligned&)target );
case Type_box: return Utility::Intersect( *this, *(Box*)&target ); case Type_box: return Utility::Intersect( *this, (const Box&)target );
case Type_frustrum: return Utility::Intersect( *this, *(Frustrum*)&target ); case Type_frustrum: return Utility::Intersect( *this, (const Frustrum&)target );
// case Type_line: return false; // TODO: //case Type_line: return false; // TODO:
default: return false; default: return false;
} }
} }
@ -228,15 +230,15 @@ bool Frustrum::Contains( const ICollideable &target ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_point: return Utility::Intersect( *this, *(Point*)&target ); case Type_point: return Utility::Intersect( *this, (const Point&)target );
// case Type_ray: return false; // TODO: //case Type_ray: return false; // TODO:
// case Type_sphere: return false; // TODO: //case Type_sphere: return false; // TODO:
// case Type_plane: return false; // TODO: //case Type_plane: return false; // TODO:
// case Type_triangle: return false; // TODO: //case Type_triangle: return false; // TODO:
// case Type_box_axis_aligned: return false; // TODO: //case Type_box_axis_aligned: return false; // TODO:
// case Type_box: return false; // TODO: //case Type_box: return false; // TODO:
// case Type_frustrum: return false; // TODO: //case Type_frustrum: return false; // TODO:
// case Type_line: return false; // TODO: //case Type_line: return false; // TODO:
default: return false; default: return false;
} }
} }

View File

@ -796,6 +796,20 @@ namespace Oyster { namespace Collision3D { namespace Utility
return Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( alignedOffsetBoundaries.xyz, boxA.boundingOffset, boxA.rotation, offset ); return Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( alignedOffsetBoundaries.xyz, boxA.boundingOffset, boxA.rotation, offset );
} }
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB, ::Oyster::Math::Float3 &worldPointOfContact )
{ // by Dan Andersson
Float4 alignedOffsetBoundaries = (Float4(boxB.maxVertex, 1.0f) - Float4(boxB.minVertex, 1.0f)) * 0.5f,
offset = Float4(boxA.center, 1.0f) - Average( Float4(boxB.maxVertex, 1.0f), Float4(boxB.minVertex, 1.0f) );
Float4 pointOfContact;
if( Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( alignedOffsetBoundaries.xyz, boxA.boundingOffset, boxA.rotation, offset, pointOfContact ) )
{
worldPointOfContact = pointOfContact.xyz;
return true;
}
else return false;
}
bool Intersect( const Box &boxA, const Box &boxB ) bool Intersect( const Box &boxA, const Box &boxB )
{ // by Dan Andersson { // by Dan Andersson
Float4x4 rotationB = TransformMatrix( InverseRotationMatrix(boxA.rotation), boxB.rotation ); Float4x4 rotationB = TransformMatrix( InverseRotationMatrix(boxA.rotation), boxB.rotation );
@ -812,7 +826,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
Float4 pointOfContact; Float4 pointOfContact;
if( Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( boxA.boundingOffset, boxB.boundingOffset, rotationB, posB, pointOfContact ) ) if( Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( boxA.boundingOffset, boxB.boundingOffset, rotationB, posB, pointOfContact ) )
{ {
TransformVector( boxA.rotation, pointOfContact, pointOfContact ); worldPointOfContact = TransformVector( boxA.rotation, pointOfContact, pointOfContact ).xyz;
return true; return true;
} }
else return false; else return false;

View File

@ -75,6 +75,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
bool Intersect( const Box &box, const Plane &plane, ::Oyster::Math::Float3 &worldPointOfContact ); bool Intersect( const Box &box, const Plane &plane, ::Oyster::Math::Float3 &worldPointOfContact );
// bool Intersect( const Box &box, const Triangle &triangle, ? ); // bool Intersect( const Box &box, const Triangle &triangle, ? );
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB ); bool Intersect( const Box &boxA, const BoxAxisAligned &boxB );
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Box &boxA, const Box &boxB ); bool Intersect( const Box &boxA, const Box &boxB );
bool Intersect( const Box &boxA, const Box &boxB, ::Oyster::Math::Float3 &worldPointOfContact ); bool Intersect( const Box &boxA, const Box &boxB, ::Oyster::Math::Float3 &worldPointOfContact );

View File

@ -30,40 +30,45 @@ Plane & Plane::operator = ( const Plane &plane )
} }
::Utility::DynamicMemory::UniquePointer<ICollideable> Plane::Clone( ) const ::Utility::DynamicMemory::UniquePointer<ICollideable> Plane::Clone( ) const
{ return ::Utility::DynamicMemory::UniquePointer<ICollideable>( new Plane(*this) ); } {
return ::Utility::DynamicMemory::UniquePointer<ICollideable>( new Plane(*this) );
}
bool Plane::Intersects( const ICollideable &target ) const bool Plane::Intersects( const ICollideable &target ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_universe: return true; case Type_universe: return true;
case Type_point: return Utility::Intersect( *this, *(Point*)&target ); case Type_point: return Utility::Intersect( *this, (const Point&)target );
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance ); case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target ); case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
case Type_plane: return Utility::Intersect( *this, *(Plane*)&target ); case Type_plane: return Utility::Intersect( *this, (const Plane&)target );
// case Type_triangle: return false; // TODO: //case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this ); case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this );
case Type_box: return Utility::Intersect( *(Box*)&target, *this ); case Type_box: return Utility::Intersect( (const Box&)target, *this );
case Type_frustrum: return false; // TODO: //case Type_frustrum: return false; // TODO:
case Type_line: return false; // TODO: //case Type_line: return false; // TODO:
default: return false; default: return false;
} }
} }
bool Plane::Intersects( const ICollideable &target, ::Oyster::Math::Float3 &worldPointOfContact ) const bool Plane::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_universe: return true; case Type_universe:
case Type_point: return Utility::Intersect( *this, *(Point*)&target, worldPointOfContact ); worldPointOfContact = this->normal * this->phasing;
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance, worldPointOfContact ); return true;
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target, worldPointOfContact ); case Type_point: return Utility::Intersect( *this, (const Point&)target, worldPointOfContact );
case Type_plane: return Utility::Intersect( *(Plane*)&target, *this, worldPointOfContact ); case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance, worldPointOfContact );
// case Type_triangle: return false; // TODO: case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target, worldPointOfContact );
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this, worldPointOfContact ); case Type_plane: return Utility::Intersect( (const Plane&)target, *this, worldPointOfContact );
case Type_box: return Utility::Intersect( *(Box*)&target, *this, worldPointOfContact ); //case Type_triangle: return false; // TODO:
case Type_frustrum: return false; // TODO: case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this, worldPointOfContact );
default: worldPointOfContact = NULL; case Type_box: return Utility::Intersect( (const Box&)target, *this, worldPointOfContact );
//case Type_frustrum: return false; // TODO:
default:
worldPointOfContact = Float3::null;
return false; return false;
} }
} }
@ -72,10 +77,10 @@ bool Plane::Contains( const ICollideable &target ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_point: return Utility::Intersect( *this, *(Point*)&target ); case Type_point: return Utility::Intersect( *this, (const Point&)target );
case Type_ray: return Utility::Contains( *this, *(Ray*)&target ); case Type_ray: return Utility::Contains( *this, (const Ray&)target );
case Type_plane: return Utility::Contains( *this, *(Plane*)&target ); case Type_plane: return Utility::Contains( *this, (const Plane&)target );
// case Type_triangle: return false; // TODO: //case Type_triangle: return false; // TODO:
default: return false; default: return false;
} }
} }

View File

@ -35,33 +35,36 @@ bool Point::Intersects( const ICollideable &target ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_universe: return true; case Type_universe: return true;
case Type_point: return Utility::Intersect( *this, *(Point*)&target ); case Type_point: return Utility::Intersect( *this, (const Point&)target );
case Type_ray: return Utility::Intersect( *(Ray*)&target, *this, ((Ray*)&target)->collisionDistance ); case Type_ray: return Utility::Intersect( (const Ray&)target, *this, ((const Ray&)target).collisionDistance );
case Type_sphere: return Utility::Intersect( *(Sphere*)&target, *this ); case Type_sphere: return Utility::Intersect( (const Sphere&)target, *this );
case Type_plane: return Utility::Intersect( *(Plane*)&target, *this ); case Type_plane: return Utility::Intersect( (const Plane&)target, *this );
//case Type_triangle: return false; // TODO: //case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this ); case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this );
case Type_box: return Utility::Intersect( *(Box*)&target, *this ); case Type_box: return Utility::Intersect( (const Box&)target, *this );
case Type_frustrum: return false; // TODO: //case Type_frustrum: return false; // TODO:
default: return false; default: return false;
} }
} }
bool Point::Intersects( const ICollideable &target, ::Oyster::Math::Float3 &worldPointOfContact ) const bool Point::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_universe: return true; case Type_universe:
case Type_point: return Utility::Intersect( *this, *(Point*)&target, worldPointOfContact ); worldPointOfContact = this->center;
case Type_ray: return Utility::Intersect( *(Ray*)&target, *this, ((Ray*)&target)->collisionDistance, worldPointOfContact ); return true;
case Type_sphere: return Utility::Intersect( *(Sphere*)&target, *this, worldPointOfContact ); case Type_point: return Utility::Intersect( *this, (const Point&)target, worldPointOfContact );
//case Type_plane: return Utility::Intersect( *(Plane*)&target, *this, worldPointOfContact ); case Type_ray: return Utility::Intersect( (const Ray&)target, *this, ((const Ray&)target).collisionDistance, worldPointOfContact );
// case Type_triangle: return false; // TODO: case Type_sphere: return Utility::Intersect( (const Sphere&)target, *this, worldPointOfContact );
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this, worldPointOfContact ); case Type_plane: return Utility::Intersect( (const Plane&)target, *this, worldPointOfContact );
case Type_box: return Utility::Intersect( *(Box*)&target, *this, worldPointOfContact ); //case Type_triangle: return false; // TODO:
case Type_frustrum: return false; // TODO: case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this, worldPointOfContact );
default: worldPointOfContact = NULL; case Type_box: return Utility::Intersect( (const Box&)target, *this, worldPointOfContact );
case Type_frustrum: return false; // TODO:
default:
worldPointOfContact = Float3::null;
return false; return false;
} }
} }
@ -70,7 +73,7 @@ bool Point::Contains( const ICollideable &target ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_point: return Utility::Intersect( *this, *(Point*)&target ); case Type_point: return Utility::Intersect( *this, (const Point&)target );
default: return false; default: return false;
} }
} }

View File

@ -43,34 +43,36 @@ bool Ray::Intersects( const ICollideable &target ) const
case Type_universe: case Type_universe:
this->collisionDistance = 0.0f; this->collisionDistance = 0.0f;
return true; return true;
case Type_point: return Utility::Intersect( *this, *(Point*)&target, this->collisionDistance ); case Type_point: return Utility::Intersect( *this, (const Point&)target, this->collisionDistance );
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, this->collisionDistance, ((Ray*)&target)->collisionDistance ); case Type_ray: return Utility::Intersect( *this, (const Ray&)target, this->collisionDistance, ((const Ray&)target).collisionDistance );
case Type_sphere: return Utility::Intersect( *(Sphere*)&target, *this, this->collisionDistance ); case Type_sphere: return Utility::Intersect( (const Sphere&)target, *this, this->collisionDistance );
case Type_plane: return Utility::Intersect( *(Plane*)&target, *this, this->collisionDistance ); case Type_plane: return Utility::Intersect( (const Plane&)target, *this, this->collisionDistance );
// case Type_triangle: return false; // TODO: // case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this, this->collisionDistance ); case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this, this->collisionDistance );
case Type_box: return Utility::Intersect( *(Box*)&target, *this, this->collisionDistance ); case Type_box: return Utility::Intersect( (const Box&)target, *this, this->collisionDistance );
case Type_frustrum: return false; // TODO: case Type_frustrum: return false; // TODO:
default: return false; default: return false;
} }
} }
bool Ray::Intersects( const ICollideable &target, ::Oyster::Math::Float3 &worldPointOfContact ) const bool Ray::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_universe: case Type_universe:
this->collisionDistance = 0.0f; this->collisionDistance = 0.0f;
worldPointOfContact = this->origin;
return true; return true;
case Type_point: return Utility::Intersect( *this, *(Point*)&target, this->collisionDistance, worldPointOfContact ); case Type_point: return Utility::Intersect( *this, (const Point&)target, this->collisionDistance, worldPointOfContact );
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, this->collisionDistance, ((Ray*)&target)->collisionDistance, worldPointOfContact ); case Type_ray: return Utility::Intersect( *this, (const Ray&)target, this->collisionDistance, ((const Ray&)target).collisionDistance, worldPointOfContact );
case Type_sphere: return Utility::Intersect( *(Sphere*)&target, *this, this->collisionDistance, worldPointOfContact ); case Type_sphere: return Utility::Intersect( (const Sphere&)target, *this, this->collisionDistance, worldPointOfContact );
case Type_plane: return Utility::Intersect( *(Plane*)&target, *this, this->collisionDistance, worldPointOfContact ); case Type_plane: return Utility::Intersect( (const Plane&)target, *this, this->collisionDistance, worldPointOfContact );
// case Type_triangle: return false; // TODO: //case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this, this->collisionDistance, worldPointOfContact ); case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this, this->collisionDistance, worldPointOfContact );
case Type_box: return Utility::Intersect( *(Box*)&target, *this, this->collisionDistance, worldPointOfContact ); case Type_box: return Utility::Intersect( (const Box&)target, *this, this->collisionDistance, worldPointOfContact );
case Type_frustrum: return false; // TODO: //case Type_frustrum: return false; // TODO:
default: worldPointOfContact = NULL; default:
worldPointOfContact = Float3::null;
return false; return false;
} }
} }
@ -79,8 +81,8 @@ bool Ray::Contains( const ICollideable &target ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_point: return Utility::Intersect( *this, *(Point*)&target, this->collisionDistance ); case Type_point: return Utility::Intersect( *this, (const Point&)target, this->collisionDistance );
case Type_ray: return Utility::Contains( *this, *(Ray*)&target ); case Type_ray: return Utility::Contains( *this, (const Ray&)target );
default: return false; default: return false;
} }
} }

View File

@ -26,39 +26,44 @@ Sphere & Sphere::operator = ( const Sphere &sphere )
} }
::Utility::DynamicMemory::UniquePointer<ICollideable> Sphere::Clone( ) const ::Utility::DynamicMemory::UniquePointer<ICollideable> Sphere::Clone( ) const
{ return ::Utility::DynamicMemory::UniquePointer<ICollideable>( new Sphere(*this) ); } {
return ::Utility::DynamicMemory::UniquePointer<ICollideable>( new Sphere(*this) );
}
bool Sphere::Intersects( const ICollideable &target ) const bool Sphere::Intersects( const ICollideable &target ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_universe: return true; case Type_universe: return true;
case Type_point: return Utility::Intersect( *this, *(Point*)&target ); case Type_point: return Utility::Intersect( *this, (const Point&)target );
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance ); case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target ); case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
case Type_plane: return Utility::Intersect( *(Plane*)&target, *this ); case Type_plane: return Utility::Intersect( (const Plane&)target, *this );
// case Type_triangle: return false; // TODO: //case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this ); case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this );
case Type_box: return Utility::Intersect( *(Box*)&target, *this ); case Type_box: return Utility::Intersect( (const Box&)target, *this );
case Type_frustrum: return false; // TODO: //case Type_frustrum: return false; // TODO:
default: return false; default: return false;
} }
} }
bool Sphere::Intersects( const ICollideable &target, ::Oyster::Math::Float3 &worldPointOfContact ) const bool Sphere::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_universe: return true; case Type_universe:
case Type_point: return Utility::Intersect( *this, *(Point*)&target, worldPointOfContact ); worldPointOfContact = this->center;
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance, worldPointOfContact ); return true;
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target, worldPointOfContact ); case Type_point: return Utility::Intersect( *this, (const Point&)target, worldPointOfContact );
//case Type_plane: return Utility::Intersect( *(Plane*)&target, *this, worldPointOfContact ); case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance, worldPointOfContact );
// case Type_triangle: return false; // TODO: case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target, worldPointOfContact );
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this, worldPointOfContact ); case Type_plane: return Utility::Intersect( (const Plane&)target, *this, worldPointOfContact );
case Type_box: return Utility::Intersect( *(Box*)&target, *this, worldPointOfContact ); //case Type_triangle: return false; // TODO:
case Type_frustrum: return false; // TODO: case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this, worldPointOfContact );
default: worldPointOfContact = Float3::null; case Type_box: return Utility::Intersect( (const Box&)target, *this, worldPointOfContact );
//case Type_frustrum: return false; // TODO:
default:
worldPointOfContact = Float3::null;
return false; return false;
} }
} }
@ -67,12 +72,12 @@ bool Sphere::Contains( const ICollideable &target ) const
{ {
switch( target.type ) switch( target.type )
{ {
case Type_point: return Utility::Intersect( *this, *(Point*)&target ); case Type_point: return Utility::Intersect( *this, (const Point&)target );
case Type_sphere: return Utility::Contains( *this, *(Sphere*)&target ); case Type_sphere: return Utility::Contains( *this, (const Sphere&)target );
// case Type_triangle: return false; // TODO: //case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return false; // TODO: //case Type_box_axis_aligned: return false; // TODO:
case Type_box: return false; // TODO: //case Type_box: return false; // TODO:
case Type_frustrum: return false; // TODO: //case Type_frustrum: return false; // TODO:
default: return false; default: return false;
} }
} }

View File

@ -10,20 +10,24 @@ Universe::Universe() : ICollideable(Type_universe) {}
Universe::~Universe() {} Universe::~Universe() {}
Universe & Universe::operator = ( const Universe &universe ) Universe & Universe::operator = ( const Universe &universe )
{ return *this; } {
return *this;
}
UniquePointer<ICollideable> Universe::Clone( ) const UniquePointer<ICollideable> Universe::Clone( ) const
{ return UniquePointer<ICollideable>( new Universe(*this) ); } {
return UniquePointer<ICollideable>( new Universe(*this) );
}
bool Universe::Intersects( const ICollideable &target ) const bool Universe::Intersects( const ICollideable &target ) const
{ // universe touches everything { // universe touches everything
switch( target.type ) switch( target.type )
{ {
case Type_ray: case Type_ray:
((Ray*)&target)->collisionDistance = 0.0f; ((const Ray&)target).collisionDistance = 0.0f;
break; break;
case Type_line: case Type_line:
((Line*)&target)->ray.collisionDistance = 0.0f; ((const Line&)target).ray.collisionDistance = 0.0f;
break; break;
default: break; default: break;
} }
@ -36,32 +40,32 @@ bool Universe::Intersects( const ICollideable &target, Float3 &worldPointOfConta
switch( target.type ) switch( target.type )
{ {
case Type_point: case Type_point:
worldPointOfContact = ((Point*)&target)->center; worldPointOfContact = ((const Point&)target).center;
break; break;
case Type_sphere: case Type_sphere:
worldPointOfContact = ((Sphere*)&target)->center; worldPointOfContact = ((const Sphere&)target).center;
break; break;
case Type_plane: case Type_plane:
worldPointOfContact = ((Plane*)&target)->normal * ((Plane*)&target)->phasing; worldPointOfContact = ((const Plane&)target).normal * ((const Plane&)target).phasing;
break; break;
case Type_box_axis_aligned: case Type_box_axis_aligned:
worldPointOfContact = Average( ((BoxAxisAligned*)&target)->minVertex, ((BoxAxisAligned*)&target)->maxVertex ); worldPointOfContact = Average( ((const BoxAxisAligned&)target).minVertex, ((const BoxAxisAligned&)target).maxVertex );
break; break;
case Type_box: case Type_box:
worldPointOfContact = ((Box*)&target)->center; worldPointOfContact = ((const Box&)target).center;
break; break;
case Type_frustrum: case Type_frustrum:
worldPointOfContact = Average( ((Frustrum*)&target)->leftPlane.normal * ((Frustrum*)&target)->leftPlane.phasing, ((Frustrum*)&target)->rightPlane.normal * ((Frustrum*)&target)->rightPlane.phasing ); worldPointOfContact = Average( ((const Frustrum&)target).leftPlane.normal * ((const Frustrum&)target).leftPlane.phasing, ((const Frustrum&)target).rightPlane.normal * ((const Frustrum&)target).rightPlane.phasing );
worldPointOfContact = Average( worldPointOfContact, Average( ((Frustrum*)&target)->bottomPlane.normal * ((Frustrum*)&target)->bottomPlane.phasing, ((Frustrum*)&target)->topPlane.normal * ((Frustrum*)&target)->topPlane.phasing ) ); worldPointOfContact = Average( worldPointOfContact, Average( ((const Frustrum&)target).bottomPlane.normal * ((const Frustrum&)target).bottomPlane.phasing, ((const Frustrum&)target).topPlane.normal * ((const Frustrum&)target).topPlane.phasing ) );
worldPointOfContact = Average( worldPointOfContact, Average( ((Frustrum*)&target)->nearPlane.normal * ((Frustrum*)&target)->nearPlane.phasing, ((Frustrum*)&target)->farPlane.normal * ((Frustrum*)&target)->farPlane.phasing ) ); worldPointOfContact = Average( worldPointOfContact, Average( ((const Frustrum&)target).nearPlane.normal * ((const Frustrum&)target).nearPlane.phasing, ((const Frustrum&)target).farPlane.normal * ((const Frustrum&)target).farPlane.phasing ) );
break; break;
case Type_ray: case Type_ray:
((Ray*)&target)->collisionDistance = 0.0f; ((const Ray&)target).collisionDistance = 0.0f;
worldPointOfContact = ((Ray*)&target)->origin; worldPointOfContact = ((const Ray&)target).origin;
break; break;
case Type_line: case Type_line:
((Line*)&target)->ray.collisionDistance = 0.0f; ((const Line&)target).ray.collisionDistance = 0.0f;
worldPointOfContact = ((Line*)&target)->ray.origin; worldPointOfContact = ((const Line&)target).ray.origin;
break; break;
default: default:
worldPointOfContact = Float3::null; worldPointOfContact = Float3::null;
@ -72,5 +76,6 @@ bool Universe::Intersects( const ICollideable &target, Float3 &worldPointOfConta
} }
bool Universe::Contains( const ICollideable &target ) const bool Universe::Contains( const ICollideable &target ) const
{ return true; } // universe contains everything { // universe contains everything
return true;
}