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

View File

@ -3,23 +3,14 @@
/////////////////////////////////////////////////////////////////////
#include "Box.h"
#include "Collision.h"
#include "OysterCollision.h"
using namespace ::Oyster::Collision;
using namespace ::Oyster::Math;
using namespace ::Oyster::Collision3D;
using namespace ::Oyster::Math3D;
Box::Box( ) : ICollideable(ICollideable::Box), orientation(Float4x4::identity), boundingOffset() {}
Box::Box( const Box &box ) : ICollideable(ICollideable::Box), orientation(box.orientation), boundingOffset(box.boundingOffset)
{
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( ) : 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( ) {}
Box & Box::operator = ( const Box &box )
{
@ -28,21 +19,22 @@ Box & Box::operator = ( const Box &box )
return *this;
}
ICollideable* Box::clone( ) const
{ return new Box( *this ); }
::Utility::Memory::UniquePointer<ICollideable> Box::Clone( ) const
{ return ::Utility::Memory::UniquePointer<ICollideable>( new Box(*this) ); }
bool Box::Intersects( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target );
case ICollideable::Ray: return Utility::intersect( *this, *(Collision::Ray*)target, ((Collision::Ray*)target)->collisionDistance );
case ICollideable::Sphere: return Utility::intersect( *this, *(Collision::Sphere*)target );
case ICollideable::Plane: return Utility::intersect( *this, *(Collision::Plane*)target );
case ICollideable::Triangle: return false; // TODO
case ICollideable::BoxAxisAligned: return Utility::intersect( *this, *(Collision::BoxAxisAligned*)target );
case ICollideable::Box: return Utility::intersect( *this, *(Collision::Box*)target );
case ICollideable::Frustrum: return false; // TODO
case Type_universe: return true;
case Type_point: return Utility::Intersect( *this, *(Point*)target );
case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance );
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)target );
case Type_plane: return Utility::Intersect( *this, *(Plane*)target );
case Type_triangle: return false; // TODO: :
case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)target );
case Type_box: return Utility::Intersect( *this, *(Box*)target );
case Type_frustrum: return false; // TODO: :
default: return false;
}
}
@ -51,15 +43,12 @@ bool Box::Contains( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target );
case ICollideable::Sphere: return false; // TODO
case ICollideable::Triangle: return false; // TODO
case ICollideable::BoxAxisAligned: return false; // TODO
case ICollideable::Box: return false; // TODO
case ICollideable::Frustrum: return false; // TODO
case Type_point: return Utility::Intersect( *this, *(Point*)target );
case Type_sphere: return false; // TODO:
case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return false; // TODO:
case Type_box: return false; // TODO:
case Type_frustrum: return false; // TODO:
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
#ifndef OYSTER_COLLISION_BOX_H
#define OYSTER_COLLISION_BOX_H
#ifndef OYSTER_COLLISION_3D_BOX_H
#define OYSTER_COLLISION_3D_BOX_H
#include "OysterMath.h"
#include "ICollideable.h"
namespace Oyster { namespace Collision
namespace Oyster { namespace Collision3D
{
class Box : public ICollideable
{
@ -28,16 +28,14 @@ namespace Oyster { namespace Collision
};
Box( );
Box( const Box &box );
Box( const ::Oyster::Math::Float4x4 &orientation, const ::Oyster::Math::Float3 &size );
~Box( );
virtual ~Box( );
Box & operator = ( const Box &box );
ICollideable* clone( ) const;
virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( 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 "Collision.h"
#include "OysterCollision.h"
using namespace ::Oyster::Collision;
using namespace ::Oyster::Math;
using namespace ::Oyster::Collision3D;
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( const BoxAxisAligned &box ) : ICollideable(ICollideable::BoxAxisAligned), minVertex(box.minVertex), maxVertex(box.maxVertex) {}
BoxAxisAligned::BoxAxisAligned( const Float3 &_minVertex, const Float3 &_maxVertex ) : ICollideable(ICollideable::BoxAxisAligned), minVertex(_minVertex), maxVertex(_maxVertex) {}
BoxAxisAligned::BoxAxisAligned( ) : ICollideable(Type_box_axis_aligned), minVertex(-0.5f,-0.5f,-0.5f), maxVertex(0.5f,0.5f,0.5f) {}
BoxAxisAligned::BoxAxisAligned( const Float3 &_minVertex, const Float3 &_maxVertex ) : ICollideable(Type_box_axis_aligned), minVertex(_minVertex), maxVertex(_maxVertex) {}
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) {}
BoxAxisAligned::~BoxAxisAligned( ) { /*Nothing needs to be done here*/ }
: ICollideable(Type_box_axis_aligned), minVertex(leftClip, bottomClip, nearClip), maxVertex(rightClip, topClip, farClip) {}
BoxAxisAligned::~BoxAxisAligned( ) {}
BoxAxisAligned & BoxAxisAligned::operator = ( const BoxAxisAligned &box )
{
@ -22,21 +21,22 @@ BoxAxisAligned & BoxAxisAligned::operator = ( const BoxAxisAligned &box )
return *this;
}
ICollideable* BoxAxisAligned::clone( ) const
{ return new BoxAxisAligned( *this ); }
::Utility::Memory::UniquePointer<ICollideable> BoxAxisAligned::Clone( ) const
{ return ::Utility::Memory::UniquePointer<ICollideable>( new BoxAxisAligned(*this) ); }
bool BoxAxisAligned::Intersects( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target );
case ICollideable::Ray: return Utility::intersect( *this, *(Collision::Ray*)target, ((Collision::Ray*)target)->collisionDistance );
case ICollideable::Sphere: return Utility::intersect( *this, *(Collision::Sphere*)target );
case ICollideable::Plane: return Utility::intersect( *this, *(Collision::Plane*)target );
case ICollideable::Triangle: return false; // TODO
case ICollideable::BoxAxisAligned: return Utility::intersect( *this, *(Collision::BoxAxisAligned*)target );
case ICollideable::Box: return false; // TODO
case ICollideable::Frustrum: return false; // TODO
case Type_universe: return true;
case Type_point: return Utility::Intersect( *this, *(Point*)target );
case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance );
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)target );
case Type_plane: return Utility::Intersect( *this, *(Plane*)target );
case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)target );
case Type_box: return false; // TODO:
case Type_frustrum: return false; // TODO:
default: return false;
}
}
@ -45,15 +45,12 @@ bool BoxAxisAligned::Contains( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return false; // TODO
case ICollideable::Sphere: return false; // TODO
case ICollideable::Triangle: return false; // TODO
case ICollideable::BoxAxisAligned: return false; // TODO
case ICollideable::Box: return false; // TODO
case ICollideable::Frustrum: return false; // TODO
case Type_point: return false; // TODO:
case Type_sphere: return false; // TODO:
case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return false; // TODO:
case Type_box: return false; // TODO:
case Type_frustrum: return false; // TODO:
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
#ifndef OYSTER_COLLISION_BOXAXISALIGNED_H
#define OYSTER_COLLISION_BOXAXISALIGNED_H
#ifndef OYSTER_COLLISION_3D_BOXAXISALIGNED_H
#define OYSTER_COLLISION_3D_BOXAXISALIGNED_H
#include "OysterMath.h"
#include "ICollideable.h"
namespace Oyster { namespace Collision
namespace Oyster { namespace Collision3D
{
class BoxAxisAligned : public ICollideable
{
@ -21,17 +21,15 @@ namespace Oyster { namespace Collision
};
BoxAxisAligned( );
BoxAxisAligned( const BoxAxisAligned &box );
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( );
virtual ~BoxAxisAligned( );
BoxAxisAligned & operator = ( const BoxAxisAligned &box );
ICollideable* clone( ) const;
virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( 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 "Collision.h"
#include "OysterCollision.h"
using namespace Oyster::Math;
using namespace Oyster::Collision;
using namespace Oyster::Collision3D;
namespace PrivateStatic
{
inline void vpToPlanes( Plane &lp, Plane &rp, Plane &bp, Plane &tp, Plane &np, Plane &fp, const Float4x4 &vp )
{
Float4x4 m = vp.getTranspose();
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();
// left
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.phasing = (m.v[3].w + m.v[0].w) / lp.phasing;
// right
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.phasing = (m.v[3].w - m.v[0].w) / rp.phasing;
// bottom
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.phasing = (m.v[3].w + m.v[1].w) / bp.phasing;
// top
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.phasing = (m.v[3].w - m.v[1].w) / tp.phasing;
// near leftHanded DirectX
np.normal = m.v[2].xyz;
np.phasing = np.normal.length();
np.phasing = np.normal.GetMagnitude();
np.normal /= np.phasing;
np.phasing = m.v[2].w / np.phasing;
// far lefthanded
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.phasing = (m.v[3].w - m.v[2].w) / fp.phasing;
/*/ near rightHanded openGL
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.phasing = -(m.v[3].w + m.v[2].w) / np.phasing;
// far rightHanded
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.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;
target.normal = counterInterpol * planeA.normal;
target.normal += interpolation * planeB.normal;
target.phasing = counterInterpol * planeA.phasing;
target.phasing += interpolation * planeB.phasing;
target.normal.normalize();
target.normal.Normalize();
}
}
Frustrum::Frustrum( ) : ICollideable(ICollideable::Frustrum),
leftPlane(Float3::standardUnitX, -0.5f), rightPlane(-Float3::standardUnitX, 0.5f),
bottomPlane(Float3::standardUnitY, -0.5f), topPlane(-Float3::standardUnitY, 0.5f),
nearPlane(Float3::standardUnitZ, -0.5f), farPlane(-Float3::standardUnitZ, 0.5f) {}
Frustrum::Frustrum( ) : ICollideable(Type_frustrum),
leftPlane(Float3::standard_unit_x, -0.5f), rightPlane(-Float3::standard_unit_x, 0.5f),
bottomPlane(Float3::standard_unit_y, -0.5f), topPlane(-Float3::standard_unit_y, 0.5f),
nearPlane(Float3::standard_unit_z, -0.5f), farPlane(-Float3::standard_unit_z, 0.5f) {}
Frustrum::Frustrum( const Frustrum &frustrum ) : ICollideable(ICollideable::Frustrum),
leftPlane(frustrum.leftPlane), rightPlane(frustrum.rightPlane),
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( const Float4x4 &vp ) : ICollideable(Type_frustrum)
{ PrivateStatic::VP_ToPlanes( this->leftPlane, this->rightPlane, this->bottomPlane, this->topPlane, this->nearPlane, this->farPlane, vp ); }
Frustrum::~Frustrum( ) {}
Frustrum & Frustrum::operator = ( const Frustrum &frustrum )
{
this->leftPlane = frustrum.leftPlane;
this->rightPlane = frustrum.rightPlane;
this->bottomPlane = frustrum.bottomPlane;
this->topPlane = frustrum.topPlane;
this->nearPlane = frustrum.nearPlane;
this->farPlane = frustrum.farPlane;
this->plane[0] = frustrum.plane[0];
this->plane[1] = frustrum.plane[1];
this->plane[2] = frustrum.plane[2];
this->plane[3] = frustrum.plane[3];
this->plane[4] = frustrum.plane[4];
this->plane[5] = frustrum.plane[5];
return *this;
}
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;
}
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,
incrementY = 1.0f / numY,
@ -119,9 +114,9 @@ void Frustrum::split( Frustrum target[], unsigned int numX, unsigned int numY, u
stepY = numX,
stepZ = numX * numY;
Collision::Plane invRight( -this->rightPlane.normal, -this->rightPlane.phasing ),
invBottom( -this->bottomPlane.normal, -this->bottomPlane.phasing ),
invFar( -this->farPlane.normal, -this->farPlane.phasing );
Plane invRight( -this->rightPlane.normal, -this->rightPlane.phasing ),
invBottom( -this->bottomPlane.normal, -this->bottomPlane.phasing ),
invFar( -this->farPlane.normal, -this->farPlane.phasing );
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;
else
{
PrivateStatic::interpolatePlanes( target[i].leftPlane, this->leftPlane, invRight, interpolX );
PrivateStatic::InterpolatePlanes( target[i].leftPlane, this->leftPlane, invRight, interpolX );
unsigned int iLeft = i - 1;
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;
else
{
PrivateStatic::interpolatePlanes( target[i].topPlane, this->topPlane, invBottom, interpolY );
PrivateStatic::InterpolatePlanes( target[i].topPlane, this->topPlane, invBottom, interpolY );
unsigned int iAbove = i - stepY;
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;
else
{
PrivateStatic::interpolatePlanes( target[i].nearPlane, this->nearPlane, invFar, interpolZ );
PrivateStatic::InterpolatePlanes( target[i].nearPlane, this->nearPlane, invFar, interpolZ );
unsigned int iCloser = i - stepZ;
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];
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 = &fMem[4];
}
nextIndex += 6 * ::Utility::StaticArray::numElementsOf( this->plane[0].byte );
nextIndex += 6 * ::Utility::StaticArray::NumElementsOf( this->plane[0].byte );
}
ICollideable* Frustrum::clone( ) const
{ return new Frustrum(*this); }
::Utility::Memory::UniquePointer<ICollideable> Frustrum::Clone( ) const
{ return ::Utility::Memory::UniquePointer<ICollideable>( new Frustrum(*this) ); }
bool Frustrum::Intersects( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target );
case ICollideable::Ray: return Utility::intersect( *this, *(Collision::Ray*)target, ((Collision::Ray*)target)->collisionDistance );
case ICollideable::Sphere: return Utility::intersect( *this, *(Collision::Sphere*)target );
case ICollideable::Plane: return Utility::intersect( *this, *(Collision::Plane*)target );
case ICollideable::Triangle: return false; // TODO
case ICollideable::BoxAxisAligned: return Utility::intersect( *this, *(Collision::BoxAxisAligned*)target );
case ICollideable::Box: return Utility::intersect( *this, *(Collision::Box*)target );
case ICollideable::Frustrum: return Utility::intersect( *this, *(Collision::Frustrum*)target );
case ICollideable::Line: return false; // TODO
case Type_universe: return true;
case Type_point: return Utility::Intersect( *this, *(Point*)target );
case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance );
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)target );
case Type_plane: return Utility::Intersect( *this, *(Plane*)target );
case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)target );
case Type_box: return Utility::Intersect( *this, *(Box*)target );
case Type_frustrum: return Utility::Intersect( *this, *(Frustrum*)target );
case Type_line: return false; // TODO:
default: return false;
}
}
@ -217,18 +213,15 @@ bool Frustrum::Contains( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target );
case ICollideable::Ray: return false; // TODO
case ICollideable::Sphere: return false; // TODO
case ICollideable::Plane: return false; // TODO
case ICollideable::Triangle: return false; // TODO
case ICollideable::BoxAxisAligned: return false; // TODO
case ICollideable::Box: return false; // TODO
case ICollideable::Frustrum: return false; // TODO
case ICollideable::Line: return false; // TODO
case Type_point: return Utility::Intersect( *this, *(Point*)target );
case Type_ray: return false; // TODO:
case Type_sphere: return false; // TODO:
case Type_plane: return false; // TODO:
case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return false; // TODO:
case Type_box: return false; // TODO:
case Type_frustrum: return false; // TODO:
case Type_line: return false; // TODO:
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
#ifndef OYSTER_COLLISION_FRUSTRUM_H
#define OYSTER_COLLISION_FRUSTRUM_H
#ifndef OYSTER_COLLISION_3D_FRUSTRUM_H
#define OYSTER_COLLISION_3D_FRUSTRUM_H
#include "OysterMath.h"
#include "ICollideable.h"
#include "Plane.h"
namespace Oyster { namespace Collision
namespace Oyster { namespace Collision3D
{
class Frustrum : public ICollideable
@ -25,20 +25,18 @@ namespace Oyster { namespace Collision
};
Frustrum( );
Frustrum( const Frustrum &frustrum );
Frustrum( const ::Oyster::Math::Float4x4 &viewProjection );
~Frustrum( );
virtual ~Frustrum( );
Frustrum & operator = ( const Frustrum &frustrum );
Frustrum & operator = ( const ::Oyster::Math::Float4x4 &viewProjection );
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 Split( Frustrum targetList[], unsigned int numX, unsigned int numY = 1U, unsigned int numZ = 1u ) 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 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
/////////////////////////////////////////////////////////////////////
#pragma once
#ifndef 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.
{
class ICollideable
@ -31,7 +32,7 @@ namespace Oyster { namespace Collision3D /// Contains a collection of 3D shapes
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 Contains( const ICollideable *target ) const = 0;
};

View File

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

View File

@ -3,14 +3,14 @@
/////////////////////////////////////////////////////////////////////
#pragma once
#ifndef OYSTER_COLLISION_LINE_H
#define OYSTER_COLLISION_LINE_H
#ifndef OYSTER_COLLISION_3D_LINE_H
#define OYSTER_COLLISION_3D_LINE_H
#include "OysterMath.h"
#include "ICollideable.h"
#include "Ray.h"
namespace Oyster { namespace Collision
namespace Oyster { namespace Collision3D
{
class Line : public ICollideable
{
@ -22,17 +22,15 @@ namespace Oyster { namespace Collision
};
Line( );
Line( const Line &line );
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( );
virtual ~Line( );
Line & operator = ( const Line &line );
ICollideable* clone( ) const;
virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( 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
/////////////////////////////////////////////////////////////////////
#include "Collision.h"
#include "OysterCollision.h"
#include "Utilities.h"
#include <limits>
using namespace Oyster::Math;
using namespace Oyster::Math3D;
namespace Oyster { namespace Collision { namespace Utility
namespace Oyster { namespace Collision3D { namespace Utility
{
// PRIVATE HEADER ///////////////////////////////////////////////////
@ -17,30 +17,30 @@ namespace Oyster { namespace Collision { namespace Utility
const Float epsilon = (const Float)1e-20;
// 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
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
inline bool notEqualsZero( const Float &value )
inline bool NotEqualsZero( const Float &value )
{ // by Dan Andersson
return ::Utility::Value::abs( value ) > epsilon;
return ::Utility::Value::Abs( value ) > epsilon;
}
// 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
Float e = axis.dot( deltaPos ),
f = axis.dot( rayDirection );
if( equalsZero(f) ) // if axis is not parallell with ray
Float e = axis.Dot( deltaPos ),
f = axis.Dot( rayDirection );
if( EqualsZero(f) ) // if axis is not parallell with ray
{
Float t1 = e + boundingOffset,
t2 = e - boundingOffset;
t1 /= f; t2 /= f;
if( t1 > t2 ) ::Utility::Element::swap( t1, t2 );
tMin = ::Utility::Value::max( tMin, t1 );
tMax = ::Utility::Value::min( tMax, t2 );
if( t1 > t2 ) ::Utility::Element::Swap( t1, t2 );
tMin = ::Utility::Value::Max( tMin, t1 );
tMax = ::Utility::Value::Min( tMax, t2 );
if( tMin > tMax ) return true;
if( tMax < 0.0f ) return true;
}
@ -50,116 +50,116 @@ namespace Oyster { namespace Collision { namespace Utility
return false;
}
inline bool contains( const Plane &container, const Float3 &pos )
inline bool Contains( const Plane &container, const Float3 &pos )
{ // 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
connectOffset = plane.normal.dot(pos);
connectOffset = plane.normal.Dot(pos);
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
Float3 c = (box.maxVertex + box.minVertex) * 0.5f, // box.Center
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.y * ::Utility::Value::abs(plane.normal.y);
boxExtend += h.z * ::Utility::Value::abs(plane.normal.z);
centerDistance = c.dot(plane.normal) + plane.phasing; // distance between box center and 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.z * ::Utility::Value::Abs(plane.normal.z);
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
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.z * ::Utility::Value::abs(plane.normal.dot(box.orientation.v[2].xyz));
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.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
Float4x4 absOrientationB;
{
Float4x4 tO = orientationB.getTranspose();
absOrientationB.v[0] = ::Utility::Value::abs(tO.v[0]);
if( absOrientationB.v[0].w > boundingOffsetA.x + boundingOffsetB.dot(absOrientationB.v[0].xyz) ) return false;
absOrientationB.v[1] = ::Utility::Value::abs(tO.v[1]);
if( absOrientationB.v[1].w > boundingOffsetA.y + boundingOffsetB.dot(absOrientationB.v[1].xyz) ) return false;
absOrientationB.v[2] = ::Utility::Value::abs(tO.v[2]);
if( absOrientationB.v[2].w > boundingOffsetA.z + boundingOffsetB.dot(absOrientationB.v[2].xyz) ) return false;
Float4x4 tO = orientationB.GetTranspose();
absOrientationB.v[0] = ::Utility::Value::Abs(tO.v[0]);
if( absOrientationB.v[0].w > boundingOffsetA.x + boundingOffsetB.Dot(absOrientationB.v[0].xyz) ) return false;
absOrientationB.v[1] = ::Utility::Value::Abs(tO.v[1]);
if( absOrientationB.v[1].w > boundingOffsetA.y + boundingOffsetB.Dot(absOrientationB.v[1].xyz) ) return false;
absOrientationB.v[2] = ::Utility::Value::Abs(tO.v[2]);
if( absOrientationB.v[2].w > boundingOffsetA.z + boundingOffsetB.Dot(absOrientationB.v[2].xyz) ) return false;
}
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[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;
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[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;
// ( 1,0,0 ) x orientationB.v[0].xyz:
Float d = boundingOffsetA.y * absOrientationB.v[0].z;
d += boundingOffsetA.z * absOrientationB.v[0].y;
d += boundingOffsetB.y * absOrientationB.v[2].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:
d = boundingOffsetA.y * absOrientationB.v[1].z;
d += boundingOffsetA.z * absOrientationB.v[1].y;
d += boundingOffsetB.x * absOrientationB.v[2].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:
d = boundingOffsetA.y * absOrientationB.v[2].z;
d += boundingOffsetA.z * absOrientationB.v[2].y;
d += boundingOffsetB.x * absOrientationB.v[1].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:
d = boundingOffsetA.x * absOrientationB.v[0].z;
d += boundingOffsetA.z * absOrientationB.v[0].x;
d += boundingOffsetB.y * absOrientationB.v[2].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:
d = boundingOffsetA.x * absOrientationB.v[1].z;
d += boundingOffsetA.z * absOrientationB.v[1].x;
d += boundingOffsetB.x * absOrientationB.v[2].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:
d = boundingOffsetA.x * absOrientationB.v[2].z;
d += boundingOffsetA.z * absOrientationB.v[2].x;
d += boundingOffsetB.x * absOrientationB.v[1].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:
d = boundingOffsetA.x * absOrientationB.v[0].y;
d += boundingOffsetA.y * absOrientationB.v[0].x;
d += boundingOffsetB.y * absOrientationB.v[2].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:
d = boundingOffsetA.x * absOrientationB.v[1].y;
d += boundingOffsetA.y * absOrientationB.v[1].x;
d += boundingOffsetB.x * absOrientationB.v[2].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:
d = boundingOffsetA.x * absOrientationB.v[2].y;
d += boundingOffsetA.y * absOrientationB.v[2].x;
d += boundingOffsetB.x * absOrientationB.v[1].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;
}
@ -167,54 +167,54 @@ namespace Oyster { namespace Collision { namespace Utility
// 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
Float3 dP = point.position - ray.origin;
Float3 dP = point.center - ray.origin;
connectDistance = dP.dot( ray.direction );
connectDistance /= ray.direction.dot( ray.direction );
connectDistance = dP.Dot( ray.direction );
connectDistance /= ray.direction.Dot( 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
Float3 dP = rayB.origin - rayA.origin;
connectDistanceA = rayA.direction.dot( dP );
connectDistanceA /= rayA.direction.dot( rayA.direction );
connectDistanceA = rayA.direction.Dot( dP );
connectDistanceA /= rayA.direction.Dot( rayA.direction );
dP *= -1.0f;
connectDistanceB = rayB.direction.dot( dP );
connectDistanceB /= rayB.direction.dot( rayB.direction );
connectDistanceB = rayB.direction.Dot( dP );
connectDistanceB /= rayB.direction.Dot( rayB.direction );
dP = rayA.direction * connectDistanceA;
dP += rayA.origin;
dP -= rayB.direction * connectDistanceB;
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
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
if (pointA.position.x != pointB.position.x) return false;
if (pointA.position.y != pointB.position.y) return false;
if (pointA.position.z != pointB.position.z) return false;
return true; // Passed all tests, is in same position
if (pointA.center.x != pointB.center.x) return false;
if (pointA.center.y != pointB.center.y) return false;
if (pointA.center.z != pointB.center.z) return false;
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
Float connectOffsetSquared;
compare( connectDistance, connectOffsetSquared, ray, point );
Compare( connectDistance, connectOffsetSquared, ray, point );
if( Private::equalsZero(connectOffsetSquared) )
if( Private::EqualsZero(connectOffsetSquared) )
{
connectOffsetSquared = 0.0f;
return true;
@ -224,12 +224,12 @@ namespace Oyster { namespace Collision { namespace Utility
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
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;
return true;
@ -239,19 +239,19 @@ namespace Oyster { namespace Collision { namespace Utility
return false;
}
bool intersect( const Sphere &sphere, const Point &point )
bool Intersect( const Sphere &sphere, const Point &point )
{ // by Dan Andersson
Float3 dP = point.position - sphere.center;
if( dP.dot(dP) > (sphere.radius * sphere.radius) )
Float3 dP = point.center - sphere.center;
if( dP.Dot(dP) > (sphere.radius * sphere.radius) )
return false;
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
Float3 dP = sphere.center - ray.origin;
Float s = dP.dot( ray.direction ),
dSquared = dP.dot( dP ),
Float s = dP.Dot( ray.direction ),
dSquared = dP.Dot( dP ),
rSquared = sphere.radius * sphere.radius;
if( dSquared <= rSquared ) { connectDistance = 0.0f; return true; }
@ -267,13 +267,13 @@ namespace Oyster { namespace Collision { namespace Utility
return true;
}
bool intersect( const Sphere &sphereA, const Sphere &sphereB )
bool Intersect( const Sphere &sphereA, const Sphere &sphereB )
{ // by Fredrick Johansson
Float3 C = sphereA.center;
C -= sphereB.center;
Float r = (sphereA.radius + sphereB.radius);
if (r*r >= C.dot(C))
if (r*r >= C.Dot(C))
{
return true; // Intersect detected!
}
@ -281,24 +281,24 @@ namespace Oyster { namespace Collision { namespace Utility
return false;
}
bool intersect( const Plane &plane, const Point &point )
bool Intersect( const Plane &plane, const Point &point )
{ // by Dan Andersson
Float connectOffset;
Private::compare( connectOffset, plane, point.position );
return Private::equalsZero(connectOffset);
Private::Compare( connectOffset, plane, point.center );
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
Float c = plane.normal.dot(ray.direction);
if( Private::equalsZero(c) )
Float c = plane.normal.Dot(ray.direction);
if( Private::EqualsZero(c) )
{ // ray is parallell with the plane. (ray direction orthogonal with the planar normal)
connectDistance = 0.0f;
return contains( plane, ray.origin );
return Contains( plane, ray.origin );
}
connectDistance = -plane.phasing;
connectDistance -= plane.normal.dot( ray.origin );
connectDistance -= plane.normal.Dot( ray.origin );
connectDistance /= c;
if( connectDistance > 0.0f )
@ -308,14 +308,14 @@ namespace Oyster { namespace Collision { namespace Utility
return false;
}
bool intersect( const Plane &plane, const Sphere &sphere )
bool Intersect( const Plane &plane, const Sphere &sphere )
{ // by Dan Andersson
Float connectOffset;
Private::compare( connectOffset, plane, sphere.center );
Private::Compare( connectOffset, plane, sphere.center );
return (connectOffset <= sphere.radius);
}
bool intersect( const Plane &planeA, const Plane &planeB )
bool Intersect( const Plane &planeA, const Plane &planeB )
{ // by Dan Andersson
if( planeA.normal == planeB.normal ) // they are parallell
return (planeA.phasing == planeB.phasing);
@ -324,55 +324,55 @@ namespace Oyster { namespace Collision { namespace Utility
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
if( point.position.x < box.minVertex.x ) return false;
if( point.position.x > box.maxVertex.x ) return false;
if( point.position.y < box.minVertex.y ) return false;
if( point.position.y > box.maxVertex.y ) return false;
if( point.position.z < box.minVertex.z ) return false;
if( point.position.z > box.maxVertex.z ) return false;
if( point.center.x < box.minVertex.x ) return false;
if( point.center.x > box.maxVertex.x ) return false;
if( point.center.y < box.minVertex.y ) return false;
if( point.center.y > box.maxVertex.y ) return false;
if( point.center.z < box.minVertex.z ) return false;
if( point.center.z > box.maxVertex.z ) return false;
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
Float tMin = ::std::numeric_limits<Float>::max(),
tMax = -tMin; // initiating to extremevalues
Float3 boundingOffset = ((box.maxVertex - box.minVertex) * 0.5f),
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::standardUnitY, 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_x, boundingOffset.x, 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::standard_unit_z, boundingOffset.z, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
if( tMin > 0.0f ) connectDistance = tMin;
else connectDistance = tMax;
return true;
}
bool intersect( const BoxAxisAligned &box, const Sphere &sphere )
bool Intersect( const BoxAxisAligned &box, const Sphere &sphere )
{ // by Dan Andersson
Float3 e = ::Utility::Value::max( box.minVertex - sphere.center, Float3::null );
e += ::Utility::Value::max( sphere.center - box.maxVertex, Float3::null );
Float3 e = ::Utility::Value::Max( box.minVertex - sphere.center, 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;
}
bool intersect( const BoxAxisAligned &box, const Plane &plane )
bool Intersect( const BoxAxisAligned &box, const Plane &plane )
{ // by Dan Andersson
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 above
return true;
}
// bool intersect( const BoxAxisAligned &box, const Triangle &triangle )
// { return false; /* TODO */ }
// bool Intersect( const BoxAxisAligned &box, const Triangle &triangle )
// { return false; /* TODO: */ }
bool intersect( const BoxAxisAligned &boxA, const BoxAxisAligned &boxB )
bool Intersect( const BoxAxisAligned &boxA, const BoxAxisAligned &boxB )
{ // by Dan Andersson
if( boxA.maxVertex.x < boxB.minVertex.x ) return false;
if( boxA.minVertex.x > boxB.maxVertex.x ) return false;
@ -383,144 +383,144 @@ namespace Oyster { namespace Collision { namespace Utility
return true;
}
bool intersect( const Box &box, const Point &point )
bool Intersect( const Box &box, const Point &point )
{ // 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;
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;
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;
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
Float tMin = ::std::numeric_limits<Float>::max(),
tMax = -tMin; // initiating to extremevalues
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.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.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.zAxis, box.boundingOffset.z, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
if( tMin > 0.0f ) connectDistance = tMin;
else connectDistance = tMax;
return true;
}
bool intersect( const Box &box, const Sphere &sphere )
bool Intersect( const Box &box, const Sphere &sphere )
{ // by Dan Andersson
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( centerL - box.boundingOffset, Float3::null );
e = ::Utility::Value::Max( (box.boundingOffset + centerL)*=-1.0f, 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;
}
bool intersect( const Box &box, const Plane &plane )
bool Intersect( const Box &box, const Plane &plane )
{// by Dan Andersson
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 above
return true;
}
bool intersect( const Box &boxA, const BoxAxisAligned &boxB )
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB )
{ // by Dan Andersson
Float3 alignedOffsetBoundaries = boxB.maxVertex - boxB.minVertex;
Float4x4 translated = boxA.orientation;
translated.v[3].xyz -= boxB.minVertex;
translated.v[3].xyz += alignedOffsetBoundaries * 0.5f;
alignedOffsetBoundaries = ::Utility::Value::abs(alignedOffsetBoundaries);
return Private::fifteenAxisVsAlignedAxisOverlappingChecks( alignedOffsetBoundaries, boxA.boundingOffset, translated );
alignedOffsetBoundaries = ::Utility::Value::Abs(alignedOffsetBoundaries);
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
Float4x4 M;
inverseRigidBodyMatrix( M, boxA.orientation );
transformMatrix( M, boxB.orientation, M );
return Private::fifteenAxisVsAlignedAxisOverlappingChecks( boxA.boundingOffset, boxB.boundingOffset, M );
InverseOrientationMatrix( boxA.orientation, M );
TransformMatrix( M, boxB.orientation, M ); /// TODO: not verified
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
Float connectOffset;
Private::compare( connectOffset, frustrum.leftPlane, point.position );
Private::Compare( connectOffset, frustrum.leftPlane, point.center );
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;
Private::compare( connectOffset, frustrum.bottomPlane, point.position );
Private::Compare( connectOffset, frustrum.bottomPlane, point.center );
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;
Private::compare( connectOffset, frustrum.nearPlane, point.position );
Private::Compare( connectOffset, frustrum.nearPlane, point.center );
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;
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
bool intersected = false;
Float distance = 0.0f;
connectDistance = ::std::numeric_limits<Float>::max();
if( intersect(frustrum.leftPlane, ray, distance) )
if( Intersect(frustrum.leftPlane, ray, distance) )
{
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;
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;
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;
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;
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;
connectDistance = ::Utility::Value::min( connectDistance, distance );
connectDistance = ::Utility::Value::Min( connectDistance, distance );
}
if( intersected ) return true;
@ -529,99 +529,99 @@ namespace Oyster { namespace Collision { namespace Utility
return false;
}
bool intersect( const Frustrum &frustrum, const Sphere &sphere )
bool Intersect( const Frustrum &frustrum, const Sphere &sphere )
{ // by Dan Andersson
Float connectOffset;
Private::compare( connectOffset, frustrum.leftPlane, sphere.center );
Private::Compare( connectOffset, frustrum.leftPlane, sphere.center );
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;
Private::compare( connectOffset, frustrum.bottomPlane, sphere.center );
Private::Compare( connectOffset, frustrum.bottomPlane, sphere.center );
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;
Private::compare( connectOffset, frustrum.nearPlane, sphere.center );
Private::Compare( connectOffset, frustrum.nearPlane, sphere.center );
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;
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
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
Private::compare( e, d, frustrum.rightPlane, box );
Private::Compare( e, d, frustrum.rightPlane, box );
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
Private::compare( e, d, frustrum.topPlane, box );
Private::Compare( e, d, frustrum.topPlane, box );
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
Private::compare( e, d, frustrum.farPlane, box );
Private::Compare( e, d, frustrum.farPlane, box );
if( d - e > 0.0f ) return false; // is beneath
return true;
}
bool intersect( const Frustrum &frustrum, const Box &box )
bool Intersect( const Frustrum &frustrum, const Box &box )
{ // by Dan Andersson
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
Private::compare( e, d, frustrum.rightPlane, box );
Private::Compare( e, d, frustrum.rightPlane, box );
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
Private::compare( e, d, frustrum.topPlane, box );
Private::Compare( e, d, frustrum.topPlane, box );
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
Private::compare( e, d, frustrum.farPlane, box );
Private::Compare( e, d, frustrum.farPlane, box );
if( d - e > 0.0f ) return false; // is beneath
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
// Check if SphereB is larger than sphereA
if (sphereA.radius < sphereB.radius)
@ -634,7 +634,7 @@ namespace Oyster { namespace Collision { namespace Utility
Float deltaR = sphereA.radius - sphereB.radius;
// Check if contained
if (d.dot(d) <= (deltaR*deltaR))
if (d.Dot(d) <= (deltaR*deltaR))
{
return true;
}
@ -643,18 +643,18 @@ namespace Oyster { namespace Collision { namespace Utility
return false;
}
bool contains( const Plane &container, const Point &point )
bool Contains( const Plane &container, const Point &point )
{ // 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
if( Private::notEqualsZero(container.normal.dot(ray.direction)) ) return false;
return contains( container, ray.origin );
if( Private::NotEqualsZero(container.normal.Dot(ray.direction)) ) return false;
return Contains( container, ray.origin );
}
bool contains( const Plane &container, const Plane &plane )
bool Contains( const Plane &container, const Plane &plane )
{ // by Dan Andersson
if( container.phasing == plane.phasing )
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 "Universe.h"
#include "Point.h"
#include "Ray.h"
#include "Plane.h"
#include "Sphere.h"
#include "Plane.h"
//#include "Triangle.h"
#include "BoxAxisAligned.h"
#include "Box.h"
#include "Frustrum.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 "Collision.h"
#include "OysterCollision.h"
using namespace ::Oyster::Collision;
using namespace ::Oyster::Collision3D;
using namespace ::Oyster::Math;
Plane::Plane( ) : ICollideable(ICollideable::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(ICollideable::Plane), normal(n), phasing(p) {}
Plane::~Plane( ) { /*Nothing needs to be done here*/ }
Plane::Plane( ) : ICollideable(Type_plane), normal(), phasing(0.0f) {}
Plane::Plane( const Float3 &n, const Float &p ) : ICollideable(Type_plane), normal(n), phasing(p) {}
Plane::~Plane( ) {}
Plane & Plane::operator = ( const Plane &plane )
{
@ -20,22 +19,23 @@ Plane & Plane::operator = ( const Plane &plane )
return *this;
}
ICollideable* Plane::clone( ) const
{ return new Plane( *this ); }
::Utility::Memory::UniquePointer<ICollideable> Plane::Clone( ) const
{ return ::Utility::Memory::UniquePointer<ICollideable>( new Plane(*this) ); }
bool Plane::Intersects( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target );
case ICollideable::Ray: return Utility::intersect( *this, *(Collision::Ray*)target, ((Collision::Ray*)target)->collisionDistance );
case ICollideable::Sphere: return Utility::intersect( *this, *(Collision::Sphere*)target );
case ICollideable::Plane: return Utility::intersect( *this, *(Collision::Plane*)target );
case ICollideable::Triangle: return false; // TODO
case ICollideable::BoxAxisAligned: return Utility::intersect( *(Collision::BoxAxisAligned*)target, *this );
case ICollideable::Box: return Utility::intersect( *(Collision::Box*)target, *this );
case ICollideable::Frustrum: return false; // TODO
case ICollideable::Line: return false; // TODO
case Type_universe: return true;
case Type_point: return Utility::Intersect( *this, *(Point*)target );
case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance );
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)target );
case Type_plane: return Utility::Intersect( *this, *(Plane*)target );
case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)target, *this );
case Type_box: return Utility::Intersect( *(Box*)target, *this );
case Type_frustrum: return false; // TODO:
case Type_line: return false; // TODO:
default: return false;
}
}
@ -44,13 +44,10 @@ bool Plane::Contains( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target );
case ICollideable::Ray: return Utility::contains( *this, *(Collision::Ray*)target );
case ICollideable::Plane: return Utility::contains( *this, *(Collision::Plane*)target );
case ICollideable::Triangle: return false; // TODO
case Type_point: return Utility::Intersect( *this, *(Point*)target );
case Type_ray: return Utility::Contains( *this, *(Ray*)target );
case Type_plane: return Utility::Contains( *this, *(Plane*)target );
case Type_triangle: return false; // TODO:
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
#ifndef OYSTER_COLLISION_PLANE_H
#define OYSTER_COLLISION_PLANE_H
#ifndef OYSTER_COLLISION_3D_PLANE_H
#define OYSTER_COLLISION_3D_PLANE_H
#include "OysterMath.h"
#include "ICollideable.h"
namespace Oyster { namespace Collision
namespace Oyster { namespace Collision3D
{
class Plane : public ICollideable
{
@ -22,16 +22,14 @@ namespace Oyster { namespace Collision
};
Plane( );
Plane( const Plane &plane );
Plane( const ::Oyster::Math::Float3 &normal, const ::Oyster::Math::Float &phasing );
~Plane( );
virtual ~Plane( );
Plane & operator = ( const Plane &plane );
ICollideable* clone( ) const;
virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( 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 "Collision.h"
#include "OysterCollision.h"
using namespace ::Oyster::Collision;
using namespace ::Oyster::Math;
using namespace ::Oyster::Collision3D;
using namespace ::Oyster::Math3D;
Point::Point( ) : ICollideable(ICollideable::Point), position() {}
Point::Point( const Point &point ) : ICollideable(ICollideable::Point), position(point.position) {}
Point::Point( const Float3 &pos ) : ICollideable(ICollideable::Point), position(pos) {}
Point::~Point( ) { /*Nothing needs to be done here*/ }
Point::Point( ) : ICollideable(Type_point), center() {}
Point::Point( const Float3 &pos ) : ICollideable(Type_point), center(pos) {}
Point::~Point( ) {}
Point & Point::operator = ( const Point &point )
{
this->position = point.position;
this->center = point.center;
return *this;
}
ICollideable* Point::clone( ) const
{ return new Point( *this ); }
::Utility::Memory::UniquePointer<ICollideable> Point::Clone( ) const
{ return ::Utility::Memory::UniquePointer<ICollideable>( new Point(*this) ); }
bool Point::Intersects( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target );
case ICollideable::Ray: return Utility::intersect( *(Collision::Ray*)target, *this, ((Collision::Ray*)target)->collisionDistance );
case ICollideable::Sphere: Utility::intersect( *(Collision::Sphere*)target, *this );
case ICollideable::Plane: return Utility::intersect( *(Collision::Plane*)target, *this );
case ICollideable::Triangle: return false; // TODO
case ICollideable::BoxAxisAligned: return Utility::intersect( *(Collision::BoxAxisAligned*)target, *this );
case ICollideable::Box: return Utility::intersect( *(Collision::Box*)target, *this );
case ICollideable::Frustrum: return false; // TODO
case Type_universe: return true;
case Type_point: return Utility::Intersect( *this, *(Point*)target );
case Type_ray: return Utility::Intersect( *(Ray*)target, *this, ((Ray*)target)->collisionDistance );
case Type_sphere: Utility::Intersect( *(Sphere*)target, *this );
case Type_plane: return Utility::Intersect( *(Plane*)target, *this );
case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)target, *this );
case Type_box: return Utility::Intersect( *(Box*)target, *this );
case Type_frustrum: return false; // TODO:
default: return false;
}
}
@ -42,10 +42,7 @@ bool Point::Contains( const ICollideable *target ) const
{
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;
}
}
ICollideable::State Point::Advanced( const ICollideable *target ) const
{ return ICollideable::Missed; } //Not supported returns 0
}

View File

@ -3,34 +3,32 @@
/////////////////////////////////////////////////////////////////////
#pragma once
#ifndef OYSTER_COLLISION_POINT_H
#define OYSTER_COLLISION_POINT_H
#ifndef OYSTER_COLLISION_3D_POINT_H
#define OYSTER_COLLISION_3D_POINT_H
#include "OysterMath.h"
#include "ICollideable.h"
namespace Oyster { namespace Collision
namespace Oyster { namespace Collision3D
{
class Point : public ICollideable
{
public:
union
{
struct{ ::Oyster::Math::Float3 position; };
struct{ ::Oyster::Math::Float3 center; };
char byte[sizeof(::Oyster::Math::Float3)];
};
Point( );
Point( const Point &point );
Point( const ::Oyster::Math::Float3 &position );
~Point( );
virtual ~Point( );
Point & operator = ( const Point &point );
ICollideable* clone( ) const;
virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( 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 "Collision.h"
#include "OysterCollision.h"
using namespace ::Oyster::Collision;
using namespace ::Oyster::Math;
using namespace ::Oyster::Collision3D;
using namespace ::Oyster::Math3D;
Ray::Ray( ) : ICollideable(ICollideable::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(ICollideable::Ray), origin(o), direction(d), collisionDistance(0.0f) {}
Ray::~Ray( ) { /*Nothing needs to be done here*/ }
Ray::Ray( ) : ICollideable(Type_ray), origin(), 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( ) {}
Ray & Ray::operator = ( const Ray &ray )
{
this->origin = ray.origin;
this->direction = ray.direction;
this->collisionDistance = ray.collisionDistance;
return *this;
}
ICollideable* Ray::clone( ) const
{ return new Ray( *this ); }
::Utility::Memory::UniquePointer<ICollideable> Ray::Clone( ) const
{ return ::Utility::Memory::UniquePointer<ICollideable>( new Ray(*this) ); }
bool Ray::Intersects( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target, this->collisionDistance );
case ICollideable::Ray: return Utility::intersect( *this, *(Collision::Ray*)target, this->collisionDistance, ((Collision::Ray*)target)->collisionDistance );
case ICollideable::Sphere: return Utility::intersect( *(Collision::Sphere*)target, *this, this->collisionDistance );
case ICollideable::Plane: return Utility::intersect( *(Collision::Plane*)target, *this, this->collisionDistance );
case ICollideable::Triangle: return false; // TODO
case ICollideable::BoxAxisAligned: return Utility::intersect( *(Collision::BoxAxisAligned*)target, *this, this->collisionDistance );
case ICollideable::Box: return Utility::intersect( *(Collision::Box*)target, *this, this->collisionDistance );
case ICollideable::Frustrum: return false; // TODO
case Type_universe:
this->collisionDistance = 0.0f;
return true;
case Type_point: return Utility::Intersect( *this, *(Point*)target, this->collisionDistance );
case Type_ray: return Utility::Intersect( *this, *(Ray*)target, this->collisionDistance, ((Ray*)target)->collisionDistance );
case Type_sphere: return Utility::Intersect( *(Sphere*)target, *this, this->collisionDistance );
case Type_plane: return Utility::Intersect( *(Plane*)target, *this, this->collisionDistance );
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;
}
}
@ -44,11 +45,8 @@ bool Ray::Contains( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target, this->collisionDistance );
case ICollideable::Ray: Utility::contains( *this, *(Collision::Ray*)target );
case Type_point: return Utility::Intersect( *this, *(Point*)target, this->collisionDistance );
case Type_ray: Utility::Contains( *this, *(Ray*)target );
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
#ifndef OYSTER_COLLISION_RAY_H
#define OYSTER_COLLISION_RAY_H
#ifndef OYSTER_COLLISION_3D_RAY_H
#define OYSTER_COLLISION_3D_RAY_H
#include "OysterMath.h"
#include "ICollideable.h"
namespace Oyster { namespace Collision
namespace Oyster { namespace Collision3D
{
class Ray : public ICollideable
{
public:
union
{
struct{ ::Oyster::Math::Float3 origin, direction; };
struct
{
::Oyster::Math::Float3 origin,
direction; /// Assumed to be normalized
};
char byte[2*sizeof(::Oyster::Math::Float3)];
};
mutable float collisionDistance;
Ray( );
Ray( const Ray &ray );
Ray( const ::Oyster::Math::Float3 &origin, const ::Oyster::Math::Float3 &normalizedDirection );
~Ray( );
virtual ~Ray( );
Ray & operator = ( const Ray &ray );
ICollideable* clone( ) const;
virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( 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 "Collision.h"
#include "OysterCollision.h"
using namespace ::Oyster::Collision;
using namespace ::Oyster::Collision3D;
using namespace ::Oyster::Math;
Sphere::Sphere( ) : ICollideable(ICollideable::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(ICollideable::Sphere), center(_position), radius(_radius) {}
Sphere::~Sphere( ) { /*Nothing needs to be done here*/ }
Sphere::Sphere( ) : ICollideable(Type_sphere), center(), radius(0.0f) { }
Sphere::Sphere( const Float3 &_position, const Float &_radius ) : ICollideable(Type_sphere), center(_position), radius(_radius) {}
Sphere::~Sphere( ) {}
Sphere & Sphere::operator = ( const Sphere &sphere )
{
@ -16,21 +15,22 @@ Sphere & Sphere::operator = ( const Sphere &sphere )
return *this;
}
ICollideable* Sphere::clone( ) const
{ return new Sphere( *this ); }
::Utility::Memory::UniquePointer<ICollideable> Sphere::Clone( ) const
{ return ::Utility::Memory::UniquePointer<ICollideable>( new Sphere(*this) ); }
bool Sphere::Intersects( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target );
case ICollideable::Ray: return Utility::intersect( *this, *(Collision::Ray*)target, ((Collision::Ray*)target)->collisionDistance );
case ICollideable::Sphere: Utility::intersect( *this, *(Collision::Sphere*)target );
case ICollideable::Plane: return Utility::intersect( *(Collision::Plane*)target, *this );
case ICollideable::Triangle: return false; // TODO
case ICollideable::BoxAxisAligned: return Utility::intersect( *(Collision::BoxAxisAligned*)target, *this );
case ICollideable::Box: return Utility::intersect( *(Collision::Box*)target, *this );
case ICollideable::Frustrum: return false; // TODO
case Type_universe: return true;
case Type_point: return Utility::Intersect( *this, *(Point*)target );
case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance );
case Type_sphere: Utility::Intersect( *this, *(Sphere*)target );
case Type_plane: return Utility::Intersect( *(Plane*)target, *this );
case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)target, *this );
case Type_box: return Utility::Intersect( *(Box*)target, *this );
case Type_frustrum: return false; // TODO:
default: return false;
}
}
@ -39,15 +39,12 @@ bool Sphere::Contains( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target );
case ICollideable::Sphere: return Utility::contains( *this, *(Collision::Sphere*)target );
case ICollideable::Triangle: return false; // TODO
case ICollideable::BoxAxisAligned: return false; // TODO
case ICollideable::Box: return false; // TODO
case ICollideable::Frustrum: return false; // TODO
case Type_point: return Utility::Intersect( *this, *(Point*)target );
case Type_sphere: return Utility::Contains( *this, *(Sphere*)target );
case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return false; // TODO:
case Type_box: return false; // TODO:
case Type_frustrum: return false; // TODO:
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
#ifndef OYSTER_COLLISION_SPHERE_H
#define OYSTER_COLLISION_SPHERE_H
#ifndef OYSTER_COLLISION_3D_SPHERE_H
#define OYSTER_COLLISION_3D_SPHERE_H
#include "OysterMath.h"
#include "ICollideable.h"
namespace Oyster { namespace Collision
namespace Oyster { namespace Collision3D
{
class Sphere : public ICollideable
{
@ -21,16 +21,14 @@ namespace Oyster { namespace Collision
};
Sphere( );
Sphere( const Sphere &point );
Sphere( const ::Oyster::Math::Float3 &position, const ::Oyster::Math::Float &radius );
~Sphere( );
Sphere( const ::Oyster::Math::Float3 &center, const ::Oyster::Math::Float &radius );
virtual ~Sphere( );
Sphere & operator = ( const Sphere &sphere );
ICollideable* clone( ) const;
virtual ::Utility::Memory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( 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>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
@ -90,7 +90,7 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)Misc;$(SolutionDir)OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -101,7 +101,7 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)Misc;$(SolutionDir)OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -114,7 +114,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)Misc;$(SolutionDir)OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -129,7 +129,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)Misc;$(SolutionDir)OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -140,26 +140,35 @@
<ItemGroup>
<ClCompile Include="Collision\Box.cpp" />
<ClCompile Include="Collision\BoxAxisAligned.cpp" />
<ClCompile Include="Collision\Collision.cpp" />
<ClCompile Include="Collision\OysterCollision.cpp" />
<ClCompile Include="Collision\Frustrum.cpp" />
<ClCompile Include="Collision\Line.cpp" />
<ClCompile Include="Collision\Plane.cpp" />
<ClCompile Include="Collision\Point.cpp" />
<ClCompile Include="Collision\Ray.cpp" />
<ClCompile Include="Collision\Sphere.cpp" />
<ClCompile Include="Collision\Universe.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Collision\Box.h" />
<ClInclude Include="Collision\BoxAxisAligned.h" />
<ClInclude Include="Collision\Collision.h" />
<ClInclude Include="Collision\OysterCollision.h" />
<ClInclude Include="Collision\Frustrum.h" />
<ClInclude Include="Collision\ICollideable.h" />
<ClInclude Include="Collision\Line.h" />
<ClInclude Include="Collision\OysterCollision.h" />
<ClInclude Include="Collision\Plane.h" />
<ClInclude Include="Collision\Point.h" />
<ClInclude Include="Collision\Ray.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>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

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