Merge branch 'Collision3D'

This commit is contained in:
Dander7BD 2013-11-10 02:28:46 +01:00
commit 065352e898
25 changed files with 654 additions and 626 deletions

View File

@ -24,13 +24,13 @@
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset> <PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset> <PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
@ -90,7 +90,7 @@
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -101,7 +101,7 @@
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -114,7 +114,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -129,7 +129,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -147,6 +147,11 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="OysterMath.cpp" /> <ClCompile Include="OysterMath.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Misc\Misc.vcxproj">
<Project>{2ec4dded-8f75-4c86-a10b-e1e8eb29f3ee}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>

View File

@ -3,23 +3,14 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#include "Box.h" #include "Box.h"
#include "Collision.h" #include "OysterCollision.h"
using namespace ::Oyster::Collision; using namespace ::Oyster::Collision3D;
using namespace ::Oyster::Math; using namespace ::Oyster::Math3D;
Box::Box( ) : ICollideable(ICollideable::Box), orientation(Float4x4::identity), boundingOffset() {} Box::Box( ) : ICollideable(Type_box), orientation(Float4x4::identity), boundingOffset() {}
Box::Box( const Float4x4 &o, const Float3 &s ) : ICollideable(Type_box), orientation(o), boundingOffset(s*0.5) {}
Box::Box( const Box &box ) : ICollideable(ICollideable::Box), orientation(box.orientation), boundingOffset(box.boundingOffset) Box::~Box( ) {}
{
this->orientation = box.orientation;
}
Box::Box( const Float4x4 &o, const Float3 &s ) : ICollideable(ICollideable::Box), orientation(o), boundingOffset(s*0.5)
{
this->orientation = o;
}
Box::~Box( ) { /*Nothing needs to be done here*/ }
Box & Box::operator = ( const Box &box ) Box & Box::operator = ( const Box &box )
{ {
@ -28,21 +19,22 @@ Box & Box::operator = ( const Box &box )
return *this; return *this;
} }
ICollideable* Box::clone( ) const ::Utility::Memory::UniquePointer<ICollideable> Box::Clone( ) const
{ return new Box( *this ); } { return ::Utility::Memory::UniquePointer<ICollideable>( new Box(*this) ); }
bool Box::Intersects( const ICollideable *target ) const bool Box::Intersects( const ICollideable *target ) const
{ {
switch( target->type ) switch( target->type )
{ {
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target ); case Type_universe: return true;
case ICollideable::Ray: return Utility::intersect( *this, *(Collision::Ray*)target, ((Collision::Ray*)target)->collisionDistance ); case Type_point: return Utility::Intersect( *this, *(Point*)target );
case ICollideable::Sphere: return Utility::intersect( *this, *(Collision::Sphere*)target ); case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance );
case ICollideable::Plane: return Utility::intersect( *this, *(Collision::Plane*)target ); case Type_sphere: return Utility::Intersect( *this, *(Sphere*)target );
case ICollideable::Triangle: return false; // TODO case Type_plane: return Utility::Intersect( *this, *(Plane*)target );
case ICollideable::BoxAxisAligned: return Utility::intersect( *this, *(Collision::BoxAxisAligned*)target ); case Type_triangle: return false; // TODO: :
case ICollideable::Box: return Utility::intersect( *this, *(Collision::Box*)target ); case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)target );
case ICollideable::Frustrum: return false; // TODO case Type_box: return Utility::Intersect( *this, *(Box*)target );
case Type_frustrum: return false; // TODO: :
default: return false; default: return false;
} }
} }
@ -51,15 +43,12 @@ bool Box::Contains( const ICollideable *target ) const
{ {
switch( target->type ) switch( target->type )
{ {
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target ); case Type_point: return Utility::Intersect( *this, *(Point*)target );
case ICollideable::Sphere: return false; // TODO case Type_sphere: return false; // TODO:
case ICollideable::Triangle: return false; // TODO case Type_triangle: return false; // TODO:
case ICollideable::BoxAxisAligned: return false; // TODO case Type_box_axis_aligned: return false; // TODO:
case ICollideable::Box: return false; // TODO case Type_box: return false; // TODO:
case ICollideable::Frustrum: return false; // TODO case Type_frustrum: return false; // TODO:
default: return false; default: return false;
} }
} }
ICollideable::State Box::Advanced( const ICollideable *target ) const
{ return ICollideable::Missed; } //Not supported returns 0

View File

@ -3,13 +3,13 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#pragma once #pragma once
#ifndef OYSTER_COLLISION_BOX_H #ifndef OYSTER_COLLISION_3D_BOX_H
#define OYSTER_COLLISION_BOX_H #define OYSTER_COLLISION_3D_BOX_H
#include "OysterMath.h" #include "OysterMath.h"
#include "ICollideable.h" #include "ICollideable.h"
namespace Oyster { namespace Collision namespace Oyster { namespace Collision3D
{ {
class Box : public ICollideable class Box : public ICollideable
{ {
@ -28,16 +28,14 @@ namespace Oyster { namespace Collision
}; };
Box( ); Box( );
Box( const Box &box );
Box( const ::Oyster::Math::Float4x4 &orientation, const ::Oyster::Math::Float3 &size ); Box( const ::Oyster::Math::Float4x4 &orientation, const ::Oyster::Math::Float3 &size );
~Box( ); virtual ~Box( );
Box & operator = ( const Box &box ); Box & operator = ( const Box &box );
ICollideable* clone( ) const; virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable *target ) const; bool Intersects( const ICollideable *target ) const;
bool Contains( const ICollideable *target ) const; bool Contains( const ICollideable *target ) const;
ICollideable::State Advanced( const ICollideable *target ) const; //Not supported returns 0;
}; };
} } } }

View File

@ -3,17 +3,16 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#include "BoxAxisAligned.h" #include "BoxAxisAligned.h"
#include "Collision.h" #include "OysterCollision.h"
using namespace ::Oyster::Collision; using namespace ::Oyster::Collision3D;
using namespace ::Oyster::Math; using namespace ::Oyster::Math3D;
BoxAxisAligned::BoxAxisAligned( ) : ICollideable(ICollideable::BoxAxisAligned), minVertex(-0.5f,-0.5f,-0.5f), maxVertex(0.5f,0.5f,0.5f) {} BoxAxisAligned::BoxAxisAligned( ) : ICollideable(Type_box_axis_aligned), minVertex(-0.5f,-0.5f,-0.5f), maxVertex(0.5f,0.5f,0.5f) {}
BoxAxisAligned::BoxAxisAligned( const BoxAxisAligned &box ) : ICollideable(ICollideable::BoxAxisAligned), minVertex(box.minVertex), maxVertex(box.maxVertex) {} BoxAxisAligned::BoxAxisAligned( const Float3 &_minVertex, const Float3 &_maxVertex ) : ICollideable(Type_box_axis_aligned), minVertex(_minVertex), maxVertex(_maxVertex) {}
BoxAxisAligned::BoxAxisAligned( const Float3 &_minVertex, const Float3 &_maxVertex ) : ICollideable(ICollideable::BoxAxisAligned), minVertex(_minVertex), maxVertex(_maxVertex) {}
BoxAxisAligned::BoxAxisAligned( const Float &leftClip, const Float &rightClip, const Float &topClip, const Float &bottomClip, const Float &nearClip, const Float &farClip ) BoxAxisAligned::BoxAxisAligned( const Float &leftClip, const Float &rightClip, const Float &topClip, const Float &bottomClip, const Float &nearClip, const Float &farClip )
: ICollideable(ICollideable::BoxAxisAligned), minVertex(leftClip, bottomClip, nearClip), maxVertex(rightClip, topClip, farClip) {} : ICollideable(Type_box_axis_aligned), minVertex(leftClip, bottomClip, nearClip), maxVertex(rightClip, topClip, farClip) {}
BoxAxisAligned::~BoxAxisAligned( ) { /*Nothing needs to be done here*/ } BoxAxisAligned::~BoxAxisAligned( ) {}
BoxAxisAligned & BoxAxisAligned::operator = ( const BoxAxisAligned &box ) BoxAxisAligned & BoxAxisAligned::operator = ( const BoxAxisAligned &box )
{ {
@ -22,21 +21,22 @@ BoxAxisAligned & BoxAxisAligned::operator = ( const BoxAxisAligned &box )
return *this; return *this;
} }
ICollideable* BoxAxisAligned::clone( ) const ::Utility::Memory::UniquePointer<ICollideable> BoxAxisAligned::Clone( ) const
{ return new BoxAxisAligned( *this ); } { return ::Utility::Memory::UniquePointer<ICollideable>( new BoxAxisAligned(*this) ); }
bool BoxAxisAligned::Intersects( const ICollideable *target ) const bool BoxAxisAligned::Intersects( const ICollideable *target ) const
{ {
switch( target->type ) switch( target->type )
{ {
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target ); case Type_universe: return true;
case ICollideable::Ray: return Utility::intersect( *this, *(Collision::Ray*)target, ((Collision::Ray*)target)->collisionDistance ); case Type_point: return Utility::Intersect( *this, *(Point*)target );
case ICollideable::Sphere: return Utility::intersect( *this, *(Collision::Sphere*)target ); case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance );
case ICollideable::Plane: return Utility::intersect( *this, *(Collision::Plane*)target ); case Type_sphere: return Utility::Intersect( *this, *(Sphere*)target );
case ICollideable::Triangle: return false; // TODO case Type_plane: return Utility::Intersect( *this, *(Plane*)target );
case ICollideable::BoxAxisAligned: return Utility::intersect( *this, *(Collision::BoxAxisAligned*)target ); case Type_triangle: return false; // TODO:
case ICollideable::Box: return false; // TODO case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)target );
case ICollideable::Frustrum: return false; // TODO case Type_box: return false; // TODO:
case Type_frustrum: return false; // TODO:
default: return false; default: return false;
} }
} }
@ -45,15 +45,12 @@ bool BoxAxisAligned::Contains( const ICollideable *target ) const
{ {
switch( target->type ) switch( target->type )
{ {
case ICollideable::Point: return false; // TODO case Type_point: return false; // TODO:
case ICollideable::Sphere: return false; // TODO case Type_sphere: return false; // TODO:
case ICollideable::Triangle: return false; // TODO case Type_triangle: return false; // TODO:
case ICollideable::BoxAxisAligned: return false; // TODO case Type_box_axis_aligned: return false; // TODO:
case ICollideable::Box: return false; // TODO case Type_box: return false; // TODO:
case ICollideable::Frustrum: return false; // TODO case Type_frustrum: return false; // TODO:
default: return false; default: return false;
} }
} }
ICollideable::State BoxAxisAligned::Advanced( const ICollideable *target ) const
{ return ICollideable::Missed; } //Not supported returns 0

View File

@ -3,13 +3,13 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#pragma once #pragma once
#ifndef OYSTER_COLLISION_BOXAXISALIGNED_H #ifndef OYSTER_COLLISION_3D_BOXAXISALIGNED_H
#define OYSTER_COLLISION_BOXAXISALIGNED_H #define OYSTER_COLLISION_3D_BOXAXISALIGNED_H
#include "OysterMath.h" #include "OysterMath.h"
#include "ICollideable.h" #include "ICollideable.h"
namespace Oyster { namespace Collision namespace Oyster { namespace Collision3D
{ {
class BoxAxisAligned : public ICollideable class BoxAxisAligned : public ICollideable
{ {
@ -21,17 +21,15 @@ namespace Oyster { namespace Collision
}; };
BoxAxisAligned( ); BoxAxisAligned( );
BoxAxisAligned( const BoxAxisAligned &box );
BoxAxisAligned( const ::Oyster::Math::Float3 &minVertex, const ::Oyster::Math::Float3 &maxVertex ); BoxAxisAligned( const ::Oyster::Math::Float3 &minVertex, const ::Oyster::Math::Float3 &maxVertex );
BoxAxisAligned( const ::Oyster::Math::Float &leftClip, const ::Oyster::Math::Float &rightClip, const ::Oyster::Math::Float &topClip, const ::Oyster::Math::Float &bottomClip, const ::Oyster::Math::Float &nearClip, const ::Oyster::Math::Float &farClip ); BoxAxisAligned( const ::Oyster::Math::Float &leftClip, const ::Oyster::Math::Float &rightClip, const ::Oyster::Math::Float &topClip, const ::Oyster::Math::Float &bottomClip, const ::Oyster::Math::Float &nearClip, const ::Oyster::Math::Float &farClip );
~BoxAxisAligned( ); virtual ~BoxAxisAligned( );
BoxAxisAligned & operator = ( const BoxAxisAligned &box ); BoxAxisAligned & operator = ( const BoxAxisAligned &box );
ICollideable* clone( ) const; virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable *target ) const; bool Intersects( const ICollideable *target ) const;
bool Contains( const ICollideable *target ) const; bool Contains( const ICollideable *target ) const;
ICollideable::State Advanced( const ICollideable *target ) const; //Not supported returns 0;
}; };
} } } }

View File

@ -1,104 +0,0 @@
/////////////////////////////////////////////////////////////////////
// Created by Dan Andersson 2013
/////////////////////////////////////////////////////////////////////
#pragma once
#ifndef OYSTER_COLLISION_UTILITY_H
#define OYSTER_COLLISION_UTILITY_H
#include "ICollideable.h"
#include "Point.h"
#include "Ray.h"
#include "Sphere.h"
#include "Plane.h"
//#include "Triangle.h"
#include "BoxAxisAligned.h"
#include "Box.h"
#include "Frustrum.h"
namespace Oyster { namespace Collision { namespace Utility
{
void compare( ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float &connectOffsetSquared, const Ray &ray, const Point &point );
void compare( ::Oyster::Math::Float &connectDistanceA, ::Oyster::Math::Float &connectDistanceB, ::Oyster::Math::Float &connectOffsetSquared, const Ray &rayA, const Ray &rayB );
void compare( ::Oyster::Math::Float &connectOffset, const Plane &plane, const Point &point );
bool intersect( const Point &pointA, const Point &pointB );
bool intersect( const Ray &ray, const Point &point, ::Oyster::Math::Float &connectDistance );
bool intersect( const Ray &rayA, const Ray &rayB, ::Oyster::Math::Float &connectDistanceA, ::Oyster::Math::Float &connectDistanceB );
bool intersect( const Sphere &sphere, const Point &point );
bool intersect( const Sphere &sphere, const Ray &ray, ::Oyster::Math::Float &connectDistance );
bool intersect( const Sphere &sphereA, const Sphere &sphereB );
bool intersect( const Plane &plane, const Point &point );
bool intersect( const Plane &plane, const Ray &ray, ::Oyster::Math::Float &connectDistance );
bool intersect( const Plane &plane, const Sphere &sphere );
bool intersect( const Plane &planeA, const Plane &planeB );
// bool intersect( const Triangle &triangle, const Point &point, ? );
// bool intersect( const Triangle &triangle, const Ray &ray, ? );
// bool intersect( const Triangle &triangle, const Sphere &sphere, ? );
// bool intersect( const Triangle &triangle, const Plane &plane, ? );
// bool intersect( const Triangle &triangleA, const Triangle &triangleB, ? );
bool intersect( const BoxAxisAligned &box, const Point &point );
bool intersect( const BoxAxisAligned &box, const Ray &ray, ::Oyster::Math::Float &connectDistance );
bool intersect( const BoxAxisAligned &box, const Sphere &sphere );
bool intersect( const BoxAxisAligned &box, const Plane &plane );
// bool intersect( const BoxAxisAligned &box, const Triangle &triangle );
bool intersect( const BoxAxisAligned &boxA, const BoxAxisAligned &boxB );
bool intersect( const Box &box, const Point &point );
bool intersect( const Box &box, const Ray &ray, ::Oyster::Math::Float &connectDistance );
bool intersect( const Box &box, const Sphere &sphere );
bool intersect( const Box &box, const Plane &plane );
// bool intersect( const Box &box, const Triangle &triangle, ? );
bool intersect( const Box &boxA, const BoxAxisAligned &boxB );
bool intersect( const Box &boxA, const Box &boxB );
bool intersect( const Frustrum &frustrum, const Point &point );
bool intersect( const Frustrum &frustrum, const Ray &ray, ::Oyster::Math::Float &connectDistance );
bool intersect( const Frustrum &frustrum, const Sphere &sphere );
bool intersect( const Frustrum &frustrum, const Plane &plane );
// bool intersect( const Frustrum &frustrum, const Triangle &triangle, ? );
bool intersect( const Frustrum &frustrum, const BoxAxisAligned &box );
bool intersect( const Frustrum &frustrum, const Box &box );
bool intersect( const Frustrum &frustrumA, const Frustrum &frustrumB );
bool contains( const Ray &container, const Ray &ray );
bool contains( const Sphere &container, const Sphere &sphere );
// bool contains( const Sphere &container, const Triangle &triangle );
// bool contains( const Sphere &container, const BoxAxisAligned &box );
// bool contains( const Sphere &container, const Box &box );
// bool contains( const Sphere &container, const Frustrum &frustrum );
bool contains( const Plane &container, const Point &point );
bool contains( const Plane &container, const Ray &ray );
bool contains( const Plane &container, const Plane &plane );
// bool contains( const Plane &container, const Triangle &triangle );
// bool contains( const Triangle &container, const Point &point );
// bool contains( const Triangle &container, const Triangle &triangle );
// bool contains( const BoxAxisAligned &container, const Sphere &sphere );
// bool contains( const BoxAxisAligned &container, const Triangle &triangle );
// bool contains( const BoxAxisAligned &container, const BoxAxisAligned &box );
// bool contains( const BoxAxisAligned &container, const Box &box );
// bool contains( const BoxAxisAligned &container, const Frustrum &frustrum );
// bool contains( const Box &container, const Sphere &sphere );
// bool contains( const Box &container, const Triangle &triangle );
// bool contains( const Box &container, const BoxAxisAligned &box );
// bool contains( const Box &container, const Box &box );
// bool contains( const Box &container, const Frustrum &frustrum );
// bool contains( const Frustrum &container, const Sphere &sphere );
// bool contains( const Frustrum &container, const Triangle &triangle );
// bool contains( const Frustrum &container, const BoxAxisAligned &box );
// bool contains( const Frustrum &container, const Box &box );
// bool contains( const Frustrum &container, const Frustrum &frustrum );
} } }
#endif

View File

@ -3,110 +3,105 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#include "Frustrum.h" #include "Frustrum.h"
#include "Collision.h" #include "OysterCollision.h"
using namespace Oyster::Math; using namespace Oyster::Math;
using namespace Oyster::Collision; using namespace Oyster::Collision3D;
namespace PrivateStatic namespace PrivateStatic
{ {
inline void vpToPlanes( Plane &lp, Plane &rp, Plane &bp, Plane &tp, Plane &np, Plane &fp, const Float4x4 &vp ) inline void VP_ToPlanes( Plane &lp, Plane &rp, Plane &bp, Plane &tp, Plane &np, Plane &fp, const Float4x4 &vp )
{ { /// TODO: : not verified
Float4x4 m = vp.getTranspose(); Float4x4 m = vp.GetTranspose();
// left // left
lp.normal = m.v[3].xyz + m.v[0].xyz; lp.normal = m.v[3].xyz + m.v[0].xyz;
lp.phasing = lp.normal.length(); lp.phasing = lp.normal.GetMagnitude();
lp.normal /= lp.phasing; lp.normal /= lp.phasing;
lp.phasing = (m.v[3].w + m.v[0].w) / lp.phasing; lp.phasing = (m.v[3].w + m.v[0].w) / lp.phasing;
// right // right
rp.normal = m.v[3].xyz - m.v[0].xyz; rp.normal = m.v[3].xyz - m.v[0].xyz;
rp.phasing = rp.normal.length(); rp.phasing = rp.normal.GetMagnitude();
rp.normal /= rp.phasing; rp.normal /= rp.phasing;
rp.phasing = (m.v[3].w - m.v[0].w) / rp.phasing; rp.phasing = (m.v[3].w - m.v[0].w) / rp.phasing;
// bottom // bottom
bp.normal = m.v[3].xyz + m.v[1].xyz; bp.normal = m.v[3].xyz + m.v[1].xyz;
bp.phasing = bp.normal.length(); bp.phasing = bp.normal.GetMagnitude();
bp.normal /= bp.phasing; bp.normal /= bp.phasing;
bp.phasing = (m.v[3].w + m.v[1].w) / bp.phasing; bp.phasing = (m.v[3].w + m.v[1].w) / bp.phasing;
// top // top
tp.normal = m.v[3].xyz - m.v[1].xyz; tp.normal = m.v[3].xyz - m.v[1].xyz;
tp.phasing = tp.normal.length(); tp.phasing = tp.normal.GetMagnitude();
tp.normal /= tp.phasing; tp.normal /= tp.phasing;
tp.phasing = (m.v[3].w - m.v[1].w) / tp.phasing; tp.phasing = (m.v[3].w - m.v[1].w) / tp.phasing;
// near leftHanded DirectX // near leftHanded DirectX
np.normal = m.v[2].xyz; np.normal = m.v[2].xyz;
np.phasing = np.normal.length(); np.phasing = np.normal.GetMagnitude();
np.normal /= np.phasing; np.normal /= np.phasing;
np.phasing = m.v[2].w / np.phasing; np.phasing = m.v[2].w / np.phasing;
// far lefthanded // far lefthanded
fp.normal = m.v[3].xyz - m.v[2].xyz; fp.normal = m.v[3].xyz - m.v[2].xyz;
fp.phasing = fp.normal.length(); fp.phasing = fp.normal.GetMagnitude();
fp.normal /= fp.phasing; fp.normal /= fp.phasing;
fp.phasing = (m.v[3].w - m.v[2].w) / fp.phasing; fp.phasing = (m.v[3].w - m.v[2].w) / fp.phasing;
/*/ near rightHanded openGL /*/ near rightHanded openGL
np.normal = m.v[3].xyz + m.v[2].xyz; np.normal = m.v[3].xyz + m.v[2].xyz;
np.phasing = np.normal.length(); np.phasing = np.normal.GetMagnitude();
np.normal /= np.phasing; np.normal /= np.phasing;
np.phasing = -(m.v[3].w + m.v[2].w) / np.phasing; np.phasing = -(m.v[3].w + m.v[2].w) / np.phasing;
// far rightHanded // far rightHanded
fp.normal = m.v[3].xyz - m.v[2].xyz; fp.normal = m.v[3].xyz - m.v[2].xyz;
fp.phasing = fp.normal.length(); fp.phasing = fp.normal.GetMagnitude();
fp.normal /= fp.phasing; fp.normal /= fp.phasing;
fp.phasing = -(m.v[3].w - m.v[2].w) / fp.phasing;*/ fp.phasing = -(m.v[3].w - m.v[2].w) / fp.phasing;*/
} }
void interpolatePlanes( Plane &target, const Plane &planeA, const Plane &planeB, float interpolation ) void InterpolatePlanes( Plane &target, const Plane &planeA, const Plane &planeB, float interpolation )
{ {
float counterInterpol = 1.0f - interpolation; float counterInterpol = 1.0f - interpolation;
target.normal = counterInterpol * planeA.normal; target.normal = counterInterpol * planeA.normal;
target.normal += interpolation * planeB.normal; target.normal += interpolation * planeB.normal;
target.phasing = counterInterpol * planeA.phasing; target.phasing = counterInterpol * planeA.phasing;
target.phasing += interpolation * planeB.phasing; target.phasing += interpolation * planeB.phasing;
target.normal.normalize(); target.normal.Normalize();
} }
} }
Frustrum::Frustrum( ) : ICollideable(ICollideable::Frustrum), Frustrum::Frustrum( ) : ICollideable(Type_frustrum),
leftPlane(Float3::standardUnitX, -0.5f), rightPlane(-Float3::standardUnitX, 0.5f), leftPlane(Float3::standard_unit_x, -0.5f), rightPlane(-Float3::standard_unit_x, 0.5f),
bottomPlane(Float3::standardUnitY, -0.5f), topPlane(-Float3::standardUnitY, 0.5f), bottomPlane(Float3::standard_unit_y, -0.5f), topPlane(-Float3::standard_unit_y, 0.5f),
nearPlane(Float3::standardUnitZ, -0.5f), farPlane(-Float3::standardUnitZ, 0.5f) {} nearPlane(Float3::standard_unit_z, -0.5f), farPlane(-Float3::standard_unit_z, 0.5f) {}
Frustrum::Frustrum( const Frustrum &frustrum ) : ICollideable(ICollideable::Frustrum), Frustrum::Frustrum( const Float4x4 &vp ) : ICollideable(Type_frustrum)
leftPlane(frustrum.leftPlane), rightPlane(frustrum.rightPlane), { PrivateStatic::VP_ToPlanes( this->leftPlane, this->rightPlane, this->bottomPlane, this->topPlane, this->nearPlane, this->farPlane, vp ); }
bottomPlane(frustrum.bottomPlane), topPlane(frustrum.topPlane),
nearPlane(frustrum.nearPlane), farPlane(frustrum.farPlane) {}
Frustrum::Frustrum( const Float4x4 &vp ) : ICollideable(ICollideable::Frustrum)
{ PrivateStatic::vpToPlanes( this->leftPlane, this->rightPlane, this->bottomPlane, this->topPlane, this->nearPlane, this->farPlane, vp ); }
Frustrum::~Frustrum( ) {} Frustrum::~Frustrum( ) {}
Frustrum & Frustrum::operator = ( const Frustrum &frustrum ) Frustrum & Frustrum::operator = ( const Frustrum &frustrum )
{ {
this->leftPlane = frustrum.leftPlane; this->plane[0] = frustrum.plane[0];
this->rightPlane = frustrum.rightPlane; this->plane[1] = frustrum.plane[1];
this->bottomPlane = frustrum.bottomPlane; this->plane[2] = frustrum.plane[2];
this->topPlane = frustrum.topPlane; this->plane[3] = frustrum.plane[3];
this->nearPlane = frustrum.nearPlane; this->plane[4] = frustrum.plane[4];
this->farPlane = frustrum.farPlane; this->plane[5] = frustrum.plane[5];
return *this; return *this;
} }
Frustrum & Frustrum::operator = ( const Float4x4 &vp ) Frustrum & Frustrum::operator = ( const Float4x4 &vp )
{ {
PrivateStatic::vpToPlanes( this->leftPlane, this->rightPlane, this->bottomPlane, this->topPlane, this->nearPlane, this->farPlane, vp ); PrivateStatic::VP_ToPlanes( this->leftPlane, this->rightPlane, this->bottomPlane, this->topPlane, this->nearPlane, this->farPlane, vp );
return *this; return *this;
} }
void Frustrum::split( Frustrum target[], unsigned int numX, unsigned int numY, unsigned int numZ ) const void Frustrum::Split( Frustrum target[], unsigned int numX, unsigned int numY, unsigned int numZ ) const
{ {
float incrementX = 1.0f / numX, float incrementX = 1.0f / numX,
incrementY = 1.0f / numY, incrementY = 1.0f / numY,
@ -119,9 +114,9 @@ void Frustrum::split( Frustrum target[], unsigned int numX, unsigned int numY, u
stepY = numX, stepY = numX,
stepZ = numX * numY; stepZ = numX * numY;
Collision::Plane invRight( -this->rightPlane.normal, -this->rightPlane.phasing ), Plane invRight( -this->rightPlane.normal, -this->rightPlane.phasing ),
invBottom( -this->bottomPlane.normal, -this->bottomPlane.phasing ), invBottom( -this->bottomPlane.normal, -this->bottomPlane.phasing ),
invFar( -this->farPlane.normal, -this->farPlane.phasing ); invFar( -this->farPlane.normal, -this->farPlane.phasing );
for( unsigned int iz = 0U; iz < numZ; ++iz ) for( unsigned int iz = 0U; iz < numZ; ++iz )
{ {
@ -135,7 +130,7 @@ void Frustrum::split( Frustrum target[], unsigned int numX, unsigned int numY, u
target[i].leftPlane = this->leftPlane; target[i].leftPlane = this->leftPlane;
else else
{ {
PrivateStatic::interpolatePlanes( target[i].leftPlane, this->leftPlane, invRight, interpolX ); PrivateStatic::InterpolatePlanes( target[i].leftPlane, this->leftPlane, invRight, interpolX );
unsigned int iLeft = i - 1; unsigned int iLeft = i - 1;
target[iLeft].rightPlane.normal = -target[i].leftPlane.normal; target[iLeft].rightPlane.normal = -target[i].leftPlane.normal;
@ -148,7 +143,7 @@ void Frustrum::split( Frustrum target[], unsigned int numX, unsigned int numY, u
target[i].topPlane = this->topPlane; target[i].topPlane = this->topPlane;
else else
{ {
PrivateStatic::interpolatePlanes( target[i].topPlane, this->topPlane, invBottom, interpolY ); PrivateStatic::InterpolatePlanes( target[i].topPlane, this->topPlane, invBottom, interpolY );
unsigned int iAbove = i - stepY; unsigned int iAbove = i - stepY;
target[iAbove].bottomPlane.normal = -target[i].topPlane.normal; target[iAbove].bottomPlane.normal = -target[i].topPlane.normal;
@ -161,7 +156,7 @@ void Frustrum::split( Frustrum target[], unsigned int numX, unsigned int numY, u
target[i].nearPlane = this->nearPlane; target[i].nearPlane = this->nearPlane;
else else
{ {
PrivateStatic::interpolatePlanes( target[i].nearPlane, this->nearPlane, invFar, interpolZ ); PrivateStatic::InterpolatePlanes( target[i].nearPlane, this->nearPlane, invFar, interpolZ );
unsigned int iCloser = i - stepZ; unsigned int iCloser = i - stepZ;
target[iCloser].farPlane.normal = -target[i].nearPlane.normal; target[iCloser].farPlane.normal = -target[i].nearPlane.normal;
@ -179,7 +174,7 @@ void Frustrum::split( Frustrum target[], unsigned int numX, unsigned int numY, u
} }
} }
void Frustrum::writeToByte( unsigned char targetMem[], unsigned int &nextIndex ) const void Frustrum::WriteToByte( unsigned char targetMem[], unsigned int &nextIndex ) const
{ {
Float *fMem = (Float*)&targetMem[nextIndex]; Float *fMem = (Float*)&targetMem[nextIndex];
for( int p = 0; p < 6; ++p ) for( int p = 0; p < 6; ++p )
@ -190,25 +185,26 @@ void Frustrum::writeToByte( unsigned char targetMem[], unsigned int &nextIndex )
fMem[3] = this->plane[p].element[3]; fMem[3] = this->plane[p].element[3];
fMem = &fMem[4]; fMem = &fMem[4];
} }
nextIndex += 6 * ::Utility::StaticArray::numElementsOf( this->plane[0].byte ); nextIndex += 6 * ::Utility::StaticArray::NumElementsOf( this->plane[0].byte );
} }
ICollideable* Frustrum::clone( ) const ::Utility::Memory::UniquePointer<ICollideable> Frustrum::Clone( ) const
{ return new Frustrum(*this); } { return ::Utility::Memory::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 ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target ); case Type_universe: return true;
case ICollideable::Ray: return Utility::intersect( *this, *(Collision::Ray*)target, ((Collision::Ray*)target)->collisionDistance ); case Type_point: return Utility::Intersect( *this, *(Point*)target );
case ICollideable::Sphere: return Utility::intersect( *this, *(Collision::Sphere*)target ); case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance );
case ICollideable::Plane: return Utility::intersect( *this, *(Collision::Plane*)target ); case Type_sphere: return Utility::Intersect( *this, *(Sphere*)target );
case ICollideable::Triangle: return false; // TODO case Type_plane: return Utility::Intersect( *this, *(Plane*)target );
case ICollideable::BoxAxisAligned: return Utility::intersect( *this, *(Collision::BoxAxisAligned*)target ); case Type_triangle: return false; // TODO:
case ICollideable::Box: return Utility::intersect( *this, *(Collision::Box*)target ); case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)target );
case ICollideable::Frustrum: return Utility::intersect( *this, *(Collision::Frustrum*)target ); case Type_box: return Utility::Intersect( *this, *(Box*)target );
case ICollideable::Line: return false; // TODO case Type_frustrum: return Utility::Intersect( *this, *(Frustrum*)target );
case Type_line: return false; // TODO:
default: return false; default: return false;
} }
} }
@ -217,18 +213,15 @@ bool Frustrum::Contains( const ICollideable *target ) const
{ {
switch( target->type ) switch( target->type )
{ {
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target ); case Type_point: return Utility::Intersect( *this, *(Point*)target );
case ICollideable::Ray: return false; // TODO case Type_ray: return false; // TODO:
case ICollideable::Sphere: return false; // TODO case Type_sphere: return false; // TODO:
case ICollideable::Plane: return false; // TODO case Type_plane: return false; // TODO:
case ICollideable::Triangle: return false; // TODO case Type_triangle: return false; // TODO:
case ICollideable::BoxAxisAligned: return false; // TODO case Type_box_axis_aligned: return false; // TODO:
case ICollideable::Box: return false; // TODO case Type_box: return false; // TODO:
case ICollideable::Frustrum: return false; // TODO case Type_frustrum: return false; // TODO:
case ICollideable::Line: return false; // TODO case Type_line: return false; // TODO:
default: return false; default: return false;
} }
} }
ICollideable::State Frustrum::Advanced( const ICollideable *target ) const
{ return ICollideable::Missed; } //Not supported returns 0

View File

@ -3,14 +3,14 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#pragma once #pragma once
#ifndef OYSTER_COLLISION_FRUSTRUM_H #ifndef OYSTER_COLLISION_3D_FRUSTRUM_H
#define OYSTER_COLLISION_FRUSTRUM_H #define OYSTER_COLLISION_3D_FRUSTRUM_H
#include "OysterMath.h" #include "OysterMath.h"
#include "ICollideable.h" #include "ICollideable.h"
#include "Plane.h" #include "Plane.h"
namespace Oyster { namespace Collision namespace Oyster { namespace Collision3D
{ {
class Frustrum : public ICollideable class Frustrum : public ICollideable
@ -25,20 +25,18 @@ namespace Oyster { namespace Collision
}; };
Frustrum( ); Frustrum( );
Frustrum( const Frustrum &frustrum );
Frustrum( const ::Oyster::Math::Float4x4 &viewProjection ); Frustrum( const ::Oyster::Math::Float4x4 &viewProjection );
~Frustrum( ); virtual ~Frustrum( );
Frustrum & operator = ( const Frustrum &frustrum ); Frustrum & operator = ( const Frustrum &frustrum );
Frustrum & operator = ( const ::Oyster::Math::Float4x4 &viewProjection ); Frustrum & operator = ( const ::Oyster::Math::Float4x4 &viewProjection );
void split( Frustrum targetList[], unsigned int numX, unsigned int numY = 1U, unsigned int numZ = 1u ) const; void Split( Frustrum targetList[], unsigned int numX, unsigned int numY = 1U, unsigned int numZ = 1u ) const;
void writeToByte( unsigned char targetMem[], unsigned int &nextIndex ) const; void WriteToByte( unsigned char targetMem[], unsigned int &nextIndex ) const;
ICollideable* clone( ) const; virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable *target ) const; bool Intersects( const ICollideable *target ) const;
bool Contains( const ICollideable *target ) const; bool Contains( const ICollideable *target ) const;
ICollideable::State Advanced( const ICollideable *target ) const; //Not supported returns 0;
}; };
} } } }

View File

@ -3,10 +3,11 @@
// Edited by Dan Andersson 2013 // Edited by Dan Andersson 2013
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#pragma once
#ifndef OYSTER_COLLISION_3D_ICOLLIDEABLE_H #ifndef OYSTER_COLLISION_3D_ICOLLIDEABLE_H
#define OYSTER_COLLISION_3D_ICOLLIDEABLE_H #define OYSTER_COLLISION_3D_ICOLLIDEABLE_H
#include "Utilities.h"
namespace Oyster { namespace Collision3D /// Contains a collection of 3D shapes and intercollission algorithms. namespace Oyster { namespace Collision3D /// Contains a collection of 3D shapes and intercollission algorithms.
{ {
class ICollideable class ICollideable
@ -31,7 +32,7 @@ namespace Oyster { namespace Collision3D /// Contains a collection of 3D shapes
ICollideable( Type type = Type_undefined ); ICollideable( Type type = Type_undefined );
virtual ICollideable* clone( ) const = 0; // TODO: use smart unique pointer here virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const = 0;
virtual bool Intersects( const ICollideable *target ) const = 0; virtual bool Intersects( const ICollideable *target ) const = 0;
virtual bool Contains( const ICollideable *target ) const = 0; virtual bool Contains( const ICollideable *target ) const = 0;
}; };

View File

@ -3,16 +3,15 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#include "Line.h" #include "Line.h"
#include "Collision.h" #include "OysterCollision.h"
using namespace ::Oyster::Collision; using namespace ::Oyster::Collision3D;
using namespace ::Oyster::Math; using namespace ::Oyster::Math3D;
Line::Line( ) : ICollideable(ICollideable::Line), ray(), length(0.0f) {} Line::Line( ) : ICollideable(Type_line), ray(), length(0.0f) {}
Line::Line( const Line &_line ) : ICollideable(ICollideable::Line), ray(_line.ray), length(_line.length) {} Line::Line( const class Ray &_ray, const Float &_length ) : ICollideable(Type_line), ray(_ray), length(_length) {}
Line::Line( const class Ray &_ray, const Float &_length ) : ICollideable(ICollideable::Line), ray(_ray), length(_length) {} Line::Line( const Float3 &origin, const Float3 &normalizedDirection, const Float &_length ) : ICollideable(Type_line), ray(origin, normalizedDirection), length(_length) {}
Line::Line( const Float3 &origin, const Float3 &normalizedDirection, const Float &_length ) : ICollideable(ICollideable::Line), ray(origin, normalizedDirection), length(_length) {} Line::~Line( ) {}
Line::~Line( ) { /*Nothing needs to be done here*/ }
Line & Line::operator = ( const Line &line ) Line & Line::operator = ( const Line &line )
{ {
@ -21,20 +20,23 @@ Line & Line::operator = ( const Line &line )
return *this; return *this;
} }
ICollideable* Line::clone( ) const ::Utility::Memory::UniquePointer<ICollideable> Line::Clone( ) const
{ return new Line(*this); } { return ::Utility::Memory::UniquePointer<ICollideable>( new Line(*this) ); }
bool Line::Intersects( const ICollideable *target ) const bool Line::Intersects( const ICollideable *target ) const
{ {
if( target->type == Type_universe )
{
this->ray.collisionDistance = 0.0f;
return true;
}
if( this->ray.Intersects( target ) ) if( this->ray.collisionDistance >= 0.0f ) if( this->ray.collisionDistance <= this->length ) if( this->ray.Intersects( target ) ) if( this->ray.collisionDistance >= 0.0f ) if( this->ray.collisionDistance <= this->length )
return true; return true;
this->ray.collisionDistance = 0.0f; this->ray.collisionDistance = 0.0f;
return false; return false;
} }
bool Line::Contains( const ICollideable *target ) const bool Line::Contains( const ICollideable *target ) const
{ /*TODO*/ return false; } { /* TODO: : */ return false; }
ICollideable::State Line::Advanced( const ICollideable *target ) const
{ return ICollideable::Missed; } //Not supported returns 0

View File

@ -3,14 +3,14 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#pragma once #pragma once
#ifndef OYSTER_COLLISION_LINE_H #ifndef OYSTER_COLLISION_3D_LINE_H
#define OYSTER_COLLISION_LINE_H #define OYSTER_COLLISION_3D_LINE_H
#include "OysterMath.h" #include "OysterMath.h"
#include "ICollideable.h" #include "ICollideable.h"
#include "Ray.h" #include "Ray.h"
namespace Oyster { namespace Collision namespace Oyster { namespace Collision3D
{ {
class Line : public ICollideable class Line : public ICollideable
{ {
@ -22,17 +22,15 @@ namespace Oyster { namespace Collision
}; };
Line( ); Line( );
Line( const Line &line );
Line( const class Ray &ray, const ::Oyster::Math::Float &length ); Line( const class Ray &ray, const ::Oyster::Math::Float &length );
Line( const ::Oyster::Math::Float3 &origin, const ::Oyster::Math::Float3 &normalizedDirection, const ::Oyster::Math::Float &length ); Line( const ::Oyster::Math::Float3 &origin, const ::Oyster::Math::Float3 &normalizedDirection, const ::Oyster::Math::Float &length );
~Line( ); virtual ~Line( );
Line & operator = ( const Line &line ); Line & operator = ( const Line &line );
ICollideable* clone( ) const; virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable *target ) const; bool Intersects( const ICollideable *target ) const;
bool Contains( const ICollideable *target ) const; bool Contains( const ICollideable *target ) const;
ICollideable::State Advanced( const ICollideable *target ) const; //Not supported returns 0;
}; };
} } } }

View File

@ -2,13 +2,13 @@
// Created by Dan Andersson 2013 // Created by Dan Andersson 2013
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#include "Collision.h" #include "OysterCollision.h"
#include "Utilities.h" #include "Utilities.h"
#include <limits> #include <limits>
using namespace Oyster::Math; using namespace Oyster::Math3D;
namespace Oyster { namespace Collision { namespace Utility namespace Oyster { namespace Collision3D { namespace Utility
{ {
// PRIVATE HEADER /////////////////////////////////////////////////// // PRIVATE HEADER ///////////////////////////////////////////////////
@ -17,30 +17,30 @@ namespace Oyster { namespace Collision { namespace Utility
const Float epsilon = (const Float)1e-20; const Float epsilon = (const Float)1e-20;
// Float calculations can suffer roundingerrors. Which is where epsilon = 1e-20 comes into the picture // Float calculations can suffer roundingerrors. Which is where epsilon = 1e-20 comes into the picture
inline bool equalsZero( const Float &value ) inline bool EqualsZero( const Float &value )
{ // by Dan Andersson { // by Dan Andersson
return ::Utility::Value::abs( value ) < epsilon; return ::Utility::Value::Abs( value ) < epsilon;
} }
// Float calculations can suffer roundingerrors. Which is where epsilon = 1e-20 comes into the picture // Float calculations can suffer roundingerrors. Which is where epsilon = 1e-20 comes into the picture
inline bool notEqualsZero( const Float &value ) inline bool NotEqualsZero( const Float &value )
{ // by Dan Andersson { // by Dan Andersson
return ::Utility::Value::abs( value ) > epsilon; return ::Utility::Value::Abs( value ) > epsilon;
} }
// returns true if miss/reject // returns true if miss/reject
bool boxVsRayPerSlabCheck( const Float3 &axis, const Float &boundingOffset, const Float3 &deltaPos, const Float3 rayDirection, Float &tMin, Float &tMax ) bool BoxVsRayPerSlabCheck( const Float3 &axis, const Float &boundingOffset, const Float3 &deltaPos, const Float3 rayDirection, Float &tMin, Float &tMax )
{ // by Dan Andersson { // by Dan Andersson
Float e = axis.dot( deltaPos ), Float e = axis.Dot( deltaPos ),
f = axis.dot( rayDirection ); f = axis.Dot( rayDirection );
if( equalsZero(f) ) // if axis is not parallell with ray if( EqualsZero(f) ) // if axis is not parallell with ray
{ {
Float t1 = e + boundingOffset, Float t1 = e + boundingOffset,
t2 = e - boundingOffset; t2 = e - boundingOffset;
t1 /= f; t2 /= f; t1 /= f; t2 /= f;
if( t1 > t2 ) ::Utility::Element::swap( t1, t2 ); if( t1 > t2 ) ::Utility::Element::Swap( t1, t2 );
tMin = ::Utility::Value::max( tMin, t1 ); tMin = ::Utility::Value::Max( tMin, t1 );
tMax = ::Utility::Value::min( tMax, t2 ); tMax = ::Utility::Value::Min( tMax, t2 );
if( tMin > tMax ) return true; if( tMin > tMax ) return true;
if( tMax < 0.0f ) return true; if( tMax < 0.0f ) return true;
} }
@ -50,116 +50,116 @@ namespace Oyster { namespace Collision { namespace Utility
return false; return false;
} }
inline bool contains( const Plane &container, const Float3 &pos ) inline bool Contains( const Plane &container, const Float3 &pos )
{ // by Dan Andersson { // by Dan Andersson
return equalsZero( container.normal.dot( pos ) + container.phasing ); return EqualsZero( container.normal.Dot( pos ) + container.phasing );
} }
inline void compare( Float &connectOffset, const Plane &plane, const Float3 &pos ) inline void Compare( Float &connectOffset, const Plane &plane, const Float3 &pos )
{ // by Dan Andersson { // by Dan Andersson
connectOffset = plane.normal.dot(pos); connectOffset = plane.normal.Dot(pos);
connectOffset += plane.phasing; connectOffset += plane.phasing;
} }
void compare( Float &boxExtend, Float &centerDistance, const Plane &plane, const BoxAxisAligned &box ) void Compare( Float &boxExtend, Float &centerDistance, const Plane &plane, const BoxAxisAligned &box )
{ // by Dan Andersson { // by Dan Andersson
Float3 c = (box.maxVertex + box.minVertex) * 0.5f, // box.Center Float3 c = (box.maxVertex + box.minVertex) * 0.5f, // box.Center
h = (box.maxVertex - box.minVertex) * 0.5f; // box.halfSize h = (box.maxVertex - box.minVertex) * 0.5f; // box.halfSize
boxExtend = h.x * ::Utility::Value::abs(plane.normal.x); // Box max extending towards plane boxExtend = h.x * ::Utility::Value::Abs(plane.normal.x); // Box max extending towards plane
boxExtend += h.y * ::Utility::Value::abs(plane.normal.y); boxExtend += h.y * ::Utility::Value::Abs(plane.normal.y);
boxExtend += h.z * ::Utility::Value::abs(plane.normal.z); boxExtend += h.z * ::Utility::Value::Abs(plane.normal.z);
centerDistance = c.dot(plane.normal) + plane.phasing; // distance between box center and plane centerDistance = c.Dot(plane.normal) + plane.phasing; // distance between box center and plane
} }
void compare( Float &boxExtend, Float &centerDistance, const Plane &plane, const Box &box ) void Compare( Float &boxExtend, Float &centerDistance, const Plane &plane, const Box &box )
{ // by Dan Andersson { // by Dan Andersson
boxExtend = box.boundingOffset.x * ::Utility::Value::abs(plane.normal.dot(box.orientation.v[0].xyz)); // Box max extending towards plane boxExtend = box.boundingOffset.x * ::Utility::Value::Abs(plane.normal.Dot(box.orientation.v[0].xyz)); // Box max extending towards plane
boxExtend += box.boundingOffset.y * ::Utility::Value::abs(plane.normal.dot(box.orientation.v[1].xyz)); boxExtend += box.boundingOffset.y * ::Utility::Value::Abs(plane.normal.Dot(box.orientation.v[1].xyz));
boxExtend += box.boundingOffset.z * ::Utility::Value::abs(plane.normal.dot(box.orientation.v[2].xyz)); boxExtend += box.boundingOffset.z * ::Utility::Value::Abs(plane.normal.Dot(box.orientation.v[2].xyz));
centerDistance = box.orientation.v[3].xyz.dot(plane.normal) + plane.phasing; // distance between box center and plane centerDistance = box.orientation.v[3].xyz.Dot(plane.normal) + plane.phasing; // distance between box center and plane
} }
bool fifteenAxisVsAlignedAxisOverlappingChecks( const Float3 &boundingOffsetA, const Float3 &boundingOffsetB, const Float4x4 &orientationB ) bool FifteenAxisVsAlignedAxisOverlappingChecks( const Float3 &boundingOffsetA, const Float3 &boundingOffsetB, const Float4x4 &orientationB )
{ // by Dan Andersson { // by Dan Andersson
Float4x4 absOrientationB; Float4x4 absOrientationB;
{ {
Float4x4 tO = orientationB.getTranspose(); Float4x4 tO = orientationB.GetTranspose();
absOrientationB.v[0] = ::Utility::Value::abs(tO.v[0]); absOrientationB.v[0] = ::Utility::Value::Abs(tO.v[0]);
if( absOrientationB.v[0].w > boundingOffsetA.x + boundingOffsetB.dot(absOrientationB.v[0].xyz) ) return false; if( absOrientationB.v[0].w > boundingOffsetA.x + boundingOffsetB.Dot(absOrientationB.v[0].xyz) ) return false;
absOrientationB.v[1] = ::Utility::Value::abs(tO.v[1]); absOrientationB.v[1] = ::Utility::Value::Abs(tO.v[1]);
if( absOrientationB.v[1].w > boundingOffsetA.y + boundingOffsetB.dot(absOrientationB.v[1].xyz) ) return false; if( absOrientationB.v[1].w > boundingOffsetA.y + boundingOffsetB.Dot(absOrientationB.v[1].xyz) ) return false;
absOrientationB.v[2] = ::Utility::Value::abs(tO.v[2]); absOrientationB.v[2] = ::Utility::Value::Abs(tO.v[2]);
if( absOrientationB.v[2].w > boundingOffsetA.z + boundingOffsetB.dot(absOrientationB.v[2].xyz) ) return false; if( absOrientationB.v[2].w > boundingOffsetA.z + boundingOffsetB.Dot(absOrientationB.v[2].xyz) ) return false;
} }
absOrientationB.transpose(); absOrientationB.Transpose();
if( ::Utility::Value::abs(orientationB.v[3].dot(orientationB.v[0])) > boundingOffsetB.x + boundingOffsetA.dot(absOrientationB.v[0].xyz) ) return false; if( ::Utility::Value::Abs(orientationB.v[3].Dot(orientationB.v[0])) > boundingOffsetB.x + boundingOffsetA.Dot(absOrientationB.v[0].xyz) ) return false;
if( ::Utility::Value::abs(orientationB.v[3].dot(orientationB.v[1])) > boundingOffsetB.x + boundingOffsetA.dot(absOrientationB.v[1].xyz) ) return false; if( ::Utility::Value::Abs(orientationB.v[3].Dot(orientationB.v[1])) > boundingOffsetB.x + boundingOffsetA.Dot(absOrientationB.v[1].xyz) ) return false;
if( ::Utility::Value::abs(orientationB.v[3].dot(orientationB.v[2])) > boundingOffsetB.x + boundingOffsetA.dot(absOrientationB.v[2].xyz) ) return false; if( ::Utility::Value::Abs(orientationB.v[3].Dot(orientationB.v[2])) > boundingOffsetB.x + boundingOffsetA.Dot(absOrientationB.v[2].xyz) ) return false;
// ( 1,0,0 ) x orientationB.v[0].xyz: // ( 1,0,0 ) x orientationB.v[0].xyz:
Float d = boundingOffsetA.y * absOrientationB.v[0].z; Float d = boundingOffsetA.y * absOrientationB.v[0].z;
d += boundingOffsetA.z * absOrientationB.v[0].y; d += boundingOffsetA.z * absOrientationB.v[0].y;
d += boundingOffsetB.y * absOrientationB.v[2].x; d += boundingOffsetB.y * absOrientationB.v[2].x;
d += boundingOffsetB.z * absOrientationB.v[1].x; d += boundingOffsetB.z * absOrientationB.v[1].x;
if( ::Utility::Value::abs(orientationB.v[3].z*orientationB.v[0].y - orientationB.v[3].y*orientationB.v[0].z) > d ) return false; if( ::Utility::Value::Abs(orientationB.v[3].z*orientationB.v[0].y - orientationB.v[3].y*orientationB.v[0].z) > d ) return false;
// ( 1,0,0 ) x orientationB.v[1].xyz: // ( 1,0,0 ) x orientationB.v[1].xyz:
d = boundingOffsetA.y * absOrientationB.v[1].z; d = boundingOffsetA.y * absOrientationB.v[1].z;
d += boundingOffsetA.z * absOrientationB.v[1].y; d += boundingOffsetA.z * absOrientationB.v[1].y;
d += boundingOffsetB.x * absOrientationB.v[2].x; d += boundingOffsetB.x * absOrientationB.v[2].x;
d += boundingOffsetB.z * absOrientationB.v[0].x; d += boundingOffsetB.z * absOrientationB.v[0].x;
if( ::Utility::Value::abs(orientationB.v[3].z*orientationB.v[1].y - orientationB.v[3].y*orientationB.v[1].z) > d ) return false; if( ::Utility::Value::Abs(orientationB.v[3].z*orientationB.v[1].y - orientationB.v[3].y*orientationB.v[1].z) > d ) return false;
// ( 1,0,0 ) x orientationB.v[2].xyz: // ( 1,0,0 ) x orientationB.v[2].xyz:
d = boundingOffsetA.y * absOrientationB.v[2].z; d = boundingOffsetA.y * absOrientationB.v[2].z;
d += boundingOffsetA.z * absOrientationB.v[2].y; d += boundingOffsetA.z * absOrientationB.v[2].y;
d += boundingOffsetB.x * absOrientationB.v[1].x; d += boundingOffsetB.x * absOrientationB.v[1].x;
d += boundingOffsetB.y * absOrientationB.v[0].x; d += boundingOffsetB.y * absOrientationB.v[0].x;
if( ::Utility::Value::abs(orientationB.v[3].z*orientationB.v[2].y - orientationB.v[3].y*orientationB.v[2].z) > d ) return false; if( ::Utility::Value::Abs(orientationB.v[3].z*orientationB.v[2].y - orientationB.v[3].y*orientationB.v[2].z) > d ) return false;
// ( 0,1,0 ) x orientationB.v[0].xyz: // ( 0,1,0 ) x orientationB.v[0].xyz:
d = boundingOffsetA.x * absOrientationB.v[0].z; d = boundingOffsetA.x * absOrientationB.v[0].z;
d += boundingOffsetA.z * absOrientationB.v[0].x; d += boundingOffsetA.z * absOrientationB.v[0].x;
d += boundingOffsetB.y * absOrientationB.v[2].y; d += boundingOffsetB.y * absOrientationB.v[2].y;
d += boundingOffsetB.z * absOrientationB.v[1].y; d += boundingOffsetB.z * absOrientationB.v[1].y;
if( ::Utility::Value::abs(orientationB.v[3].x*orientationB.v[0].z - orientationB.v[3].z*orientationB.v[0].x) > d ) return false; if( ::Utility::Value::Abs(orientationB.v[3].x*orientationB.v[0].z - orientationB.v[3].z*orientationB.v[0].x) > d ) return false;
// ( 0,1,0 ) x orientationB.v[1].xyz: // ( 0,1,0 ) x orientationB.v[1].xyz:
d = boundingOffsetA.x * absOrientationB.v[1].z; d = boundingOffsetA.x * absOrientationB.v[1].z;
d += boundingOffsetA.z * absOrientationB.v[1].x; d += boundingOffsetA.z * absOrientationB.v[1].x;
d += boundingOffsetB.x * absOrientationB.v[2].y; d += boundingOffsetB.x * absOrientationB.v[2].y;
d += boundingOffsetB.z * absOrientationB.v[0].y; d += boundingOffsetB.z * absOrientationB.v[0].y;
if( ::Utility::Value::abs(orientationB.v[3].x*orientationB.v[1].z - orientationB.v[3].z*orientationB.v[1].x) > d ) return false; if( ::Utility::Value::Abs(orientationB.v[3].x*orientationB.v[1].z - orientationB.v[3].z*orientationB.v[1].x) > d ) return false;
// ( 0,1,0 ) x orientationB.v[2].xyz: // ( 0,1,0 ) x orientationB.v[2].xyz:
d = boundingOffsetA.x * absOrientationB.v[2].z; d = boundingOffsetA.x * absOrientationB.v[2].z;
d += boundingOffsetA.z * absOrientationB.v[2].x; d += boundingOffsetA.z * absOrientationB.v[2].x;
d += boundingOffsetB.x * absOrientationB.v[1].y; d += boundingOffsetB.x * absOrientationB.v[1].y;
d += boundingOffsetB.y * absOrientationB.v[0].y; d += boundingOffsetB.y * absOrientationB.v[0].y;
if( ::Utility::Value::abs(orientationB.v[3].x*orientationB.v[2].z - orientationB.v[3].z*orientationB.v[2].x) > d ) return false; if( ::Utility::Value::Abs(orientationB.v[3].x*orientationB.v[2].z - orientationB.v[3].z*orientationB.v[2].x) > d ) return false;
// ( 0,0,1 ) x orientationB.v[0].xyz: // ( 0,0,1 ) x orientationB.v[0].xyz:
d = boundingOffsetA.x * absOrientationB.v[0].y; d = boundingOffsetA.x * absOrientationB.v[0].y;
d += boundingOffsetA.y * absOrientationB.v[0].x; d += boundingOffsetA.y * absOrientationB.v[0].x;
d += boundingOffsetB.y * absOrientationB.v[2].z; d += boundingOffsetB.y * absOrientationB.v[2].z;
d += boundingOffsetB.z * absOrientationB.v[1].z; d += boundingOffsetB.z * absOrientationB.v[1].z;
if( ::Utility::Value::abs(orientationB.v[3].y*orientationB.v[0].x - orientationB.v[3].x*orientationB.v[0].y) > d ) return false; if( ::Utility::Value::Abs(orientationB.v[3].y*orientationB.v[0].x - orientationB.v[3].x*orientationB.v[0].y) > d ) return false;
// ( 0,0,1 ) x orientationB.v[1].xyz: // ( 0,0,1 ) x orientationB.v[1].xyz:
d = boundingOffsetA.x * absOrientationB.v[1].y; d = boundingOffsetA.x * absOrientationB.v[1].y;
d += boundingOffsetA.y * absOrientationB.v[1].x; d += boundingOffsetA.y * absOrientationB.v[1].x;
d += boundingOffsetB.x * absOrientationB.v[2].z; d += boundingOffsetB.x * absOrientationB.v[2].z;
d += boundingOffsetB.z * absOrientationB.v[0].z; d += boundingOffsetB.z * absOrientationB.v[0].z;
if( ::Utility::Value::abs(orientationB.v[3].y*orientationB.v[1].x - orientationB.v[3].x*orientationB.v[1].y) > d ) return false; if( ::Utility::Value::Abs(orientationB.v[3].y*orientationB.v[1].x - orientationB.v[3].x*orientationB.v[1].y) > d ) return false;
// ( 0,0,1 ) x orientationB.v[2].xyz: // ( 0,0,1 ) x orientationB.v[2].xyz:
d = boundingOffsetA.x * absOrientationB.v[2].y; d = boundingOffsetA.x * absOrientationB.v[2].y;
d += boundingOffsetA.y * absOrientationB.v[2].x; d += boundingOffsetA.y * absOrientationB.v[2].x;
d += boundingOffsetB.x * absOrientationB.v[1].z; d += boundingOffsetB.x * absOrientationB.v[1].z;
d += boundingOffsetB.y * absOrientationB.v[0].z; d += boundingOffsetB.y * absOrientationB.v[0].z;
if( ::Utility::Value::abs(orientationB.v[3].y*orientationB.v[2].x - orientationB.v[3].x*orientationB.v[2].y) > d ) return false; if( ::Utility::Value::Abs(orientationB.v[3].y*orientationB.v[2].x - orientationB.v[3].x*orientationB.v[2].y) > d ) return false;
return true; return true;
} }
@ -167,54 +167,54 @@ namespace Oyster { namespace Collision { namespace Utility
// PUBLIC BODY ////////////////////////////////////////////////////// // PUBLIC BODY //////////////////////////////////////////////////////
void compare( Float &connectDistance, Float &connectOffsetSquared, const Ray &ray, const Point &point ) void Compare( Float &connectDistance, Float &connectOffsetSquared, const Ray &ray, const Point &point )
{ // by Dan Andersson { // by Dan Andersson
Float3 dP = point.position - ray.origin; Float3 dP = point.center - ray.origin;
connectDistance = dP.dot( ray.direction ); connectDistance = dP.Dot( ray.direction );
connectDistance /= ray.direction.dot( ray.direction ); connectDistance /= ray.direction.Dot( ray.direction );
dP -= ( connectDistance * ray.direction ); dP -= ( connectDistance * ray.direction );
connectOffsetSquared = dP.dot( dP ); connectOffsetSquared = dP.Dot( dP );
} }
void compare( Float &connectDistanceA, Float &connectDistanceB, Float &connectOffsetSquared, const Ray &rayA, const Ray &rayB ) void Compare( Float &connectDistanceA, Float &connectDistanceB, Float &connectOffsetSquared, const Ray &rayA, const Ray &rayB )
{ // by Dan Andersson { // by Dan Andersson
Float3 dP = rayB.origin - rayA.origin; Float3 dP = rayB.origin - rayA.origin;
connectDistanceA = rayA.direction.dot( dP ); connectDistanceA = rayA.direction.Dot( dP );
connectDistanceA /= rayA.direction.dot( rayA.direction ); connectDistanceA /= rayA.direction.Dot( rayA.direction );
dP *= -1.0f; dP *= -1.0f;
connectDistanceB = rayB.direction.dot( dP ); connectDistanceB = rayB.direction.Dot( dP );
connectDistanceB /= rayB.direction.dot( rayB.direction ); connectDistanceB /= rayB.direction.Dot( rayB.direction );
dP = rayA.direction * connectDistanceA; dP = rayA.direction * connectDistanceA;
dP += rayA.origin; dP += rayA.origin;
dP -= rayB.direction * connectDistanceB; dP -= rayB.direction * connectDistanceB;
dP -= rayB.origin; dP -= rayB.origin;
connectOffsetSquared = dP.dot( dP ); connectOffsetSquared = dP.Dot( dP );
} }
void compare( Float &connectOffset, const Plane &plane, const Point &point ) void Compare( Float &connectOffset, const Plane &plane, const Point &point )
{ // by Dan Andersson { // by Dan Andersson
Private::compare( connectOffset, plane, point.position ); Private::Compare( connectOffset, plane, point.center );
} }
bool intersect( const Point &pointA, const Point &pointB ) bool Intersect( const Point &pointA, const Point &pointB )
{ // by Fredrick Johansson { // by Fredrick Johansson
if (pointA.position.x != pointB.position.x) return false; if (pointA.center.x != pointB.center.x) return false;
if (pointA.position.y != pointB.position.y) return false; if (pointA.center.y != pointB.center.y) return false;
if (pointA.position.z != pointB.position.z) return false; if (pointA.center.z != pointB.center.z) return false;
return true; // Passed all tests, is in same position return true; // Passed all tests, is in same position
} }
bool intersect( const Ray &ray, const Point &point, Float &connectDistance ) bool Intersect( const Ray &ray, const Point &point, Float &connectDistance )
{ // by Dan Andersson { // by Dan Andersson
Float connectOffsetSquared; Float connectOffsetSquared;
compare( connectDistance, connectOffsetSquared, ray, point ); Compare( connectDistance, connectOffsetSquared, ray, point );
if( Private::equalsZero(connectOffsetSquared) ) if( Private::EqualsZero(connectOffsetSquared) )
{ {
connectOffsetSquared = 0.0f; connectOffsetSquared = 0.0f;
return true; return true;
@ -224,12 +224,12 @@ namespace Oyster { namespace Collision { namespace Utility
return false; return false;
} }
bool intersect( const Ray &rayA, const Ray &rayB, Float &connectDistanceA, Float &connectDistanceB ) bool Intersect( const Ray &rayA, const Ray &rayB, Float &connectDistanceA, Float &connectDistanceB )
{ // by Dan Andersson { // by Dan Andersson
Float connectOffsetSquared; Float connectOffsetSquared;
compare( connectDistanceA, connectDistanceB, connectOffsetSquared, rayA, rayB ); Compare( connectDistanceA, connectDistanceB, connectOffsetSquared, rayA, rayB );
if( Private::equalsZero(connectOffsetSquared) ) if( Private::EqualsZero(connectOffsetSquared) )
{ {
connectOffsetSquared = 0.0f; connectOffsetSquared = 0.0f;
return true; return true;
@ -239,19 +239,19 @@ namespace Oyster { namespace Collision { namespace Utility
return false; return false;
} }
bool intersect( const Sphere &sphere, const Point &point ) bool Intersect( const Sphere &sphere, const Point &point )
{ // by Dan Andersson { // by Dan Andersson
Float3 dP = point.position - sphere.center; Float3 dP = point.center - sphere.center;
if( dP.dot(dP) > (sphere.radius * sphere.radius) ) if( dP.Dot(dP) > (sphere.radius * sphere.radius) )
return false; return false;
return true; return true;
} }
bool intersect( const Sphere &sphere, const Ray &ray, Float &connectDistance ) bool Intersect( const Sphere &sphere, const Ray &ray, Float &connectDistance )
{// by Dan Andersson {// by Dan Andersson
Float3 dP = sphere.center - ray.origin; Float3 dP = sphere.center - ray.origin;
Float s = dP.dot( ray.direction ), Float s = dP.Dot( ray.direction ),
dSquared = dP.dot( dP ), dSquared = dP.Dot( dP ),
rSquared = sphere.radius * sphere.radius; rSquared = sphere.radius * sphere.radius;
if( dSquared <= rSquared ) { connectDistance = 0.0f; return true; } if( dSquared <= rSquared ) { connectDistance = 0.0f; return true; }
@ -267,13 +267,13 @@ namespace Oyster { namespace Collision { namespace Utility
return true; return true;
} }
bool intersect( const Sphere &sphereA, const Sphere &sphereB ) bool Intersect( const Sphere &sphereA, const Sphere &sphereB )
{ // by Fredrick Johansson { // by Fredrick Johansson
Float3 C = sphereA.center; Float3 C = sphereA.center;
C -= sphereB.center; C -= sphereB.center;
Float r = (sphereA.radius + sphereB.radius); Float r = (sphereA.radius + sphereB.radius);
if (r*r >= C.dot(C)) if (r*r >= C.Dot(C))
{ {
return true; // Intersect detected! return true; // Intersect detected!
} }
@ -281,24 +281,24 @@ namespace Oyster { namespace Collision { namespace Utility
return false; return false;
} }
bool intersect( const Plane &plane, const Point &point ) bool Intersect( const Plane &plane, const Point &point )
{ // by Dan Andersson { // by Dan Andersson
Float connectOffset; Float connectOffset;
Private::compare( connectOffset, plane, point.position ); Private::Compare( connectOffset, plane, point.center );
return Private::equalsZero(connectOffset); return Private::EqualsZero(connectOffset);
} }
bool intersect( const Plane &plane, const Ray &ray, Float &connectDistance ) bool Intersect( const Plane &plane, const Ray &ray, Float &connectDistance )
{ // by Dan Andersson { // by Dan Andersson
Float c = plane.normal.dot(ray.direction); Float c = plane.normal.Dot(ray.direction);
if( Private::equalsZero(c) ) if( Private::EqualsZero(c) )
{ // ray is parallell with the plane. (ray direction orthogonal with the planar normal) { // ray is parallell with the plane. (ray direction orthogonal with the planar normal)
connectDistance = 0.0f; connectDistance = 0.0f;
return contains( plane, ray.origin ); return Contains( plane, ray.origin );
} }
connectDistance = -plane.phasing; connectDistance = -plane.phasing;
connectDistance -= plane.normal.dot( ray.origin ); connectDistance -= plane.normal.Dot( ray.origin );
connectDistance /= c; connectDistance /= c;
if( connectDistance > 0.0f ) if( connectDistance > 0.0f )
@ -308,14 +308,14 @@ namespace Oyster { namespace Collision { namespace Utility
return false; return false;
} }
bool intersect( const Plane &plane, const Sphere &sphere ) bool Intersect( const Plane &plane, const Sphere &sphere )
{ // by Dan Andersson { // by Dan Andersson
Float connectOffset; Float connectOffset;
Private::compare( connectOffset, plane, sphere.center ); Private::Compare( connectOffset, plane, sphere.center );
return (connectOffset <= sphere.radius); return (connectOffset <= sphere.radius);
} }
bool intersect( const Plane &planeA, const Plane &planeB ) bool Intersect( const Plane &planeA, const Plane &planeB )
{ // by Dan Andersson { // by Dan Andersson
if( planeA.normal == planeB.normal ) // they are parallell if( planeA.normal == planeB.normal ) // they are parallell
return (planeA.phasing == planeB.phasing); return (planeA.phasing == planeB.phasing);
@ -324,55 +324,55 @@ namespace Oyster { namespace Collision { namespace Utility
return true; // none parallell planes ALWAYS intersects somewhere return true; // none parallell planes ALWAYS intersects somewhere
} }
bool intersect( const BoxAxisAligned &box, const Point &point ) bool Intersect( const BoxAxisAligned &box, const Point &point )
{ // by Dan Andersson { // by Dan Andersson
if( point.position.x < box.minVertex.x ) return false; if( point.center.x < box.minVertex.x ) return false;
if( point.position.x > box.maxVertex.x ) return false; if( point.center.x > box.maxVertex.x ) return false;
if( point.position.y < box.minVertex.y ) return false; if( point.center.y < box.minVertex.y ) return false;
if( point.position.y > box.maxVertex.y ) return false; if( point.center.y > box.maxVertex.y ) return false;
if( point.position.z < box.minVertex.z ) return false; if( point.center.z < box.minVertex.z ) return false;
if( point.position.z > box.maxVertex.z ) return false; if( point.center.z > box.maxVertex.z ) return false;
return true; return true;
} }
bool intersect( const BoxAxisAligned &box, const Ray &ray, Float &connectDistance ) bool Intersect( const BoxAxisAligned &box, const Ray &ray, Float &connectDistance )
{ // by Dan Andersson { // by Dan Andersson
Float tMin = ::std::numeric_limits<Float>::max(), Float tMin = ::std::numeric_limits<Float>::max(),
tMax = -tMin; // initiating to extremevalues tMax = -tMin; // initiating to extremevalues
Float3 boundingOffset = ((box.maxVertex - box.minVertex) * 0.5f), Float3 boundingOffset = ((box.maxVertex - box.minVertex) * 0.5f),
dP = ((box.maxVertex + box.minVertex) * 0.5f) - ray.origin; dP = ((box.maxVertex + box.minVertex) * 0.5f) - ray.origin;
if( Private::boxVsRayPerSlabCheck( Float3::standardUnitX, boundingOffset.x, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; } if( Private::BoxVsRayPerSlabCheck( Float3::standard_unit_x, boundingOffset.x, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
if( Private::boxVsRayPerSlabCheck( Float3::standardUnitY, boundingOffset.y, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; } if( Private::BoxVsRayPerSlabCheck( Float3::standard_unit_y, boundingOffset.y, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
if( Private::boxVsRayPerSlabCheck( Float3::standardUnitZ, boundingOffset.z, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; } if( Private::BoxVsRayPerSlabCheck( Float3::standard_unit_z, boundingOffset.z, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
if( tMin > 0.0f ) connectDistance = tMin; if( tMin > 0.0f ) connectDistance = tMin;
else connectDistance = tMax; else connectDistance = tMax;
return true; return true;
} }
bool intersect( const BoxAxisAligned &box, const Sphere &sphere ) bool Intersect( const BoxAxisAligned &box, const Sphere &sphere )
{ // by Dan Andersson { // by Dan Andersson
Float3 e = ::Utility::Value::max( box.minVertex - sphere.center, Float3::null ); Float3 e = ::Utility::Value::Max( box.minVertex - sphere.center, Float3::null );
e += ::Utility::Value::max( sphere.center - box.maxVertex, Float3::null ); e += ::Utility::Value::Max( sphere.center - box.maxVertex, Float3::null );
if( e.dot(e) > (sphere.radius * sphere.radius) ) return false; if( e.Dot(e) > (sphere.radius * sphere.radius) ) return false;
return true; return true;
} }
bool intersect( const BoxAxisAligned &box, const Plane &plane ) bool Intersect( const BoxAxisAligned &box, const Plane &plane )
{ // by Dan Andersson { // by Dan Andersson
Float e, d; Float e, d;
Private::compare( e, d, plane, box ); Private::Compare( e, d, plane, box );
if( d - e > 0.0f ) return false; // is beneath if( d - e > 0.0f ) return false; // is beneath
if( d + e < 0.0f ) return false; // is above if( d + e < 0.0f ) return false; // is above
return true; return true;
} }
// bool intersect( const BoxAxisAligned &box, const Triangle &triangle ) // bool Intersect( const BoxAxisAligned &box, const Triangle &triangle )
// { return false; /* TODO */ } // { return false; /* TODO: */ }
bool intersect( const BoxAxisAligned &boxA, const BoxAxisAligned &boxB ) bool Intersect( const BoxAxisAligned &boxA, const BoxAxisAligned &boxB )
{ // by Dan Andersson { // by Dan Andersson
if( boxA.maxVertex.x < boxB.minVertex.x ) return false; if( boxA.maxVertex.x < boxB.minVertex.x ) return false;
if( boxA.minVertex.x > boxB.maxVertex.x ) return false; if( boxA.minVertex.x > boxB.maxVertex.x ) return false;
@ -383,144 +383,144 @@ namespace Oyster { namespace Collision { namespace Utility
return true; return true;
} }
bool intersect( const Box &box, const Point &point ) bool Intersect( const Box &box, const Point &point )
{ // by Dan Andersson { // by Dan Andersson
Float3 dPos = point.position - box.orientation.v[3].xyz; Float3 dPos = point.center - box.orientation.v[3].xyz;
Float coordinate = dPos.dot( box.orientation.v[0].xyz ); Float coordinate = dPos.Dot( box.orientation.v[0].xyz );
if( coordinate > box.boundingOffset.x ) return false; if( coordinate > box.boundingOffset.x ) return false;
if( coordinate < -box.boundingOffset.x ) return false; if( coordinate < -box.boundingOffset.x ) return false;
coordinate = dPos.dot( box.orientation.v[1].xyz ); coordinate = dPos.Dot( box.orientation.v[1].xyz );
if( coordinate > box.boundingOffset.y ) return false; if( coordinate > box.boundingOffset.y ) return false;
if( coordinate < -box.boundingOffset.y ) return false; if( coordinate < -box.boundingOffset.y ) return false;
coordinate = dPos.dot( box.orientation.v[2].xyz ); coordinate = dPos.Dot( box.orientation.v[2].xyz );
if( coordinate > box.boundingOffset.z ) return false; if( coordinate > box.boundingOffset.z ) return false;
if( coordinate < -box.boundingOffset.z ) return false; if( coordinate < -box.boundingOffset.z ) return false;
return true; return true;
} }
bool intersect( const Box &box, const Ray &ray, Float &connectDistance ) bool Intersect( const Box &box, const Ray &ray, Float &connectDistance )
{ // by Dan Andersson { // by Dan Andersson
Float tMin = ::std::numeric_limits<Float>::max(), Float tMin = ::std::numeric_limits<Float>::max(),
tMax = -tMin; // initiating to extremevalues tMax = -tMin; // initiating to extremevalues
Float3 dP = box.center - ray.origin; Float3 dP = box.center - ray.origin;
if( Private::boxVsRayPerSlabCheck( box.xAxis, box.boundingOffset.x, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; } if( Private::BoxVsRayPerSlabCheck( box.xAxis, box.boundingOffset.x, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
if( Private::boxVsRayPerSlabCheck( box.yAxis, box.boundingOffset.y, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; } if( Private::BoxVsRayPerSlabCheck( box.yAxis, box.boundingOffset.y, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
if( Private::boxVsRayPerSlabCheck( box.zAxis, box.boundingOffset.z, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; } if( Private::BoxVsRayPerSlabCheck( box.zAxis, box.boundingOffset.z, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
if( tMin > 0.0f ) connectDistance = tMin; if( tMin > 0.0f ) connectDistance = tMin;
else connectDistance = tMax; else connectDistance = tMax;
return true; return true;
} }
bool intersect( const Box &box, const Sphere &sphere ) bool Intersect( const Box &box, const Sphere &sphere )
{ // by Dan Andersson { // by Dan Andersson
Float3 e = sphere.center - box.orientation.v[3].xyz, Float3 e = sphere.center - box.orientation.v[3].xyz,
centerL = Float3( e.dot(box.orientation.v[0].xyz), e.dot(box.orientation.v[1].xyz), e.dot(box.orientation.v[2].xyz) ); centerL = Float3( e.Dot(box.orientation.v[0].xyz), e.Dot(box.orientation.v[1].xyz), e.Dot(box.orientation.v[2].xyz) );
e = ::Utility::Value::max( (box.boundingOffset + centerL)*=-1.0f, Float3::null ); e = ::Utility::Value::Max( (box.boundingOffset + centerL)*=-1.0f, Float3::null );
e += ::Utility::Value::max( centerL - box.boundingOffset, Float3::null ); e += ::Utility::Value::Max( centerL - box.boundingOffset, Float3::null );
if( e.dot(e) > (sphere.radius * sphere.radius) ) return false; if( e.Dot(e) > (sphere.radius * sphere.radius) ) return false;
return true; return true;
} }
bool intersect( const Box &box, const Plane &plane ) bool Intersect( const Box &box, const Plane &plane )
{// by Dan Andersson {// by Dan Andersson
Float e, d; Float e, d;
Private::compare( e, d, plane, box ); Private::Compare( e, d, plane, box );
if( d - e > 0.0f ) return false; // is beneath if( d - e > 0.0f ) return false; // is beneath
if( d + e < 0.0f ) return false; // is above if( d + e < 0.0f ) return false; // is above
return true; return true;
} }
bool intersect( const Box &boxA, const BoxAxisAligned &boxB ) bool Intersect( const Box &boxA, const BoxAxisAligned &boxB )
{ // by Dan Andersson { // by Dan Andersson
Float3 alignedOffsetBoundaries = boxB.maxVertex - boxB.minVertex; Float3 alignedOffsetBoundaries = boxB.maxVertex - boxB.minVertex;
Float4x4 translated = boxA.orientation; Float4x4 translated = boxA.orientation;
translated.v[3].xyz -= boxB.minVertex; translated.v[3].xyz -= boxB.minVertex;
translated.v[3].xyz += alignedOffsetBoundaries * 0.5f; translated.v[3].xyz += alignedOffsetBoundaries * 0.5f;
alignedOffsetBoundaries = ::Utility::Value::abs(alignedOffsetBoundaries); alignedOffsetBoundaries = ::Utility::Value::Abs(alignedOffsetBoundaries);
return Private::fifteenAxisVsAlignedAxisOverlappingChecks( alignedOffsetBoundaries, boxA.boundingOffset, translated ); return Private::FifteenAxisVsAlignedAxisOverlappingChecks( alignedOffsetBoundaries, boxA.boundingOffset, translated );
} }
bool intersect( const Box &boxA, const Box &boxB ) bool Intersect( const Box &boxA, const Box &boxB )
{ // by Dan Andersson { // by Dan Andersson
Float4x4 M; Float4x4 M;
inverseRigidBodyMatrix( M, boxA.orientation ); InverseOrientationMatrix( boxA.orientation, M );
transformMatrix( M, boxB.orientation, M ); TransformMatrix( M, boxB.orientation, M ); /// TODO: not verified
return Private::fifteenAxisVsAlignedAxisOverlappingChecks( boxA.boundingOffset, boxB.boundingOffset, M ); return Private::FifteenAxisVsAlignedAxisOverlappingChecks( boxA.boundingOffset, boxB.boundingOffset, M );
} }
bool intersect( const Frustrum &frustrum, const Point &point ) bool Intersect( const Frustrum &frustrum, const Point &point )
{ // by Dan Andersson { // by Dan Andersson
Float connectOffset; Float connectOffset;
Private::compare( connectOffset, frustrum.leftPlane, point.position ); Private::Compare( connectOffset, frustrum.leftPlane, point.center );
if( connectOffset < 0.0f ) return false; if( connectOffset < 0.0f ) return false;
Private::compare( connectOffset, frustrum.rightPlane, point.position ); Private::Compare( connectOffset, frustrum.rightPlane, point.center );
if( connectOffset < 0.0f ) return false; if( connectOffset < 0.0f ) return false;
Private::compare( connectOffset, frustrum.bottomPlane, point.position ); Private::Compare( connectOffset, frustrum.bottomPlane, point.center );
if( connectOffset < 0.0f) return false; if( connectOffset < 0.0f) return false;
Private::compare( connectOffset, frustrum.topPlane, point.position ); Private::Compare( connectOffset, frustrum.topPlane, point.center );
if( connectOffset < 0.0f) return false; if( connectOffset < 0.0f) return false;
Private::compare( connectOffset, frustrum.nearPlane, point.position ); Private::Compare( connectOffset, frustrum.nearPlane, point.center );
if( connectOffset < 0.0f ) return false; if( connectOffset < 0.0f ) return false;
Private::compare( connectOffset, frustrum.farPlane, point.position ); Private::Compare( connectOffset, frustrum.farPlane, point.center );
if( connectOffset < 0.0f ) return false; if( connectOffset < 0.0f ) return false;
return true; return true;
} }
bool intersect( const Frustrum &frustrum, const Ray &ray, Float &connectDistance ) bool Intersect( const Frustrum &frustrum, const Ray &ray, Float &connectDistance )
{ // by Dan Andersson { // by Dan Andersson
bool intersected = false; bool intersected = false;
Float distance = 0.0f; Float distance = 0.0f;
connectDistance = ::std::numeric_limits<Float>::max(); connectDistance = ::std::numeric_limits<Float>::max();
if( intersect(frustrum.leftPlane, ray, distance) ) if( Intersect(frustrum.leftPlane, ray, distance) )
{ {
intersected = true; intersected = true;
connectDistance = ::Utility::Value::min( connectDistance, distance ); connectDistance = ::Utility::Value::Min( connectDistance, distance );
} }
if( intersect(frustrum.rightPlane, ray, distance) ) if( Intersect(frustrum.rightPlane, ray, distance) )
{ {
intersected = true; intersected = true;
connectDistance = ::Utility::Value::min( connectDistance, distance ); connectDistance = ::Utility::Value::Min( connectDistance, distance );
} }
if( intersect(frustrum.bottomPlane, ray, distance) ) if( Intersect(frustrum.bottomPlane, ray, distance) )
{ {
intersected = true; intersected = true;
connectDistance = ::Utility::Value::min( connectDistance, distance ); connectDistance = ::Utility::Value::Min( connectDistance, distance );
} }
if( intersect(frustrum.topPlane, ray, distance) ) if( Intersect(frustrum.topPlane, ray, distance) )
{ {
intersected = true; intersected = true;
connectDistance = ::Utility::Value::min( connectDistance, distance ); connectDistance = ::Utility::Value::Min( connectDistance, distance );
} }
if( intersect(frustrum.nearPlane, ray, distance) ) if( Intersect(frustrum.nearPlane, ray, distance) )
{ {
intersected = true; intersected = true;
connectDistance = ::Utility::Value::min( connectDistance, distance ); connectDistance = ::Utility::Value::Min( connectDistance, distance );
} }
if( intersect(frustrum.farPlane, ray, distance) ) if( Intersect(frustrum.farPlane, ray, distance) )
{ {
intersected = true; intersected = true;
connectDistance = ::Utility::Value::min( connectDistance, distance ); connectDistance = ::Utility::Value::Min( connectDistance, distance );
} }
if( intersected ) return true; if( intersected ) return true;
@ -529,99 +529,99 @@ namespace Oyster { namespace Collision { namespace Utility
return false; return false;
} }
bool intersect( const Frustrum &frustrum, const Sphere &sphere ) bool Intersect( const Frustrum &frustrum, const Sphere &sphere )
{ // by Dan Andersson { // by Dan Andersson
Float connectOffset; Float connectOffset;
Private::compare( connectOffset, frustrum.leftPlane, sphere.center ); Private::Compare( connectOffset, frustrum.leftPlane, sphere.center );
if( connectOffset < -sphere.radius ) return false; if( connectOffset < -sphere.radius ) return false;
Private::compare( connectOffset, frustrum.rightPlane, sphere.center ); Private::Compare( connectOffset, frustrum.rightPlane, sphere.center );
if( connectOffset < -sphere.radius ) return false; if( connectOffset < -sphere.radius ) return false;
Private::compare( connectOffset, frustrum.bottomPlane, sphere.center ); Private::Compare( connectOffset, frustrum.bottomPlane, sphere.center );
if( connectOffset < -sphere.radius ) return false; if( connectOffset < -sphere.radius ) return false;
Private::compare( connectOffset, frustrum.topPlane, sphere.center ); Private::Compare( connectOffset, frustrum.topPlane, sphere.center );
if( connectOffset < -sphere.radius ) return false; if( connectOffset < -sphere.radius ) return false;
Private::compare( connectOffset, frustrum.nearPlane, sphere.center ); Private::Compare( connectOffset, frustrum.nearPlane, sphere.center );
if( connectOffset < -sphere.radius ) return false; if( connectOffset < -sphere.radius ) return false;
Private::compare( connectOffset, frustrum.farPlane, sphere.center ); Private::Compare( connectOffset, frustrum.farPlane, sphere.center );
if( connectOffset < -sphere.radius ) return false; if( connectOffset < -sphere.radius ) return false;
return true; return true;
} }
bool intersect( const Frustrum &frustrum, const Plane &plane ) bool Intersect( const Frustrum &frustrum, const Plane &plane )
{ {
return false; // TODO return false; // TODO:
} }
// bool intersect( const Frustrum &frustrum, const Triangle &triangle, ? ); // bool Intersect( const Frustrum &frustrum, const Triangle &triangle, ? );
bool intersect( const Frustrum &frustrum, const BoxAxisAligned &box ) bool Intersect( const Frustrum &frustrum, const BoxAxisAligned &box )
{ // by Dan Andersson { // by Dan Andersson
Float e, d; Float e, d;
Private::compare( e, d, frustrum.leftPlane, box ); Private::Compare( e, d, frustrum.leftPlane, box );
if( d - e > 0.0f ) return false; // is beneath if( d - e > 0.0f ) return false; // is beneath
Private::compare( e, d, frustrum.rightPlane, box ); Private::Compare( e, d, frustrum.rightPlane, box );
if( d - e > 0.0f ) return false; // is beneath if( d - e > 0.0f ) return false; // is beneath
Private::compare( e, d, frustrum.bottomPlane, box ); Private::Compare( e, d, frustrum.bottomPlane, box );
if( d - e > 0.0f ) return false; // is beneath if( d - e > 0.0f ) return false; // is beneath
Private::compare( e, d, frustrum.topPlane, box ); Private::Compare( e, d, frustrum.topPlane, box );
if( d - e > 0.0f ) return false; // is beneath if( d - e > 0.0f ) return false; // is beneath
Private::compare( e, d, frustrum.nearPlane, box ); Private::Compare( e, d, frustrum.nearPlane, box );
if( d - e > 0.0f ) return false; // is beneath if( d - e > 0.0f ) return false; // is beneath
Private::compare( e, d, frustrum.farPlane, box ); Private::Compare( e, d, frustrum.farPlane, box );
if( d - e > 0.0f ) return false; // is beneath if( d - e > 0.0f ) return false; // is beneath
return true; return true;
} }
bool intersect( const Frustrum &frustrum, const Box &box ) bool Intersect( const Frustrum &frustrum, const Box &box )
{ // by Dan Andersson { // by Dan Andersson
Float e, d; Float e, d;
Private::compare( e, d, frustrum.leftPlane, box ); Private::Compare( e, d, frustrum.leftPlane, box );
if( d - e > 0.0f ) return false; // is beneath if( d - e > 0.0f ) return false; // is beneath
Private::compare( e, d, frustrum.rightPlane, box ); Private::Compare( e, d, frustrum.rightPlane, box );
if( d - e > 0.0f ) return false; // is beneath if( d - e > 0.0f ) return false; // is beneath
Private::compare( e, d, frustrum.bottomPlane, box ); Private::Compare( e, d, frustrum.bottomPlane, box );
if( d - e > 0.0f ) return false; // is beneath if( d - e > 0.0f ) return false; // is beneath
Private::compare( e, d, frustrum.topPlane, box ); Private::Compare( e, d, frustrum.topPlane, box );
if( d - e > 0.0f ) return false; // is beneath if( d - e > 0.0f ) return false; // is beneath
Private::compare( e, d, frustrum.nearPlane, box ); Private::Compare( e, d, frustrum.nearPlane, box );
if( d - e > 0.0f ) return false; // is beneath if( d - e > 0.0f ) return false; // is beneath
Private::compare( e, d, frustrum.farPlane, box ); Private::Compare( e, d, frustrum.farPlane, box );
if( d - e > 0.0f ) return false; // is beneath if( d - e > 0.0f ) return false; // is beneath
return true; return true;
} }
bool intersect( const Frustrum &frustrumA, const Frustrum &frustrumB ) bool Intersect( const Frustrum &frustrumA, const Frustrum &frustrumB )
{ {
return false; // TODO return false; // TODO:
} }
bool contains( const Ray &container, const Ray &ray ) bool Contains( const Ray &container, const Ray &ray )
{ {
return false; /*TODO*/ return false; /*TODO: */
} }
bool contains( const Sphere &sphereA, const Sphere &sphereB ) bool Contains( const Sphere &sphereA, const Sphere &sphereB )
{ // by Fredrick Johansson { // by Fredrick Johansson
// Check if SphereB is larger than sphereA // Check if SphereB is larger than sphereA
if (sphereA.radius < sphereB.radius) if (sphereA.radius < sphereB.radius)
@ -634,7 +634,7 @@ namespace Oyster { namespace Collision { namespace Utility
Float deltaR = sphereA.radius - sphereB.radius; Float deltaR = sphereA.radius - sphereB.radius;
// Check if contained // Check if contained
if (d.dot(d) <= (deltaR*deltaR)) if (d.Dot(d) <= (deltaR*deltaR))
{ {
return true; return true;
} }
@ -643,18 +643,18 @@ namespace Oyster { namespace Collision { namespace Utility
return false; return false;
} }
bool contains( const Plane &container, const Point &point ) bool Contains( const Plane &container, const Point &point )
{ // by Dan Andersson { // by Dan Andersson
return Private::contains( container, point.position ); return Private::Contains( container, point.center );
} }
bool contains( const Plane &container, const Ray &ray ) bool Contains( const Plane &container, const Ray &ray )
{ // by Dan Andersson { // by Dan Andersson
if( Private::notEqualsZero(container.normal.dot(ray.direction)) ) return false; if( Private::NotEqualsZero(container.normal.Dot(ray.direction)) ) return false;
return contains( container, ray.origin ); return Contains( container, ray.origin );
} }
bool contains( const Plane &container, const Plane &plane ) bool Contains( const Plane &container, const Plane &plane )
{ // by Dan Andersson { // by Dan Andersson
if( container.phasing == plane.phasing ) if( container.phasing == plane.phasing )
return container.normal == plane.normal; return container.normal == plane.normal;

View File

@ -1,11 +1,106 @@
/////////////////////////////////////////////////////////////////////
// Created by Dan Andersson 2013
/////////////////////////////////////////////////////////////////////
#pragma once
#ifndef OYSTER_COLLISION_3D_UTILITY_H
#define OYSTER_COLLISION_3D_UTILITY_H
#include "ICollideable.h" #include "ICollideable.h"
#include "Universe.h"
#include "Point.h" #include "Point.h"
#include "Ray.h" #include "Ray.h"
#include "Plane.h"
#include "Sphere.h" #include "Sphere.h"
#include "Plane.h"
//#include "Triangle.h"
#include "BoxAxisAligned.h" #include "BoxAxisAligned.h"
#include "Box.h" #include "Box.h"
#include "Frustrum.h" #include "Frustrum.h"
#include "Line.h" #include "Line.h"
#include "Collision.h" namespace Oyster { namespace Collision3D { namespace Utility
{
void Compare( ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float &connectOffsetSquared, const Ray &ray, const Point &point );
void Compare( ::Oyster::Math::Float &connectDistanceA, ::Oyster::Math::Float &connectDistanceB, ::Oyster::Math::Float &connectOffsetSquared, const Ray &rayA, const Ray &rayB );
void Compare( ::Oyster::Math::Float &connectOffset, const Plane &plane, const Point &point );
bool Intersect( const Point &pointA, const Point &pointB );
bool Intersect( const Ray &ray, const Point &point, ::Oyster::Math::Float &connectDistance );
bool Intersect( const Ray &rayA, const Ray &rayB, ::Oyster::Math::Float &connectDistanceA, ::Oyster::Math::Float &connectDistanceB );
bool Intersect( const Sphere &sphere, const Point &point );
bool Intersect( const Sphere &sphere, const Ray &ray, ::Oyster::Math::Float &connectDistance );
bool Intersect( const Sphere &sphereA, const Sphere &sphereB );
bool Intersect( const Plane &plane, const Point &point );
bool Intersect( const Plane &plane, const Ray &ray, ::Oyster::Math::Float &connectDistance );
bool Intersect( const Plane &plane, const Sphere &sphere );
bool Intersect( const Plane &planeA, const Plane &planeB );
// bool Intersect( const Triangle &triangle, const Point &point, ? );
// bool Intersect( const Triangle &triangle, const Ray &ray, ? );
// bool Intersect( const Triangle &triangle, const Sphere &sphere, ? );
// bool Intersect( const Triangle &triangle, const Plane &plane, ? );
// bool Intersect( const Triangle &triangleA, const Triangle &triangleB, ? );
bool Intersect( const BoxAxisAligned &box, const Point &point );
bool Intersect( const BoxAxisAligned &box, const Ray &ray, ::Oyster::Math::Float &connectDistance );
bool Intersect( const BoxAxisAligned &box, const Sphere &sphere );
bool Intersect( const BoxAxisAligned &box, const Plane &plane );
// bool Intersect( const BoxAxisAligned &box, const Triangle &triangle );
bool Intersect( const BoxAxisAligned &boxA, const BoxAxisAligned &boxB );
bool Intersect( const Box &box, const Point &point );
bool Intersect( const Box &box, const Ray &ray, ::Oyster::Math::Float &connectDistance );
bool Intersect( const Box &box, const Sphere &sphere );
bool Intersect( const Box &box, const Plane &plane );
// bool Intersect( const Box &box, const Triangle &triangle, ? );
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB );
bool Intersect( const Box &boxA, const Box &boxB );
bool Intersect( const Frustrum &frustrum, const Point &point );
bool Intersect( const Frustrum &frustrum, const Ray &ray, ::Oyster::Math::Float &connectDistance );
bool Intersect( const Frustrum &frustrum, const Sphere &sphere );
bool Intersect( const Frustrum &frustrum, const Plane &plane );
// bool Intersect( const Frustrum &frustrum, const Triangle &triangle, ? );
bool Intersect( const Frustrum &frustrum, const BoxAxisAligned &box );
bool Intersect( const Frustrum &frustrum, const Box &box );
bool Intersect( const Frustrum &frustrumA, const Frustrum &frustrumB );
bool Contains( const Ray &container, const Ray &ray );
bool Contains( const Sphere &container, const Sphere &sphere );
// bool Contains( const Sphere &container, const Triangle &triangle );
// bool Contains( const Sphere &container, const BoxAxisAligned &box );
// bool Contains( const Sphere &container, const Box &box );
// bool Contains( const Sphere &container, const Frustrum &frustrum );
bool Contains( const Plane &container, const Point &point );
bool Contains( const Plane &container, const Ray &ray );
bool Contains( const Plane &container, const Plane &plane );
// bool Contains( const Plane &container, const Triangle &triangle );
// bool Contains( const Triangle &container, const Point &point );
// bool Contains( const Triangle &container, const Triangle &triangle );
// bool Contains( const BoxAxisAligned &container, const Sphere &sphere );
// bool Contains( const BoxAxisAligned &container, const Triangle &triangle );
// bool Contains( const BoxAxisAligned &container, const BoxAxisAligned &box );
// bool Contains( const BoxAxisAligned &container, const Box &box );
// bool Contains( const BoxAxisAligned &container, const Frustrum &frustrum );
// bool Contains( const Box &container, const Sphere &sphere );
// bool Contains( const Box &container, const Triangle &triangle );
// bool Contains( const Box &container, const BoxAxisAligned &box );
// bool Contains( const Box &container, const Box &box );
// bool Contains( const Box &container, const Frustrum &frustrum );
// bool Contains( const Frustrum &container, const Sphere &sphere );
// bool Contains( const Frustrum &container, const Triangle &triangle );
// bool Contains( const Frustrum &container, const BoxAxisAligned &box );
// bool Contains( const Frustrum &container, const Box &box );
// bool Contains( const Frustrum &container, const Frustrum &frustrum );
} } }
#endif

View File

@ -3,15 +3,14 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#include "Plane.h" #include "Plane.h"
#include "Collision.h" #include "OysterCollision.h"
using namespace ::Oyster::Collision; using namespace ::Oyster::Collision3D;
using namespace ::Oyster::Math; using namespace ::Oyster::Math;
Plane::Plane( ) : ICollideable(ICollideable::Plane), normal(), phasing(0.0f) {} Plane::Plane( ) : ICollideable(Type_plane), normal(), phasing(0.0f) {}
Plane::Plane( const Plane &plane ) : ICollideable(ICollideable::Plane), normal(plane.normal), phasing(plane.phasing) {} Plane::Plane( const Float3 &n, const Float &p ) : ICollideable(Type_plane), normal(n), phasing(p) {}
Plane::Plane( const Float3 &n, const Float &p ) : ICollideable(ICollideable::Plane), normal(n), phasing(p) {} Plane::~Plane( ) {}
Plane::~Plane( ) { /*Nothing needs to be done here*/ }
Plane & Plane::operator = ( const Plane &plane ) Plane & Plane::operator = ( const Plane &plane )
{ {
@ -20,22 +19,23 @@ Plane & Plane::operator = ( const Plane &plane )
return *this; return *this;
} }
ICollideable* Plane::clone( ) const ::Utility::Memory::UniquePointer<ICollideable> Plane::Clone( ) const
{ return new Plane( *this ); } { return ::Utility::Memory::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 ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target ); case Type_universe: return true;
case ICollideable::Ray: return Utility::intersect( *this, *(Collision::Ray*)target, ((Collision::Ray*)target)->collisionDistance ); case Type_point: return Utility::Intersect( *this, *(Point*)target );
case ICollideable::Sphere: return Utility::intersect( *this, *(Collision::Sphere*)target ); case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance );
case ICollideable::Plane: return Utility::intersect( *this, *(Collision::Plane*)target ); case Type_sphere: return Utility::Intersect( *this, *(Sphere*)target );
case ICollideable::Triangle: return false; // TODO case Type_plane: return Utility::Intersect( *this, *(Plane*)target );
case ICollideable::BoxAxisAligned: return Utility::intersect( *(Collision::BoxAxisAligned*)target, *this ); case Type_triangle: return false; // TODO:
case ICollideable::Box: return Utility::intersect( *(Collision::Box*)target, *this ); case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)target, *this );
case ICollideable::Frustrum: return false; // TODO case Type_box: return Utility::Intersect( *(Box*)target, *this );
case ICollideable::Line: return false; // TODO case Type_frustrum: return false; // TODO:
case Type_line: return false; // TODO:
default: return false; default: return false;
} }
} }
@ -44,13 +44,10 @@ bool Plane::Contains( const ICollideable *target ) const
{ {
switch( target->type ) switch( target->type )
{ {
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target ); case Type_point: return Utility::Intersect( *this, *(Point*)target );
case ICollideable::Ray: return Utility::contains( *this, *(Collision::Ray*)target ); case Type_ray: return Utility::Contains( *this, *(Ray*)target );
case ICollideable::Plane: return Utility::contains( *this, *(Collision::Plane*)target ); case Type_plane: return Utility::Contains( *this, *(Plane*)target );
case ICollideable::Triangle: return false; // TODO case Type_triangle: return false; // TODO:
default: return false; default: return false;
} }
} }
ICollideable::State Plane::Advanced( const ICollideable *target ) const
{ return ICollideable::Missed; } //Not supported returns 0

View File

@ -3,13 +3,13 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#pragma once #pragma once
#ifndef OYSTER_COLLISION_PLANE_H #ifndef OYSTER_COLLISION_3D_PLANE_H
#define OYSTER_COLLISION_PLANE_H #define OYSTER_COLLISION_3D_PLANE_H
#include "OysterMath.h" #include "OysterMath.h"
#include "ICollideable.h" #include "ICollideable.h"
namespace Oyster { namespace Collision namespace Oyster { namespace Collision3D
{ {
class Plane : public ICollideable class Plane : public ICollideable
{ {
@ -22,16 +22,14 @@ namespace Oyster { namespace Collision
}; };
Plane( ); Plane( );
Plane( const Plane &plane );
Plane( const ::Oyster::Math::Float3 &normal, const ::Oyster::Math::Float &phasing ); Plane( const ::Oyster::Math::Float3 &normal, const ::Oyster::Math::Float &phasing );
~Plane( ); virtual ~Plane( );
Plane & operator = ( const Plane &plane ); Plane & operator = ( const Plane &plane );
ICollideable* clone( ) const; virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable *target ) const; bool Intersects( const ICollideable *target ) const;
bool Contains( const ICollideable *target ) const; bool Contains( const ICollideable *target ) const;
ICollideable::State Advanced( const ICollideable *target ) const; //Not supported returns 0;
}; };
} } } }

View File

@ -3,37 +3,37 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#include "Point.h" #include "Point.h"
#include "Collision.h" #include "OysterCollision.h"
using namespace ::Oyster::Collision; using namespace ::Oyster::Collision3D;
using namespace ::Oyster::Math; using namespace ::Oyster::Math3D;
Point::Point( ) : ICollideable(ICollideable::Point), position() {} Point::Point( ) : ICollideable(Type_point), center() {}
Point::Point( const Point &point ) : ICollideable(ICollideable::Point), position(point.position) {} Point::Point( const Float3 &pos ) : ICollideable(Type_point), center(pos) {}
Point::Point( const Float3 &pos ) : ICollideable(ICollideable::Point), position(pos) {} Point::~Point( ) {}
Point::~Point( ) { /*Nothing needs to be done here*/ }
Point & Point::operator = ( const Point &point ) Point & Point::operator = ( const Point &point )
{ {
this->position = point.position; this->center = point.center;
return *this; return *this;
} }
ICollideable* Point::clone( ) const ::Utility::Memory::UniquePointer<ICollideable> Point::Clone( ) const
{ return new Point( *this ); } { return ::Utility::Memory::UniquePointer<ICollideable>( new Point(*this) ); }
bool Point::Intersects( const ICollideable *target ) const bool Point::Intersects( const ICollideable *target ) const
{ {
switch( target->type ) switch( target->type )
{ {
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target ); case Type_universe: return true;
case ICollideable::Ray: return Utility::intersect( *(Collision::Ray*)target, *this, ((Collision::Ray*)target)->collisionDistance ); case Type_point: return Utility::Intersect( *this, *(Point*)target );
case ICollideable::Sphere: Utility::intersect( *(Collision::Sphere*)target, *this ); case Type_ray: return Utility::Intersect( *(Ray*)target, *this, ((Ray*)target)->collisionDistance );
case ICollideable::Plane: return Utility::intersect( *(Collision::Plane*)target, *this ); case Type_sphere: Utility::Intersect( *(Sphere*)target, *this );
case ICollideable::Triangle: return false; // TODO case Type_plane: return Utility::Intersect( *(Plane*)target, *this );
case ICollideable::BoxAxisAligned: return Utility::intersect( *(Collision::BoxAxisAligned*)target, *this ); case Type_triangle: return false; // TODO:
case ICollideable::Box: return Utility::intersect( *(Collision::Box*)target, *this ); case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)target, *this );
case ICollideable::Frustrum: return false; // TODO case Type_box: return Utility::Intersect( *(Box*)target, *this );
case Type_frustrum: return false; // TODO:
default: return false; default: return false;
} }
} }
@ -42,10 +42,7 @@ bool Point::Contains( const ICollideable *target ) const
{ {
switch( target->type ) switch( target->type )
{ {
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target ); case Type_point: return Utility::Intersect( *this, *(Point*)target );
default: return false; default: return false;
} }
} }
ICollideable::State Point::Advanced( const ICollideable *target ) const
{ return ICollideable::Missed; } //Not supported returns 0

View File

@ -3,34 +3,32 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#pragma once #pragma once
#ifndef OYSTER_COLLISION_POINT_H #ifndef OYSTER_COLLISION_3D_POINT_H
#define OYSTER_COLLISION_POINT_H #define OYSTER_COLLISION_3D_POINT_H
#include "OysterMath.h" #include "OysterMath.h"
#include "ICollideable.h" #include "ICollideable.h"
namespace Oyster { namespace Collision namespace Oyster { namespace Collision3D
{ {
class Point : public ICollideable class Point : public ICollideable
{ {
public: public:
union union
{ {
struct{ ::Oyster::Math::Float3 position; }; struct{ ::Oyster::Math::Float3 center; };
char byte[sizeof(::Oyster::Math::Float3)]; char byte[sizeof(::Oyster::Math::Float3)];
}; };
Point( ); Point( );
Point( const Point &point );
Point( const ::Oyster::Math::Float3 &position ); Point( const ::Oyster::Math::Float3 &position );
~Point( ); virtual ~Point( );
Point & operator = ( const Point &point ); Point & operator = ( const Point &point );
ICollideable* clone( ) const; virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable *target ) const; bool Intersects( const ICollideable *target ) const;
bool Contains( const ICollideable *target ) const; bool Contains( const ICollideable *target ) const;
ICollideable::State Advanced( const ICollideable *target ) const; //Not supported returns 0;
}; };
} } } }

View File

@ -3,39 +3,40 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#include "Ray.h" #include "Ray.h"
#include "Collision.h" #include "OysterCollision.h"
using namespace ::Oyster::Collision; using namespace ::Oyster::Collision3D;
using namespace ::Oyster::Math; using namespace ::Oyster::Math3D;
Ray::Ray( ) : ICollideable(ICollideable::Ray), origin(), direction(), collisionDistance(0.0f) {} Ray::Ray( ) : ICollideable(Type_ray), origin(), direction(), collisionDistance(0.0f) {}
Ray::Ray( const Ray &ray ) : ICollideable(ICollideable::Ray), origin(ray.origin), direction(ray.direction), collisionDistance(0.0f) {} Ray::Ray( const Float3 &o, const ::Oyster::Math::Float3 &d ) : ICollideable(Type_ray), origin(o), direction(d), collisionDistance(0.0f) {}
Ray::Ray( const Float3 &o, const ::Oyster::Math::Float3 &d ) : ICollideable(ICollideable::Ray), origin(o), direction(d), collisionDistance(0.0f) {} Ray::~Ray( ) {}
Ray::~Ray( ) { /*Nothing needs to be done here*/ }
Ray & Ray::operator = ( const Ray &ray ) Ray & Ray::operator = ( const Ray &ray )
{ {
this->origin = ray.origin; this->origin = ray.origin;
this->direction = ray.direction; this->direction = ray.direction;
this->collisionDistance = ray.collisionDistance;
return *this; return *this;
} }
ICollideable* Ray::clone( ) const ::Utility::Memory::UniquePointer<ICollideable> Ray::Clone( ) const
{ return new Ray( *this ); } { return ::Utility::Memory::UniquePointer<ICollideable>( new Ray(*this) ); }
bool Ray::Intersects( const ICollideable *target ) const bool Ray::Intersects( const ICollideable *target ) const
{ {
switch( target->type ) switch( target->type )
{ {
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target, this->collisionDistance ); case Type_universe:
case ICollideable::Ray: return Utility::intersect( *this, *(Collision::Ray*)target, this->collisionDistance, ((Collision::Ray*)target)->collisionDistance ); this->collisionDistance = 0.0f;
case ICollideable::Sphere: return Utility::intersect( *(Collision::Sphere*)target, *this, this->collisionDistance ); return true;
case ICollideable::Plane: return Utility::intersect( *(Collision::Plane*)target, *this, this->collisionDistance ); case Type_point: return Utility::Intersect( *this, *(Point*)target, this->collisionDistance );
case ICollideable::Triangle: return false; // TODO case Type_ray: return Utility::Intersect( *this, *(Ray*)target, this->collisionDistance, ((Ray*)target)->collisionDistance );
case ICollideable::BoxAxisAligned: return Utility::intersect( *(Collision::BoxAxisAligned*)target, *this, this->collisionDistance ); case Type_sphere: return Utility::Intersect( *(Sphere*)target, *this, this->collisionDistance );
case ICollideable::Box: return Utility::intersect( *(Collision::Box*)target, *this, this->collisionDistance ); case Type_plane: return Utility::Intersect( *(Plane*)target, *this, this->collisionDistance );
case ICollideable::Frustrum: 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: return Utility::Intersect( *(Box*)target, *this, this->collisionDistance );
case Type_frustrum: return false; // TODO:
default: return false; default: return false;
} }
} }
@ -44,11 +45,8 @@ bool Ray::Contains( const ICollideable *target ) const
{ {
switch( target->type ) switch( target->type )
{ {
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target, this->collisionDistance ); case Type_point: return Utility::Intersect( *this, *(Point*)target, this->collisionDistance );
case ICollideable::Ray: Utility::contains( *this, *(Collision::Ray*)target ); case Type_ray: Utility::Contains( *this, *(Ray*)target );
default: return false; default: return false;
} }
} }
ICollideable::State Ray::Advanced( const ICollideable *target ) const
{ return ICollideable::Missed; } //Not supported returns 0

View File

@ -7,35 +7,37 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#pragma once #pragma once
#ifndef OYSTER_COLLISION_RAY_H #ifndef OYSTER_COLLISION_3D_RAY_H
#define OYSTER_COLLISION_RAY_H #define OYSTER_COLLISION_3D_RAY_H
#include "OysterMath.h" #include "OysterMath.h"
#include "ICollideable.h" #include "ICollideable.h"
namespace Oyster { namespace Collision namespace Oyster { namespace Collision3D
{ {
class Ray : public ICollideable class Ray : public ICollideable
{ {
public: public:
union union
{ {
struct{ ::Oyster::Math::Float3 origin, direction; }; struct
{
::Oyster::Math::Float3 origin,
direction; /// Assumed to be normalized
};
char byte[2*sizeof(::Oyster::Math::Float3)]; char byte[2*sizeof(::Oyster::Math::Float3)];
}; };
mutable float collisionDistance; mutable float collisionDistance;
Ray( ); Ray( );
Ray( const Ray &ray );
Ray( const ::Oyster::Math::Float3 &origin, const ::Oyster::Math::Float3 &normalizedDirection ); Ray( const ::Oyster::Math::Float3 &origin, const ::Oyster::Math::Float3 &normalizedDirection );
~Ray( ); virtual ~Ray( );
Ray & operator = ( const Ray &ray ); Ray & operator = ( const Ray &ray );
ICollideable* clone( ) const; virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable *target ) const; bool Intersects( const ICollideable *target ) const;
bool Contains( const ICollideable *target ) const; bool Contains( const ICollideable *target ) const;
ICollideable::State Advanced( const ICollideable *target ) const; //Not supported returns 0;
}; };
} } } }

View File

@ -1,13 +1,12 @@
#include "Sphere.h" #include "Sphere.h"
#include "Collision.h" #include "OysterCollision.h"
using namespace ::Oyster::Collision; using namespace ::Oyster::Collision3D;
using namespace ::Oyster::Math; using namespace ::Oyster::Math;
Sphere::Sphere( ) : ICollideable(ICollideable::Sphere), center(), radius(0.0f) { } Sphere::Sphere( ) : ICollideable(Type_sphere), center(), radius(0.0f) { }
Sphere::Sphere( const Sphere &sphere ) : ICollideable(ICollideable::Sphere), center(sphere.center), radius(sphere.radius) {} Sphere::Sphere( const Float3 &_position, const Float &_radius ) : ICollideable(Type_sphere), center(_position), radius(_radius) {}
Sphere::Sphere( const Float3 &_position, const Float &_radius ) : ICollideable(ICollideable::Sphere), center(_position), radius(_radius) {} Sphere::~Sphere( ) {}
Sphere::~Sphere( ) { /*Nothing needs to be done here*/ }
Sphere & Sphere::operator = ( const Sphere &sphere ) Sphere & Sphere::operator = ( const Sphere &sphere )
{ {
@ -16,21 +15,22 @@ Sphere & Sphere::operator = ( const Sphere &sphere )
return *this; return *this;
} }
ICollideable* Sphere::clone( ) const ::Utility::Memory::UniquePointer<ICollideable> Sphere::Clone( ) const
{ return new Sphere( *this ); } { return ::Utility::Memory::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 ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target ); case Type_universe: return true;
case ICollideable::Ray: return Utility::intersect( *this, *(Collision::Ray*)target, ((Collision::Ray*)target)->collisionDistance ); case Type_point: return Utility::Intersect( *this, *(Point*)target );
case ICollideable::Sphere: Utility::intersect( *this, *(Collision::Sphere*)target ); case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance );
case ICollideable::Plane: return Utility::intersect( *(Collision::Plane*)target, *this ); case Type_sphere: Utility::Intersect( *this, *(Sphere*)target );
case ICollideable::Triangle: return false; // TODO case Type_plane: return Utility::Intersect( *(Plane*)target, *this );
case ICollideable::BoxAxisAligned: return Utility::intersect( *(Collision::BoxAxisAligned*)target, *this ); case Type_triangle: return false; // TODO:
case ICollideable::Box: return Utility::intersect( *(Collision::Box*)target, *this ); case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)target, *this );
case ICollideable::Frustrum: return false; // TODO case Type_box: return Utility::Intersect( *(Box*)target, *this );
case Type_frustrum: return false; // TODO:
default: return false; default: return false;
} }
} }
@ -39,15 +39,12 @@ bool Sphere::Contains( const ICollideable *target ) const
{ {
switch( target->type ) switch( target->type )
{ {
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target ); case Type_point: return Utility::Intersect( *this, *(Point*)target );
case ICollideable::Sphere: return Utility::contains( *this, *(Collision::Sphere*)target ); case Type_sphere: return Utility::Contains( *this, *(Sphere*)target );
case ICollideable::Triangle: return false; // TODO case Type_triangle: return false; // TODO:
case ICollideable::BoxAxisAligned: return false; // TODO case Type_box_axis_aligned: return false; // TODO:
case ICollideable::Box: return false; // TODO case Type_box: return false; // TODO:
case ICollideable::Frustrum: return false; // TODO case Type_frustrum: return false; // TODO:
default: return false; default: return false;
} }
} }
ICollideable::State Sphere::Advanced( const ICollideable *target ) const
{ return ICollideable::Missed; } //Not supported returns 0

View File

@ -3,13 +3,13 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#pragma once #pragma once
#ifndef OYSTER_COLLISION_SPHERE_H #ifndef OYSTER_COLLISION_3D_SPHERE_H
#define OYSTER_COLLISION_SPHERE_H #define OYSTER_COLLISION_3D_SPHERE_H
#include "OysterMath.h" #include "OysterMath.h"
#include "ICollideable.h" #include "ICollideable.h"
namespace Oyster { namespace Collision namespace Oyster { namespace Collision3D
{ {
class Sphere : public ICollideable class Sphere : public ICollideable
{ {
@ -21,16 +21,14 @@ namespace Oyster { namespace Collision
}; };
Sphere( ); Sphere( );
Sphere( const Sphere &point ); Sphere( const ::Oyster::Math::Float3 &center, const ::Oyster::Math::Float &radius );
Sphere( const ::Oyster::Math::Float3 &position, const ::Oyster::Math::Float &radius ); virtual ~Sphere( );
~Sphere( );
Sphere & operator = ( const Sphere &sphere ); Sphere & operator = ( const Sphere &sphere );
ICollideable* clone( ) const; virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable *target ) const; bool Intersects( const ICollideable *target ) const;
bool Contains( const ICollideable *target ) const; bool Contains( const ICollideable *target ) const;
ICollideable::State Advanced( const ICollideable *target ) const; //Not supported returns 0;
}; };
} } } }

View File

@ -0,0 +1,34 @@
#include "Universe.h"
#include "OysterCollision.h"
using namespace ::Oyster::Collision3D;
using namespace ::Utility::Memory;
Universe::Universe() : ICollideable(Type_universe) {}
Universe::~Universe() {}
Universe & Universe::operator = ( const Universe &universe )
{ return *this; }
UniquePointer<ICollideable> Universe::Clone( ) const
{ return UniquePointer<ICollideable>( new Universe(*this) ); }
bool Universe::Intersects( const ICollideable *target ) const
{ // universe touches everything
switch( target->type )
{
case Type_ray:
((Ray*)target)->collisionDistance = 0.0f;
break;
case Type_line:
((Line*)target)->ray.collisionDistance = 0.0f;
break;
default: break;
}
return true;
}
bool Sphere::Contains( const ICollideable *target ) const
{ return true; } // universe contains everything

View File

@ -0,0 +1,27 @@
/////////////////////////////////////////////////////////////////////
// Created by Dan Andersson 2013
/////////////////////////////////////////////////////////////////////
#pragma once
#ifndef OYSTER_COLLISION_3D_UNIVERSE_H
#define OYSTER_COLLISION_3D_UNIVERSE_H
#include "ICollideable.h"
namespace Oyster { namespace Collision3D
{
class Universe : public ICollideable
{
public:
Universe();
virtual ~Universe();
Universe & operator = ( const Universe &universe );
virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable *target ) const;
bool Contains( const ICollideable *target ) const;
};
} }
#endif

View File

@ -24,13 +24,13 @@
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset> <PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset> <PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
@ -90,7 +90,7 @@
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc;$(SolutionDir)OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -101,7 +101,7 @@
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc;$(SolutionDir)OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -114,7 +114,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc;$(SolutionDir)OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -129,7 +129,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc;$(SolutionDir)OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -140,26 +140,35 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="Collision\Box.cpp" /> <ClCompile Include="Collision\Box.cpp" />
<ClCompile Include="Collision\BoxAxisAligned.cpp" /> <ClCompile Include="Collision\BoxAxisAligned.cpp" />
<ClCompile Include="Collision\Collision.cpp" /> <ClCompile Include="Collision\OysterCollision.cpp" />
<ClCompile Include="Collision\Frustrum.cpp" /> <ClCompile Include="Collision\Frustrum.cpp" />
<ClCompile Include="Collision\Line.cpp" /> <ClCompile Include="Collision\Line.cpp" />
<ClCompile Include="Collision\Plane.cpp" /> <ClCompile Include="Collision\Plane.cpp" />
<ClCompile Include="Collision\Point.cpp" /> <ClCompile Include="Collision\Point.cpp" />
<ClCompile Include="Collision\Ray.cpp" /> <ClCompile Include="Collision\Ray.cpp" />
<ClCompile Include="Collision\Sphere.cpp" /> <ClCompile Include="Collision\Sphere.cpp" />
<ClCompile Include="Collision\Universe.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Collision\Box.h" /> <ClInclude Include="Collision\Box.h" />
<ClInclude Include="Collision\BoxAxisAligned.h" /> <ClInclude Include="Collision\BoxAxisAligned.h" />
<ClInclude Include="Collision\Collision.h" /> <ClInclude Include="Collision\OysterCollision.h" />
<ClInclude Include="Collision\Frustrum.h" /> <ClInclude Include="Collision\Frustrum.h" />
<ClInclude Include="Collision\ICollideable.h" /> <ClInclude Include="Collision\ICollideable.h" />
<ClInclude Include="Collision\Line.h" /> <ClInclude Include="Collision\Line.h" />
<ClInclude Include="Collision\OysterCollision.h" />
<ClInclude Include="Collision\Plane.h" /> <ClInclude Include="Collision\Plane.h" />
<ClInclude Include="Collision\Point.h" /> <ClInclude Include="Collision\Point.h" />
<ClInclude Include="Collision\Ray.h" /> <ClInclude Include="Collision\Ray.h" />
<ClInclude Include="Collision\Sphere.h" /> <ClInclude Include="Collision\Sphere.h" />
<ClInclude Include="Collision\Universe.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Misc\Misc.vcxproj">
<Project>{2ec4dded-8f75-4c86-a10b-e1e8eb29f3ee}</Project>
</ProjectReference>
<ProjectReference Include="..\OysterMath\OysterMath.vcxproj">
<Project>{f10cbc03-9809-4cba-95d8-327c287b18ee}</Project>
</ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -33,9 +33,6 @@
<ClCompile Include="Collision\BoxAxisAligned.cpp"> <ClCompile Include="Collision\BoxAxisAligned.cpp">
<Filter>Source Files\Collision</Filter> <Filter>Source Files\Collision</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Collision\Collision.cpp">
<Filter>Source Files\Collision</Filter>
</ClCompile>
<ClCompile Include="Collision\Frustrum.cpp"> <ClCompile Include="Collision\Frustrum.cpp">
<Filter>Source Files\Collision</Filter> <Filter>Source Files\Collision</Filter>
</ClCompile> </ClCompile>
@ -54,6 +51,12 @@
<ClCompile Include="Collision\Sphere.cpp"> <ClCompile Include="Collision\Sphere.cpp">
<Filter>Source Files\Collision</Filter> <Filter>Source Files\Collision</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Collision\Universe.cpp">
<Filter>Source Files\Collision</Filter>
</ClCompile>
<ClCompile Include="Collision\OysterCollision.cpp">
<Filter>Source Files\Collision</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Collision\Box.h"> <ClInclude Include="Collision\Box.h">
@ -62,9 +65,6 @@
<ClInclude Include="Collision\BoxAxisAligned.h"> <ClInclude Include="Collision\BoxAxisAligned.h">
<Filter>Header Files\Collision</Filter> <Filter>Header Files\Collision</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Collision\Collision.h">
<Filter>Header Files\Collision</Filter>
</ClInclude>
<ClInclude Include="Collision\Frustrum.h"> <ClInclude Include="Collision\Frustrum.h">
<Filter>Header Files\Collision</Filter> <Filter>Header Files\Collision</Filter>
</ClInclude> </ClInclude>
@ -74,9 +74,6 @@
<ClInclude Include="Collision\Line.h"> <ClInclude Include="Collision\Line.h">
<Filter>Header Files\Collision</Filter> <Filter>Header Files\Collision</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Collision\OysterCollision.h">
<Filter>Header Files\Collision</Filter>
</ClInclude>
<ClInclude Include="Collision\Plane.h"> <ClInclude Include="Collision\Plane.h">
<Filter>Header Files\Collision</Filter> <Filter>Header Files\Collision</Filter>
</ClInclude> </ClInclude>
@ -89,5 +86,11 @@
<ClInclude Include="Collision\Sphere.h"> <ClInclude Include="Collision\Sphere.h">
<Filter>Header Files\Collision</Filter> <Filter>Header Files\Collision</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Collision\Universe.h">
<Filter>Header Files\Collision</Filter>
</ClInclude>
<ClInclude Include="Collision\OysterCollision.h">
<Filter>Header Files\Collision</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>