Big patch

Loads of collision response related implementations/edits
This commit is contained in:
Dander7BD 2013-12-18 08:57:27 +01:00
parent 9cdbe2c861
commit dbb0c38432
34 changed files with 412 additions and 286 deletions

Binary file not shown.

View File

@ -17,11 +17,51 @@ namespace
auto proto = worldScene.GetCustomBody( protoTempRef );
auto deuter = worldScene.GetCustomBody( deuterTempRef );
float deltaWhen;
Float3 worldWhere;
if( proto->Intersects(*deuter, 1.0f, deltaWhen, worldWhere) )
Float4 worldPointOfContact;
if( proto->Intersects(*deuter, worldPointOfContact) )
{
proto->CallSubscription( proto, deuter );
switch( proto->CallSubscription(proto, deuter) )
{
case ICustomBody::SubscriptMessage_ignore_collision_response:
break;
default:
{ // Apply CollisionResponse in pure gather pattern
ICustomBody::State protoState; proto->GetState( protoState );
ICustomBody::State deuterState; proto->GetState( deuterState );
Float4 protoG = protoState.GetLinearMomentum( worldPointOfContact ),
deuterG = deuterState.GetLinearMomentum( worldPointOfContact );
// calc from perspective of deuter
Float4 normal; deuter->GetNormalAt( worldPointOfContact, normal );
Float protoG_Magnitude = protoG.Dot( normal ),
deuterG_Magnitude = deuterG.Dot( normal );
// bounce
Float4 sumJ = normal * Formula::CollisionResponse::Impulse( deuterState.GetRestitutionCoeff(),
deuterState.GetMass(), deuterG_Magnitude,
protoState.GetMass(), protoG_Magnitude );
// @todo TODO: friction
// sumJ -= ;
// calc from perspective of proto
proto->GetNormalAt( worldPointOfContact, normal );
protoG_Magnitude = protoG.Dot( normal ),
deuterG_Magnitude = deuterG.Dot( normal );
// bounce
sumJ += normal * Formula::CollisionResponse::Impulse( protoState.GetRestitutionCoeff(),
protoState.GetMass(), protoG_Magnitude,
deuterState.GetMass(), deuterG_Magnitude );
// @todo TODO: friction
// sumJ += ;
protoState.ApplyImpulse( sumJ, worldPointOfContact, normal );
proto->SetState( protoState );
}
break;
}
}
}
}
@ -71,10 +111,16 @@ void API_Impl::SetSubscription( API::EventAction_Destruction functionPointer )
void API_Impl::Update()
{ /** @todo TODO: Update is a temporary solution .*/
::std::vector<ICustomBody*> updateList;
auto proto = this->worldScene.Sample( Universe(), updateList ).begin();
for( ; proto != updateList.end(); ++proto )
{
// Step 1: @todo TODO: Apply Gravity
// Step 2: Apply Collision Response
this->worldScene.Visit( *proto, OnPossibleCollision );
}
@ -135,16 +181,6 @@ void API_Impl::ApplyForceAt( const ICustomBody* objRef, const Float3 &worldPos,
}
}
void API_Impl::ApplyCollisionResponse( const ICustomBody* objRefA, const ICustomBody* objRefB, Float &deltaWhen, Float3 &worldPointOfContact )
{
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRefA );
if( tempRef != this->worldScene.invalid_ref )
{
//! @todo TODO: implement stub
this->worldScene.SetAsAltered( tempRef );
}
}
void API_Impl::SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const Float4x4 &localI )
{ // deprecated
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );

View File

@ -31,7 +31,6 @@ namespace Oyster
void DestroyObject( const ICustomBody* objRef );
void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF );
void ApplyCollisionResponse( const ICustomBody* objRefA, const ICustomBody* objRefB, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact );
void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI );
void SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI );

View File

@ -44,12 +44,12 @@ UniquePointer<ICustomBody> SimpleRigidBody::Clone() const
SimpleRigidBody::State SimpleRigidBody::GetState() const
{
return State( this->rigid.box.boundingOffset, this->rigid.box.center, AngularAxis(this->rigid.box.rotation).xyz );
return State( this->rigid.box.boundingOffset.xyz, this->rigid.box.center.xyz, AngularAxis(this->rigid.box.rotation).xyz, this->rigid.linearMomentum, this->rigid.angularMomentum );
}
SimpleRigidBody::State & SimpleRigidBody::GetState( SimpleRigidBody::State &targetMem ) const
{
return targetMem = State( this->rigid.box.boundingOffset, this->rigid.box.center, AngularAxis(this->rigid.box.rotation).xyz );
return targetMem = State( this->rigid.box.boundingOffset.xyz, this->rigid.box.center.xyz, AngularAxis(this->rigid.box.rotation).xyz, this->rigid.linearMomentum, this->rigid.angularMomentum );
}
void SimpleRigidBody::SetState( const SimpleRigidBody::State &state )
@ -59,9 +59,9 @@ void SimpleRigidBody::SetState( const SimpleRigidBody::State &state )
this->rigid.box.rotation = state.GetRotation();
}
void SimpleRigidBody::CallSubscription( const ICustomBody *proto, const ICustomBody *deuter )
ICustomBody::SubscriptMessage SimpleRigidBody::CallSubscription( const ICustomBody *proto, const ICustomBody *deuter )
{
this->collisionAction( proto, deuter );
return this->collisionAction( proto, deuter );
}
bool SimpleRigidBody::IsAffectedByGravity() const
@ -69,31 +69,27 @@ bool SimpleRigidBody::IsAffectedByGravity() const
return !this->ignoreGravity;
}
bool SimpleRigidBody::Intersects( const ICustomBody &object, Float timeStepLength, Float &deltaWhen, Float3 &worldPointOfContact ) const
{
if( object.Intersects(this->rigid.box) )
{ //! @todo TODO: better implementation needed
deltaWhen = timeStepLength;
worldPointOfContact = Average( this->rigid.box.center, object.GetCenter() );
return true;
}
else
{
return false;
}
}
bool SimpleRigidBody::Intersects( const ICollideable &shape ) const
{
return this->rigid.box.Intersects( shape );
}
bool SimpleRigidBody::Intersects( const ICollideable &shape, Float4 &worldPointOfContact ) const
{
return this->rigid.box.Intersects( shape, worldPointOfContact );
}
bool SimpleRigidBody::Intersects( const ICustomBody &object, Float4 &worldPointOfContact ) const
{
return object.Intersects( this->rigid.box, worldPointOfContact );
}
Sphere & SimpleRigidBody::GetBoundingSphere( Sphere &targetMem ) const
{
return targetMem = Sphere( this->rigid.box.center, this->rigid.box.boundingOffset.GetMagnitude() );
}
Float3 & SimpleRigidBody::GetNormalAt( const Float3 &worldPos, Float3 &targetMem ) const
Float4 & SimpleRigidBody::GetNormalAt( const Float4 &worldPos, Float4 &targetMem ) const
{
//! @todo TODO: better implementation needed
return targetMem = (worldPos - this->rigid.box.center).GetNormalized();

View File

@ -20,13 +20,14 @@ namespace Oyster { namespace Physics
void SetState( const State &state );
::Oyster::Math::Float3 GetRigidLinearVelocity() const;
void CallSubscription( const ICustomBody *proto, const ICustomBody *deuter );
SubscriptMessage CallSubscription( const ICustomBody *proto, const ICustomBody *deuter );
bool IsAffectedByGravity() const;
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float timeStepLength, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) const;
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const;
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const;
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const;
::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) const;
::Oyster::Math::Float3 & GetNormalAt( const ::Oyster::Math::Float3 &worldPos, ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
::Oyster::Math::Float4 & GetNormalAt( const ::Oyster::Math::Float4 &worldPos, ::Oyster::Math::Float4 &targetMem = ::Oyster::Math::Float4() ) const;
::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;

View File

@ -46,12 +46,12 @@ UniquePointer<ICustomBody> SphericalRigidBody::Clone() const
SphericalRigidBody::State SphericalRigidBody::GetState() const
{
return State( this->rigid.box.boundingOffset, this->rigid.box.center, AngularAxis(this->rigid.box.rotation).xyz );
return State( this->rigid.box.boundingOffset.xyz, this->rigid.box.center.xyz, AngularAxis(this->rigid.box.rotation).xyz, this->rigid.linearMomentum, this->rigid.angularMomentum );
}
SphericalRigidBody::State & SphericalRigidBody::GetState( SphericalRigidBody::State &targetMem ) const
{
return targetMem = State( this->rigid.box.boundingOffset, this->rigid.box.center, AngularAxis(this->rigid.box.rotation).xyz );
return targetMem = State( this->rigid.box.boundingOffset.xyz, this->rigid.box.center.xyz, AngularAxis(this->rigid.box.rotation).xyz, this->rigid.linearMomentum, this->rigid.angularMomentum );
}
void SphericalRigidBody::SetState( const SphericalRigidBody::State &state )
@ -61,9 +61,9 @@ void SphericalRigidBody::SetState( const SphericalRigidBody::State &state )
this->rigid.box.rotation = state.GetRotation();
}
void SphericalRigidBody::CallSubscription( const ICustomBody *proto, const ICustomBody *deuter )
ICustomBody::SubscriptMessage SphericalRigidBody::CallSubscription( const ICustomBody *proto, const ICustomBody *deuter )
{
this->collisionAction( proto, deuter );
return this->collisionAction( proto, deuter );
}
bool SphericalRigidBody::IsAffectedByGravity() const
@ -71,23 +71,19 @@ bool SphericalRigidBody::IsAffectedByGravity() const
return !this->ignoreGravity;
}
bool SphericalRigidBody::Intersects( const ICustomBody &object, Float timeStepLength, Float &deltaWhen, Float3 &worldPointOfContact ) const
{
if( object.Intersects(this->body) )
{ //! @todo TODO: better implementation needed
deltaWhen = timeStepLength;
worldPointOfContact = Average( this->body.center, object.GetCenter() );
return true;
}
else
{
return false;
}
}
bool SphericalRigidBody::Intersects( const ICollideable &shape ) const
{
return this->rigid.box.Intersects( shape );
return Sphere( this->rigid.box.center, this->rigid.box.boundingOffset.x ).Intersects( shape );
}
bool SphericalRigidBody::Intersects( const ICollideable &shape, Float4 &worldPointOfContact ) const
{
return Sphere( this->rigid.box.center, this->rigid.box.boundingOffset.x ).Intersects( shape, worldPointOfContact );
}
bool SphericalRigidBody::Intersects( const ICustomBody &object, Float4 &worldPointOfContact ) const
{
return object.Intersects( Sphere(this->rigid.box.center, this->rigid.box.boundingOffset.x), worldPointOfContact );
}
Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
@ -95,7 +91,7 @@ Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
return targetMem = this->body;
}
Float3 & SphericalRigidBody::GetNormalAt( const Float3 &worldPos, Float3 &targetMem ) const
Float4 & SphericalRigidBody::GetNormalAt( const Float4 &worldPos, Float4 &targetMem ) const
{
//! @todo TODO: better implementation needed
return targetMem = (worldPos - this->rigid.box.center).GetNormalized();

View File

@ -21,13 +21,14 @@ namespace Oyster { namespace Physics
void SetState( const State &state );
::Oyster::Math::Float3 GetRigidLinearVelocity() const;
void CallSubscription( const ICustomBody *proto, const ICustomBody *deuter );
SubscriptMessage CallSubscription( const ICustomBody *proto, const ICustomBody *deuter );
bool IsAffectedByGravity() const;
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float timeStepLength, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) const;
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const;
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const;
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const;
::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) const;
::Oyster::Math::Float3 & GetNormalAt( const ::Oyster::Math::Float3 &worldPos, ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
::Oyster::Math::Float4 & GetNormalAt( const ::Oyster::Math::Float4 &worldPos, ::Oyster::Math::Float4 &targetMem = ::Oyster::Math::Float4() ) const;
::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;

View File

@ -132,15 +132,6 @@ namespace Oyster
********************************************************/
virtual void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF ) = 0;
/********************************************************
* Apply force on an object.
* @param objRefA: A pointer to the ICustomBody representing a physical object.
* @param objRefB: A pointer to the ICustomBody representing a physical object.
* @param deltaWhen: The elapsed simulation time since last update frame. [s]
* @param worldPointOfContact: Point of Collision, relative to the world origo. (Not relative to the objects) [m]
********************************************************/
virtual void ApplyCollisionResponse( const ICustomBody* objRefA, const ICustomBody* objRefB, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) = 0;
/********************************************************
* Sets the MomentOfInertia tensor matrix of an object without changing it's angular velocity.
* Noticeable effect: The angular momentum will change. Changing the amount of kinetic energy.
@ -229,11 +220,6 @@ namespace Oyster
SubscriptMessage_ignore_collision_response
};
/********************************************************
* @param gameObjectRef: a pointer to the object in the game owning the rigid body.
********************************************************/
void* gameObjectRef;
typedef SubscriptMessage (*EventAction_Collision)( const ICustomBody *proto, const ICustomBody *deuter );
typedef Struct::SimpleBodyDescription SimpleBodyDescription;
typedef Struct::SphericalBodyDescription SphericalBodyDescription;
@ -250,7 +236,7 @@ namespace Oyster
/********************************************************
* @todo TODO: need doc
********************************************************/
virtual void CallSubscription( const ICustomBody *proto, const ICustomBody *deuter ) = 0;
virtual SubscriptMessage CallSubscription( const ICustomBody *proto, const ICustomBody *deuter ) = 0;
/********************************************************
* @todo TODO: need doc
@ -277,22 +263,28 @@ namespace Oyster
********************************************************/
virtual bool IsAffectedByGravity() const = 0;
/********************************************************
* Performs a detailed Intersect test and returns if, when and where.
* @param object: What this is intersect testing against.
* @param timeStepLength: The value set by API::SetDeltaTime(...)
* @param deltaWhen: Time in seconds since last update frame til timeOfContact. 0.0f <= deltaWhen <= timeStepLength
* @param worldPointOfContact: Where at timeOfContact, this and object touches eachother.
* @return true if this truly intersects with object.
********************************************************/
virtual bool Intersects( const ICustomBody &object, ::Oyster::Math::Float timeStepLength, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) const = 0;
/********************************************************
* param shape: Any defined sample shape.
* @return true if this truly intersects with shape.
********************************************************/
virtual bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const = 0;
/********************************************************
* Performs a detailed Intersect test and returns if, when and where.
* @param shape: Any defined sample shape.
* @param worldPointOfContact: Where at timeOfContact, this and object touches eachother.
* @return true if this truly intersects with object.
********************************************************/
virtual bool Intersects( const ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const = 0;
/********************************************************
* Performs a detailed Intersect test and returns if, when and where.
* @param object: What this is intersect testing against.
* @param worldPointOfContact: Where at timeOfContact, this and object touches eachother.
* @return true if this truly intersects with object.
********************************************************/
virtual bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const = 0;
/********************************************************
* Required by Engine's Collision Search.
* @param targetMem: Provided memory that written into and then returned.
@ -306,7 +298,7 @@ namespace Oyster
* @param targetMem: Provided memory that written into and then returned.
* @return a surface normal in worldSpace.
********************************************************/
virtual ::Oyster::Math::Float3 & GetNormalAt( const ::Oyster::Math::Float3 &worldPos, ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0;
virtual ::Oyster::Math::Float4 & GetNormalAt( const ::Oyster::Math::Float4 &worldPos, ::Oyster::Math::Float4 &targetMem = ::Oyster::Math::Float4() ) const = 0;
/********************************************************
* The gravity normal will have same direction as the total gravity force pulling on this and have the magnitude of 1.0f.

View File

@ -17,8 +17,8 @@ namespace Oyster { namespace Physics { namespace Formula
namespace CollisionResponse
{
::Oyster::Math::Float Impulse( ::Oyster::Math::Float coeffOfRestitution,
::Oyster::Math::Float massA, ::Oyster::Math::Float momentumA,
::Oyster::Math::Float massB, ::Oyster::Math::Float momentumB );
::Oyster::Math::Float massA, ::Oyster::Math::Float momentumA,
::Oyster::Math::Float massB, ::Oyster::Math::Float momentumB );
}
} } }

View File

@ -28,12 +28,13 @@ namespace Oyster { namespace Physics
this->ignoreGravity = false;
}
inline CustomBodyState::CustomBodyState( const ::Oyster::Math::Float3 &reach, const ::Oyster::Math::Float3 &centerPos, const ::Oyster::Math::Float3 &rotation )
inline CustomBodyState::CustomBodyState( const ::Oyster::Math::Float3 &reach, const ::Oyster::Math::Float3 &centerPos, const ::Oyster::Math::Float3 &rotation, const ::Oyster::Math::Float3 &linearMomentum, const ::Oyster::Math::Float3 &angularMomentum )
{
this->reach = ::Oyster::Math::Float4( reach, 0.0f );
this->centerPos = ::Oyster::Math::Float4( centerPos, 1.0f );
this->angularAxis = ::Oyster::Math::Float4( rotation, 0.0f );
this->linearMomentum = ::Oyster::Math::Float4( linearMomentum, 0.0f );
this->angularMomentum = ::Oyster::Math::Float4( angularMomentum, 0.0f );
this->isSpatiallyAltered = this->isDisturbed = false;
}
@ -42,6 +43,8 @@ namespace Oyster { namespace Physics
this->reach = state.reach;
this->centerPos = state.centerPos;
this->angularAxis = state.angularAxis;
this->linearMomentum = state.linearMomentum;
this->angularMomentum = state.angularMomentum;
this->isSpatiallyAltered = state.isSpatiallyAltered;
this->isDisturbed = state.isDisturbed;
@ -73,6 +76,39 @@ namespace Oyster { namespace Physics
return ::Oyster::Math3D::RotationMatrix( this->GetAngularAxis().xyz );
}
inline const ::Oyster::Math::Float CustomBodyState::GetMass() const
{
//! @todo TODO: stub to be implemented (CustomBodyState::GetMass)
return 1.0f;
}
inline const ::Oyster::Math::Float CustomBodyState::GetRestitutionCoeff() const
{
//! @todo TODO: stub to be implemented (CustomBodyState::GetRestitutionCoeff)
return 1.0f;
}
inline const ::Oyster::Math::Float4 & CustomBodyState::GetLinearMomentum() const
{
return this->linearMomentum;
}
inline ::Oyster::Math::Float4 CustomBodyState::GetLinearMomentum( const ::Oyster::Math::Float3 &at ) const
{
return this->GetLinearMomentum( ::Oyster::Math::Float4(at, 1.0f) );
}
inline ::Oyster::Math::Float4 CustomBodyState::GetLinearMomentum( const ::Oyster::Math::Float4 &at ) const
{
//! @todo TODO: stub to be implemented (CustomBodyState::GetLinearMomentum)
return ::Oyster::Math::Float4::null;
}
inline const ::Oyster::Math::Float4 & CustomBodyState::GetAngularMomentum() const
{
return this->angularMomentum;
}
inline void CustomBodyState::SetSize( const ::Oyster::Math::Float3 &size )
{
this->SetReach( 0.5f * size );
@ -102,6 +138,44 @@ namespace Oyster { namespace Physics
this->SetRotation( ::Oyster::Math3D::AngularAxis(rotation).xyz );
}
inline void CustomBodyState::SetMass( ::Oyster::Math::Float m )
{
//! @todo TODO: stub to be implemented (CustomBodyState::SetRestitutionCoeff)
}
inline void CustomBodyState::SetRestitutionCoeff( ::Oyster::Math::Float e )
{
//! @todo TODO: stub to be implemented (CustomBodyState::SetRestitutionCoeff)
}
inline void CustomBodyState::SetLinearMomentum( const ::Oyster::Math::Float3 &g )
{
this->linearMomentum = ::Oyster::Math::Float4( g, 0.0f );
this->isDisturbed = true;
}
inline void CustomBodyState::SetAngularMomentum( const ::Oyster::Math::Float3 &h )
{
this->angularMomentum = ::Oyster::Math::Float4( h, 0.0f );
this->isDisturbed = true;
}
inline void CustomBodyState::ApplyImpulse( const ::Oyster::Math::Float4 &j )
{
this->linearMomentum += j;
this->isDisturbed = true;
}
inline void CustomBodyState::ApplyImpulse( const ::Oyster::Math::Float4 &j, const ::Oyster::Math::Float4 &at, const ::Oyster::Math::Float4 &normal )
{
//! @todo TODO: stub to be implemented (CustomBodyState::ApplyImpulse)
this->linearMomentum += j.Dot( normal ) * normal; // perpendicular impulse component
//this->angularImpulse += Formula:: ...
this->isDisturbed = true;
}
inline bool CustomBodyState::IsSpatiallyAltered() const
{
return this->isSpatiallyAltered;

View File

@ -36,9 +36,11 @@ namespace Oyster { namespace Physics
struct CustomBodyState
{
public:
CustomBodyState( const ::Oyster::Math::Float3 &reach = ::Oyster::Math::Float3::null,
const ::Oyster::Math::Float3 &centerPos = ::Oyster::Math::Float3::null,
const ::Oyster::Math::Float3 &rotation = ::Oyster::Math::Float3::null );
CustomBodyState( const ::Oyster::Math::Float3 &reach = ::Oyster::Math::Float3::null,
const ::Oyster::Math::Float3 &centerPos = ::Oyster::Math::Float3::null,
const ::Oyster::Math::Float3 &rotation = ::Oyster::Math::Float3::null,
const ::Oyster::Math::Float3 &linearMomentum = ::Oyster::Math::Float3::null,
const ::Oyster::Math::Float3 &angularMomentum = ::Oyster::Math::Float3::null );
CustomBodyState & operator = ( const CustomBodyState &state );
@ -47,18 +49,33 @@ namespace Oyster { namespace Physics
const ::Oyster::Math::Float4 & GetCenterPosition() const;
const ::Oyster::Math::Float4 & GetAngularAxis() const;
::Oyster::Math::Float4x4 GetRotation() const;
const ::Oyster::Math::Float GetMass() const;
const ::Oyster::Math::Float GetRestitutionCoeff() const;
const ::Oyster::Math::Float4 & GetLinearMomentum() const;
::Oyster::Math::Float4 GetLinearMomentum( const ::Oyster::Math::Float3 &at ) const;
::Oyster::Math::Float4 GetLinearMomentum( const ::Oyster::Math::Float4 &at ) const;
const ::Oyster::Math::Float4 & GetAngularMomentum() const;
void SetSize( const ::Oyster::Math::Float3 &size );
void SetReach( const ::Oyster::Math::Float3 &halfSize );
void SetCenterPosition( const ::Oyster::Math::Float3 &centerPos );
void SetRotation( const ::Oyster::Math::Float3 &angularAxis );
void SetRotation( const ::Oyster::Math::Float4x4 &rotation );
void SetMass( ::Oyster::Math::Float m );
void SetRestitutionCoeff( ::Oyster::Math::Float e );
void SetLinearMomentum( const ::Oyster::Math::Float3 &g );
void SetAngularMomentum( const ::Oyster::Math::Float3 &h );
void ApplyImpulse( const ::Oyster::Math::Float4 &j );
void ApplyImpulse( const ::Oyster::Math::Float4 &j, const ::Oyster::Math::Float4 &at, const ::Oyster::Math::Float4 &normal );
bool IsSpatiallyAltered() const;
bool IsDisturbed() const;
private:
::Oyster::Math::Float4 reach, centerPos, angularAxis;
::Oyster::Math::Float4 linearMomentum, angularMomentum;
bool isSpatiallyAltered, isDisturbed;
};

View File

@ -18,8 +18,8 @@ Box::Box( ) : ICollideable(Type_box)
Box::Box( const Float4x4 &r, const Float3 &p, const Float3 &s ) : ICollideable(Type_box)
{
this->rotation = r;
this->center = p;
this->boundingOffset = Float3(s*0.5);
this->center = Float4( p, 1.0f );
this->boundingOffset = Float4( s * 0.5f , 0.0f);
}
Box::~Box( ) {}
@ -54,7 +54,7 @@ bool Box::Intersects( const ICollideable &target ) const
}
}
bool Box::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const
bool Box::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
{
switch( target.type )
{

View File

@ -16,14 +16,14 @@ namespace Oyster { namespace Collision3D
public:
union
{
struct{ ::Oyster::Math::Float4x4 rotation; ::Oyster::Math::Float3 center, boundingOffset; };
struct{ ::Oyster::Math::Float4x4 rotation; ::Oyster::Math::Float4 center, boundingOffset; };
struct
{
::Oyster::Math::Float3 xAxis; ::Oyster::Math::Float paddingA;
::Oyster::Math::Float3 yAxis; ::Oyster::Math::Float paddingB;
::Oyster::Math::Float3 zAxis; ::Oyster::Math::Float paddingC;
::Oyster::Math::Float4 xAxis;
::Oyster::Math::Float4 yAxis;
::Oyster::Math::Float4 zAxis;
};
char byte[sizeof(::Oyster::Math::Float4x4) + 2*sizeof(::Oyster::Math::Float3)];
char byte[sizeof(::Oyster::Math::Float4x4) + 2*sizeof(::Oyster::Math::Float4)];
};
Box( );
@ -34,7 +34,7 @@ namespace Oyster { namespace Collision3D
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable &target ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float3 &worldPointOfContact ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
bool Contains( const ICollideable &target ) const;
};
} }

View File

@ -14,16 +14,16 @@ BoxAxisAligned::BoxAxisAligned( ) : ICollideable(Type_box_axis_aligned)
this->maxVertex = Float3( 0.5f, 0.5f, 0.5f );
}
BoxAxisAligned::BoxAxisAligned( const Float3 &_minVertex, const Float3 &_maxVertex ) : ICollideable(Type_box_axis_aligned)
BoxAxisAligned::BoxAxisAligned( const Float3 &minVertex, const Float3 &maxVertex ) : ICollideable(Type_box_axis_aligned)
{
this->minVertex = _minVertex;
this->maxVertex = _maxVertex;
this->minVertex = Float4( minVertex, 1.0f );
this->maxVertex = Float4( maxVertex, 1.0f );
}
BoxAxisAligned::BoxAxisAligned( const Float &leftClip, const Float &rightClip, const Float &topClip, const Float &bottomClip, const Float &nearClip, const Float &farClip ) : ICollideable(Type_box_axis_aligned)
{
this->minVertex = Float3( leftClip, bottomClip, nearClip );
this->maxVertex = Float3( rightClip, topClip, farClip );
this->minVertex = Float4( leftClip, bottomClip, nearClip, 1.0f );
this->maxVertex = Float4( rightClip, topClip, farClip, 1.0f );
}
BoxAxisAligned::~BoxAxisAligned( ) {}
@ -57,7 +57,7 @@ bool BoxAxisAligned::Intersects( const ICollideable &target ) const
}
}
bool BoxAxisAligned::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const
bool BoxAxisAligned::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
{
//! @todo TODO: implement stub properly
return this->Intersects( target );

View File

@ -16,8 +16,8 @@ namespace Oyster { namespace Collision3D
public:
union
{
struct{ ::Oyster::Math::Float3 minVertex, maxVertex; };
char byte[2*sizeof(::Oyster::Math::Float3)];
struct{ ::Oyster::Math::Float4 minVertex, maxVertex; };
char byte[2*sizeof(::Oyster::Math::Float4)];
};
BoxAxisAligned( );
@ -29,7 +29,7 @@ namespace Oyster { namespace Collision3D
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable &target ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float3 &worldPointOfContact ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
bool Contains( const ICollideable &target ) const;
};
} }

View File

@ -76,12 +76,12 @@ namespace PrivateStatic
Frustrum::Frustrum() : ICollideable(Type_frustrum)
{
this->leftPlane = Plane( Float3::standard_unit_x, -0.5f );
this->rightPlane = Plane(-Float3::standard_unit_x, 0.5f ),
this->bottomPlane = Plane( Float3::standard_unit_y, -0.5f );
this->topPlane = Plane(-Float3::standard_unit_y, 0.5f );
this->nearPlane = Plane( Float3::standard_unit_z, -0.5f );
this->farPlane = Plane(-Float3::standard_unit_z, 0.5f );
this->leftPlane = Plane( Float4::standard_unit_x, -0.5f );
this->rightPlane = Plane(-Float4::standard_unit_x, 0.5f ),
this->bottomPlane = Plane( Float4::standard_unit_y, -0.5f );
this->topPlane = Plane(-Float4::standard_unit_y, 0.5f );
this->nearPlane = Plane( Float4::standard_unit_z, -0.5f );
this->farPlane = Plane(-Float4::standard_unit_z, 0.5f );
}
Frustrum::Frustrum( const Float4x4 &vp ) : ICollideable(Type_frustrum)
@ -220,7 +220,7 @@ bool Frustrum::Intersects( const ICollideable &target ) const
}
}
bool Frustrum::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const
bool Frustrum::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
{
//! @todo TODO: implement stub properly
return this->Intersects( target );

View File

@ -39,7 +39,7 @@ namespace Oyster { namespace Collision3D
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable &target ) const;
bool Intersects( const ICollideable &target, Oyster::Math::Float3 &worldPointOfContact ) const;
bool Intersects( const ICollideable &target, Oyster::Math::Float4 &worldPointOfContact ) const;
bool Contains( const ICollideable &target ) const;
};

View File

@ -35,7 +35,7 @@ namespace Oyster { namespace Collision3D //! Contains a collection of 3D shapes
virtual ~ICollideable();
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const = 0;
virtual bool Intersects( const ICollideable &target, ::Oyster::Math::Float3 &worldPointOfContact ) const = 0;
virtual bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const = 0;
virtual bool Intersects( const ICollideable &target ) const = 0;
virtual bool Contains( const ICollideable &target ) const = 0;
};

View File

@ -55,7 +55,7 @@ bool Line::Intersects( const ICollideable &target ) const
return false;
}
bool Line::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const
bool Line::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
{
if( target.type == Type_universe )
{

View File

@ -30,7 +30,7 @@ namespace Oyster { namespace Collision3D
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable &target ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float3 &worldPointOfContact ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
bool Contains( const ICollideable &target ) const;
};
} }

View File

@ -30,10 +30,10 @@ namespace Oyster { namespace Collision3D { namespace Utility
}
// 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 Float4 &axis, const Float &boundingOffset, const Float4 &deltaPos, const Float4 rayDirection, Float &tMin, Float &tMax )
{ // by Dan Andersson
Float e = axis.Dot( deltaPos ),
f = axis.Dot( rayDirection );
f = axis.Dot( rayDirection );
if( EqualsZero(f) ) // if axis is not parallell with ray
{
Float t1 = e + boundingOffset,
@ -51,12 +51,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
return false;
}
inline bool Contains( const Plane &container, const Float3 &pos )
inline bool Contains( const Plane &container, const Float4 &pos )
{ // by Dan Andersson
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 Float4 &pos )
{ // by Dan Andersson
connectOffset = plane.normal.Dot(pos);
connectOffset += plane.phasing;
@ -64,7 +64,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
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
Float4 c = (box.maxVertex + box.minVertex) * 0.5f, // box.Center
h = (box.maxVertex - box.minVertex) * 0.5f; // box.halfSize
boxExtend = h.x * Abs(plane.normal.x); // Box max extending towards plane
boxExtend += h.y * Abs(plane.normal.y);
@ -81,7 +81,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
centerDistance = box.center.Dot(plane.normal) + plane.phasing; // distance between box center and plane
}
bool SeperatingAxisTest_AxisAlignedVsTransformedBox( const Float3 &boundingOffsetA, const Float3 &boundingOffsetB, const Float4x4 &rotationB, const Float4 &worldOffset )
bool SeperatingAxisTest_AxisAlignedVsTransformedBox( const Float4 &boundingOffsetA, const Float4 &boundingOffsetB, const Float4x4 &rotationB, const Float4 &worldOffset )
{ // by Dan Andersson
/*****************************************************************
@ -103,37 +103,37 @@ namespace Oyster { namespace Collision3D { namespace Utility
Float3 absWorldOffset = Abs(worldOffset); // |t|: [absWorldOffset]
// s = { 1, 0, 0 } [ RA.v[0] ]
if( absWorldOffset.x > boundingOffsetA.x + boundingOffsetB.Dot(Float3(absRotationB.v[0].x, absRotationB.v[1].x, absRotationB.v[2].x)) )
if( absWorldOffset.x > boundingOffsetA.x + boundingOffsetB.Dot(Float4(absRotationB.v[0].x, absRotationB.v[1].x, absRotationB.v[2].x, 0.0f)) )
{ // |t dot s| > hA dot |s| + hB dot |s * RB| -->> t.x > hA.x + hB dot |{RB.v[0].x, RB.v[1].x, RB.v[2].x}|
return false;
}
// s = { 0, 1, 0 } [ RA.v[1] ]
if( absWorldOffset.y > boundingOffsetA.y + boundingOffsetB.Dot(Float3(absRotationB.v[0].y, absRotationB.v[1].y, absRotationB.v[2].y)) )
if( absWorldOffset.y > boundingOffsetA.y + boundingOffsetB.Dot(Float4(absRotationB.v[0].y, absRotationB.v[1].y, absRotationB.v[2].y, 0.0f)) )
{ // t.y > hA.y + hB dot |{RB.v[0].y, RB.v[1].y, RB.v[2].y}|
return false;
}
// s = { 0, 0, 1 } [ RA.v[2] ]
if( absWorldOffset.z > boundingOffsetA.z + boundingOffsetB.Dot(Float3(absRotationB.v[0].z, absRotationB.v[1].z, absRotationB.v[2].z)) )
if( absWorldOffset.z > boundingOffsetA.z + boundingOffsetB.Dot(Float4(absRotationB.v[0].z, absRotationB.v[1].z, absRotationB.v[2].z, 0.0f)) )
{ // t.z > hA.z + hB dot |{RB.v[0].z, RB.v[1].z, RB.v[2].z}|
return false;
}
// s = RB.v[0].xyz
if( Abs(worldOffset.Dot(rotationB.v[0])) > boundingOffsetA.Dot(absRotationB.v[0].xyz) + boundingOffsetB.x )
if( Abs(worldOffset.Dot(rotationB.v[0])) > boundingOffsetA.Dot(absRotationB.v[0]) + boundingOffsetB.x )
{ // |t dot s| > hA dot |s| + hB dot |s * RB| -->> |t dot s| > hA dot |s| + hB dot |{1, 0, 0}| -->> |t dot s| > hA dot |s| + hB.x
return false;
}
// s = RB.v[1].xyz
if( Abs(worldOffset.Dot(rotationB.v[1])) > boundingOffsetA.Dot(absRotationB.v[1].xyz) + boundingOffsetB.y )
if( Abs(worldOffset.Dot(rotationB.v[1])) > boundingOffsetA.Dot(absRotationB.v[1]) + boundingOffsetB.y )
{ // |t dot s| > hA dot |s| + hB.y
return false;
}
// s = RB.v[2].xyz
if( Abs(worldOffset.Dot(rotationB.v[2])) > boundingOffsetA.Dot(absRotationB.v[2].xyz) + boundingOffsetB.z )
if( Abs(worldOffset.Dot(rotationB.v[2])) > boundingOffsetA.Dot(absRotationB.v[2]) + boundingOffsetB.z )
{ // |t dot s| > hA dot |s| + hB.z
return false;
}
@ -204,7 +204,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
return true;
}
bool SeperatingAxisTest_AxisAlignedVsTransformedBox( const Float3 &boundingOffsetA, const Float3 &boundingOffsetB, const Float4x4 &rotationB, const Float4 &worldOffset, Float4 &worldPointOfContact )
bool SeperatingAxisTest_AxisAlignedVsTransformedBox( const Float4 &boundingOffsetA, const Float4 &boundingOffsetB, const Float4x4 &rotationB, const Float4 &worldOffset, Float4 &worldPointOfContact )
{ // by Dan Andersson
/*****************************************************************
@ -229,10 +229,11 @@ namespace Oyster { namespace Collision3D { namespace Utility
* = ( p1 + p2 + ... + p5 + p6 ) / 2
*****************************************************************/
const Float4 &t = worldOffset;
Float4 s = Float4::standard_unit_x,
hA = Float4( boundingOffsetA, 0.0f ),
hB = Float4( boundingOffsetB, 0.0f );
const Float4 &t = worldOffset,
&hA = boundingOffsetA,
&hB = boundingOffsetB;
Float4 s = Float4::standard_unit_x;
Float centerSeperation = t.Dot(s),
eA = hA.Dot( Abs(s) ),
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
@ -382,7 +383,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
void Compare( Float &connectDistance, Float &connectOffsetSquared, const Ray &ray, const Point &point )
{ // by Dan Andersson
Float3 dP = point.center - ray.origin;
Float4 dP = point.center - ray.origin;
connectDistance = dP.Dot( ray.direction );
connectDistance /= ray.direction.Dot( ray.direction );
@ -393,7 +394,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
void Compare( Float &connectDistanceA, Float &connectDistanceB, Float &connectOffsetSquared, const Ray &rayA, const Ray &rayB )
{ // by Dan Andersson
Float3 dP = rayB.origin - rayA.origin;
Float4 dP = rayB.origin - rayA.origin;
connectDistanceA = rayA.direction.Dot( dP );
connectDistanceA /= rayA.direction.Dot( rayA.direction );
@ -422,7 +423,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
return true; // Passed all tests, is in same position
}
bool Intersect( const Point &pointA, const Point &pointB, ::Oyster::Math::Float3 &worldPointOfContact )
bool Intersect( const Point &pointA, const Point &pointB, ::Oyster::Math::Float4 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
@ -443,6 +444,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
return false;
}
bool Intersect( const Ray &ray, const Point &point, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float4 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
}
bool Intersect( const Ray &rayA, const Ray &rayB, Float &connectDistanceA, Float &connectDistanceB )
{ // by Dan Andersson
Float connectOffsetSquared;
@ -458,13 +465,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
return false;
}
bool Intersect( const Ray &ray, const Point &point, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float3 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
}
bool Intersect( const Ray &rayA, const Ray &rayB, ::Oyster::Math::Float &connectDistanceA, ::Oyster::Math::Float &connectDistanceB, ::Oyster::Math::Float3 &worldPointOfContact )
bool Intersect( const Ray &rayA, const Ray &rayB, ::Oyster::Math::Float &connectDistanceA, ::Oyster::Math::Float &connectDistanceB, ::Oyster::Math::Float4 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
@ -478,9 +479,15 @@ namespace Oyster { namespace Collision3D { namespace Utility
return true;
}
bool Intersect( const Sphere &sphere, const Point &point, ::Oyster::Math::Float4 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
}
bool Intersect( const Sphere &sphere, const Ray &ray, Float &connectDistance )
{// by Dan Andersson
Float3 dP = sphere.center - ray.origin;
Float4 dP = sphere.center - ray.origin;
Float s = dP.Dot( ray.direction ),
dSquared = dP.Dot( dP ),
rSquared = sphere.radius * sphere.radius;
@ -498,9 +505,15 @@ namespace Oyster { namespace Collision3D { namespace Utility
return true;
}
bool Intersect( const Sphere &sphere, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float4 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
}
bool Intersect( const Sphere &sphereA, const Sphere &sphereB )
{ // by Fredrick Johansson
Float3 C = sphereA.center;
Float4 C = sphereA.center;
C -= sphereB.center;
Float r = (sphereA.radius + sphereB.radius);
@ -512,21 +525,9 @@ namespace Oyster { namespace Collision3D { namespace Utility
return false;
}
bool Intersect( const Sphere &sphere, const Point &point, ::Oyster::Math::Float3 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
}
bool Intersect( const Sphere &sphere, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float3 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
}
bool Intersect( const Sphere &sphereA, const Sphere &sphereB, ::Oyster::Math::Float3 &worldPointOfContact )
bool Intersect( const Sphere &sphereA, const Sphere &sphereB, ::Oyster::Math::Float4 &worldPointOfContact )
{ // by Robin Engman
Float3 C = sphereA.center;
Float4 C = sphereA.center;
C -= sphereB.center;
Float r = sphereA.radius + sphereB.radius;
@ -552,6 +553,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
return Private::EqualsZero(connectOffset);
}
bool Intersect( const Plane &plane, const Point &point, Float4 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
}
bool Intersect( const Plane &plane, const Ray &ray, Float &connectDistance )
{ // by Dan Andersson
Float c = plane.normal.Dot(ray.direction);
@ -572,6 +579,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
return false;
}
bool Intersect( const Plane &plane, const Ray &ray, Float &connectDistance, Float4 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
}
bool Intersect( const Plane &plane, const Sphere &sphere )
{ // by Dan Andersson
Float connectOffset;
@ -579,6 +592,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
return (connectOffset <= sphere.radius);
}
bool Intersect( const Plane &plane, const Sphere &sphere, Float4 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
}
bool Intersect( const Plane &planeA, const Plane &planeB )
{ // by Dan Andersson
if( planeA.normal == planeB.normal ) // they are parallell
@ -588,25 +607,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
return true; // none parallell planes ALWAYS intersects somewhere
}
bool Intersect( const Plane &plane, const Point &point, const ::Oyster::Math::Float3 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
}
bool Intersect( const Plane &plane, const Ray &ray, ::Oyster::Math::Float &connectDistance, const ::Oyster::Math::Float3 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
}
bool Intersect( const Plane &plane, const Sphere &sphere, const ::Oyster::Math::Float3 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
}
bool Intersect( const Plane &planeA, const Plane &planeB, const ::Oyster::Math::Float3 &worldPointOfContact )
bool Intersect( const Plane &planeA, const Plane &planeB, Float4 &worldPointOfContact )
{
//! @todo TODO: implement Stub
return false;
@ -623,7 +624,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
return true;
}
bool Intersect( const BoxAxisAligned &box, const Point &point, Float3 &worldPointOfContact )
bool Intersect( const BoxAxisAligned &box, const Point &point, Float4 &worldPointOfContact )
{ // by Dan Andersson
if( Intersect(box, point) )
{
@ -638,18 +639,18 @@ namespace Oyster { namespace Collision3D { namespace Utility
Float tMin = ::std::numeric_limits<Float>::max(),
tMax = -tMin; // initiating to extremevalues
Float3 boundingOffset = ((box.maxVertex - box.minVertex) * 0.5f),
Float4 boundingOffset = ((box.maxVertex - box.minVertex) * 0.5f),
dP = ((box.maxVertex + box.minVertex) * 0.5f) - ray.origin;
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( Private::BoxVsRayPerSlabCheck( Float4::standard_unit_x, boundingOffset.x, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
if( Private::BoxVsRayPerSlabCheck( Float4::standard_unit_y, boundingOffset.y, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
if( Private::BoxVsRayPerSlabCheck( Float4::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 Ray &ray, Float &connectDistance, Float3 &worldPointOfContact )
bool Intersect( const BoxAxisAligned &box, const Ray &ray, Float &connectDistance, Float4 &worldPointOfContact )
{ // by Dan Andersson
if( Intersect(box, ray, connectDistance) )
{
@ -661,14 +662,14 @@ namespace Oyster { namespace Collision3D { namespace Utility
bool Intersect( const BoxAxisAligned &box, const Sphere &sphere )
{ // by Dan Andersson
Float4 e = Max( Float4(box.minVertex - sphere.center, 0.0f), Float4::null );
e += Max( Float4(sphere.center - box.maxVertex, 0.0f), Float4::null );
Float4 e = Max( box.minVertex - sphere.center, Float4::null );
e += Max( sphere.center - box.maxVertex, Float4::null );
if( e.Dot(e) > (sphere.radius * sphere.radius) ) return false;
return true;
}
bool Intersect( const BoxAxisAligned &box, const Sphere &sphere, Float3 &worldPointOfContact )
bool Intersect( const BoxAxisAligned &box, const Sphere &sphere, Float4 &worldPointOfContact )
{ // by Robin Engman
if(Intersect(box, sphere))
@ -692,7 +693,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
return true;
}
bool Intersect( const BoxAxisAligned &box, const Plane &plane, Float3 &worldPointOfContact )
bool Intersect( const BoxAxisAligned &box, const Plane &plane, Float4 &worldPointOfContact )
{
//! @todo TODO: implement stub
return Intersect( box, plane );
@ -714,7 +715,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
bool Intersect( const Box &box, const Point &point )
{ // by Dan Andersson
Float3 dPos = point.center - box.center;
Float4 dPos = point.center - box.center;
Float coordinate = dPos.Dot( box.xAxis );
if( coordinate > box.boundingOffset.x ) return false;
@ -731,7 +732,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
return true;
}
bool Intersect( const Box &box, const Point &point, Float3 &worldPointOfContact )
bool Intersect( const Box &box, const Point &point, Float4 &worldPointOfContact )
{ // by Dan Andersson
if( Intersect(box, point) )
{
@ -746,7 +747,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
Float tMin = ::std::numeric_limits<Float>::max(),
tMax = -tMin; // initiating to extremevalues
Float3 dP = box.center - ray.origin;
Float4 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; }
@ -756,7 +757,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
return true;
}
bool Intersect( const Box &box, const Ray &ray, Float &connectDistance, Float3 &worldPointOfContact )
bool Intersect( const Box &box, const Ray &ray, Float &connectDistance, Float4 &worldPointOfContact )
{ // by Dan Andersson
if( Intersect(box, ray, connectDistance) )
{
@ -769,16 +770,16 @@ namespace Oyster { namespace Collision3D { namespace Utility
bool Intersect( const Box &box, const Sphere &sphere )
{ // by Dan Andersson
// center: sphere's center in the box's view space
Float4 center = TransformVector( InverseRotationMatrix(box.rotation), Float4(sphere.center - box.center, 0.0f) );
Float4 center = TransformVector( InverseRotationMatrix(box.rotation), sphere.center - box.center );
Float4 e = Max( Float4(-box.boundingOffset, 0.0f) - center, Float4::null );
e += Max( center - Float4(box.boundingOffset, 0.0f), Float4::null );
Float4 e = Max( -box.boundingOffset - center, Float4::null );
e += Max( center - box.boundingOffset, Float4::null );
if( e.Dot(e) > (sphere.radius * sphere.radius) ) return false;
return true;
}
bool Intersect( const Box &box, const Sphere &sphere, Float3 &worldPointOfContact )
bool Intersect( const Box &box, const Sphere &sphere, Float4 &worldPointOfContact )
{ // by Robin Engman
if( Intersect(box, sphere) )
{
@ -801,7 +802,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
return true;
}
bool Intersect( const Box &box, const Plane &plane, Float3 &worldPointOfContact )
bool Intersect( const Box &box, const Plane &plane, Float4 &worldPointOfContact )
{
//! @todo TODO: implement stub
return Intersect( box, plane );
@ -809,18 +810,18 @@ namespace Oyster { namespace Collision3D { namespace Utility
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB )
{ // by Dan Andersson
Float4 alignedOffsetBoundaries = (Float4(boxB.maxVertex, 1.0f) - Float4(boxB.minVertex, 1.0f)) * 0.5f,
offset = Float4(boxA.center, 1.0f) - Average( Float4(boxB.maxVertex, 1.0f), Float4(boxB.minVertex, 1.0f) );
return Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( alignedOffsetBoundaries.xyz, boxA.boundingOffset, boxA.rotation, offset );
Float4 alignedOffsetBoundaries = (boxB.maxVertex - boxB.minVertex) * 0.5f,
offset = boxA.center- Average( boxB.maxVertex, boxB.minVertex );
return Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( alignedOffsetBoundaries, boxA.boundingOffset, boxA.rotation, offset );
}
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB, ::Oyster::Math::Float3 &worldPointOfContact )
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB, ::Oyster::Math::Float4 &worldPointOfContact )
{ // by Dan Andersson
Float4 alignedOffsetBoundaries = (Float4(boxB.maxVertex, 1.0f) - Float4(boxB.minVertex, 1.0f)) * 0.5f,
offset = Float4(boxA.center, 1.0f) - Average( Float4(boxB.maxVertex, 1.0f), Float4(boxB.minVertex, 1.0f) );
Float4 alignedOffsetBoundaries = (boxB.maxVertex - boxB.minVertex) * 0.5f,
offset = boxA.center - Average( boxB.maxVertex, boxB.minVertex );
Float4 pointOfContact;
if( Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( alignedOffsetBoundaries.xyz, boxA.boundingOffset, boxA.rotation, offset, pointOfContact ) )
if( Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( alignedOffsetBoundaries, boxA.boundingOffset, boxA.rotation, offset, pointOfContact ) )
{
worldPointOfContact = pointOfContact.xyz;
return true;
@ -836,7 +837,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
return Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( boxA.boundingOffset, boxB.boundingOffset, rotationB, posB );
}
bool Intersect( const Box &boxA, const Box &boxB, Float3 &worldPointOfContact )
bool Intersect( const Box &boxA, const Box &boxB, Float4 &worldPointOfContact )
{
Float4x4 rotationB = TransformMatrix( InverseRotationMatrix(boxA.rotation), boxB.rotation );
Float4 posB = boxB.center - boxA.center;

View File

@ -25,28 +25,28 @@ namespace Oyster { namespace Collision3D { namespace Utility
void Compare( ::Oyster::Math::Float &connectOffset, const Plane &plane, const Point &point );
bool Intersect( const Point &pointA, const Point &pointB );
bool Intersect( const Point &pointA, const Point &pointB, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Point &pointA, const Point &pointB, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const Ray &ray, const Point &point, ::Oyster::Math::Float &connectDistance );
bool Intersect( const Ray &ray, const Point &point, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const Ray &rayA, const Ray &rayB, ::Oyster::Math::Float &connectDistanceA, ::Oyster::Math::Float &connectDistanceB );
bool Intersect( const Ray &ray, const Point &point, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Ray &rayA, const Ray &rayB, ::Oyster::Math::Float &connectDistanceA, ::Oyster::Math::Float &connectDistanceB, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Ray &rayA, const Ray &rayB, ::Oyster::Math::Float &connectDistanceA, ::Oyster::Math::Float &connectDistanceB, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const Sphere &sphere, const Point &point );
bool Intersect( const Sphere &sphere, const Point &point, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const Sphere &sphere, const Ray &ray, ::Oyster::Math::Float &connectDistance );
bool Intersect( const Sphere &sphere, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const Sphere &sphereA, const Sphere &sphereB );
bool Intersect( const Sphere &sphere, const Point &point, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Sphere &sphere, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Sphere &sphereA, const Sphere &sphereB, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Sphere &sphereA, const Sphere &sphereB, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const Plane &plane, const Point &point );
bool Intersect( const Plane &plane, const Point &point, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const Plane &plane, const Ray &ray, ::Oyster::Math::Float &connectDistance );
bool Intersect( const Plane &plane, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const Plane &plane, const Sphere &sphere );
bool Intersect( const Plane &plane, const Sphere &sphere, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const Plane &planeA, const Plane &planeB );
bool Intersect( const Plane &plane, const Point &point, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Plane &plane, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Plane &plane, const Sphere &sphere, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Plane &planeA, const Plane &planeB, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Plane &planeA, const Plane &planeB, ::Oyster::Math::Float4 &worldPointOfContact );
// bool Intersect( const Triangle &triangle, const Point &point, ? );
// bool Intersect( const Triangle &triangle, const Ray &ray, ? );
@ -55,29 +55,29 @@ namespace Oyster { namespace Collision3D { namespace Utility
// bool Intersect( const Triangle &triangleA, const Triangle &triangleB, ? );
bool Intersect( const BoxAxisAligned &box, const Point &point );
bool Intersect( const BoxAxisAligned &box, const Point &point, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const BoxAxisAligned &box, const Point &point, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const BoxAxisAligned &box, const Ray &ray, ::Oyster::Math::Float &connectDistance );
bool Intersect( const BoxAxisAligned &box, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const BoxAxisAligned &box, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const BoxAxisAligned &box, const Sphere &sphere );
bool Intersect( const BoxAxisAligned &box, const Sphere &sphere, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const BoxAxisAligned &box, const Sphere &sphere, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const BoxAxisAligned &box, const Plane &plane );
bool Intersect( const BoxAxisAligned &box, const Plane &plane, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const BoxAxisAligned &box, const Plane &plane, ::Oyster::Math::Float4 &worldPointOfContact );
// 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 Point &point, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Box &box, const Point &point, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const Box &box, const Ray &ray, ::Oyster::Math::Float &connectDistance );
bool Intersect( const Box &box, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Box &box, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const Box &box, const Sphere &sphere );
bool Intersect( const Box &box, const Sphere &sphere, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Box &box, const Sphere &sphere, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const Box &box, const Plane &plane );
bool Intersect( const Box &box, const Plane &plane, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Box &box, const Plane &plane, ::Oyster::Math::Float4 &worldPointOfContact );
// bool Intersect( const Box &box, const Triangle &triangle, ? );
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB );
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const Box &boxA, const Box &boxB );
bool Intersect( const Box &boxA, const Box &boxB, ::Oyster::Math::Float3 &worldPointOfContact );
bool Intersect( const Box &boxA, const Box &boxB, ::Oyster::Math::Float4 &worldPointOfContact );
bool Intersect( const Frustrum &frustrum, const Point &point );
bool Intersect( const Frustrum &frustrum, const Ray &ray, ::Oyster::Math::Float &connectDistance );

View File

@ -34,7 +34,7 @@ Particle & Particle::operator = ( const Particle &particle )
void Particle::Update_LeapFrog( Float deltaTime )
{ // Euler leap frog update when Runga Kutta is not needed
this->impulseForceSum *= (deltaTime / this->mass); // is now deltaLinearVelocity ( dt * a = dt * F / m )
this->sphere.center += deltaTime * ::Utility::Value::AverageWithDelta( Formula::LinearVelocity(this->mass, this->linearMomentum), this->impulseForceSum );
this->sphere.center.xyz += deltaTime * ::Utility::Value::AverageWithDelta( Formula::LinearVelocity(this->mass, this->linearMomentum), this->impulseForceSum );
this->linearMomentum += Formula::LinearMomentum( this->mass, this->impulseForceSum );
this->impulseForceSum = Float3::null;
@ -66,12 +66,12 @@ void Particle::ApplyLinearImpulseAcceleration( const Float3 &a )
Float3 & Particle::AccessCenter()
{
return this->sphere.center;
return this->sphere.center.xyz;
}
const Float3 & Particle::AccessCenter() const
{
return this->sphere.center;
return this->sphere.center.xyz;
}
Float & Particle::AccessRadius()
@ -91,7 +91,7 @@ const Float & Particle::GetMass() const
const Float3 & Particle::GetCenter() const
{
return this->sphere.center;
return this->sphere.center.xyz;
}
const Float & Particle::GetRadius() const

View File

@ -10,11 +10,11 @@ using namespace ::Oyster::Math;
Plane::Plane( ) : ICollideable(Type_plane)
{
this->normal = Float3::standard_unit_z;
this->normal = Float4::standard_unit_z;
this->phasing = 0.0f;
}
Plane::Plane( const Float3 &n, const Float &p ) : ICollideable(Type_plane)
Plane::Plane( const Float4 &n, const Float &p ) : ICollideable(Type_plane)
{
this->normal = n;
this->phasing = p;
@ -52,7 +52,7 @@ bool Plane::Intersects( const ICollideable &target ) const
}
}
bool Plane::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const
bool Plane::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
{
switch( target.type )
{

View File

@ -16,20 +16,20 @@ namespace Oyster { namespace Collision3D
public:
union
{
struct{ ::Oyster::Math::Float3 normal; ::Oyster::Math::Float phasing; };
::Oyster::Math::Float element[4];
char byte[sizeof(::Oyster::Math::Float3) + sizeof(::Oyster::Math::Float)];
struct{ ::Oyster::Math::Float4 normal; ::Oyster::Math::Float phasing; };
::Oyster::Math::Float element[5];
char byte[sizeof(::Oyster::Math::Float4) + sizeof(::Oyster::Math::Float)];
};
Plane( );
Plane( const ::Oyster::Math::Float3 &normal, const ::Oyster::Math::Float &phasing );
Plane( const ::Oyster::Math::Float4 &normal, const ::Oyster::Math::Float &phasing );
virtual ~Plane( );
Plane & operator = ( const Plane &plane );
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable &target ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float3 &worldPointOfContact ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
bool Contains( const ICollideable &target ) const;
};
} }

View File

@ -10,10 +10,15 @@ using namespace ::Oyster::Math3D;
Point::Point( ) : ICollideable(Type_point)
{
this->center = Float3::null;
this->center = Float4::standard_unit_w;
}
Point::Point( const Float3 &pos ) : ICollideable(Type_point)
{
this->center = Float4( pos, 1.0f );
}
Point::Point( const Float4 &pos ) : ICollideable(Type_point)
{
this->center = pos;
}
@ -48,7 +53,7 @@ bool Point::Intersects( const ICollideable &target ) const
}
}
bool Point::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const
bool Point::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
{
switch( target.type )
{

View File

@ -16,19 +16,20 @@ namespace Oyster { namespace Collision3D
public:
union
{
struct{ ::Oyster::Math::Float3 center; };
char byte[sizeof(::Oyster::Math::Float3)];
struct{ ::Oyster::Math::Float4 center; };
char byte[sizeof(::Oyster::Math::Float4)];
};
Point( );
Point( const ::Oyster::Math::Float3 &position );
Point( const ::Oyster::Math::Float4 &position );
virtual ~Point( );
Point & operator = ( const Point &point );
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable &target ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float3 &worldPointOfContact ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
bool Contains( const ICollideable &target ) const;
};
} }

View File

@ -10,15 +10,15 @@ using namespace ::Oyster::Math3D;
Ray::Ray( ) : ICollideable(Type_ray)
{
this->origin = Float3::null;
this->direction = Float3::standard_unit_z;
this->origin = Float4::standard_unit_w;
this->direction = Float4::standard_unit_z;
this->collisionDistance = 0.0f;
}
Ray::Ray( const Float3 &o, const ::Oyster::Math::Float3 &d ) : ICollideable(Type_ray)
Ray::Ray( const Float3 &o, const Float3 &d ) : ICollideable(Type_ray)
{
this->origin = o;
this->direction = d;
this->origin = Float4( o, 1.0f );
this->direction = Float4( d, 0.0f );
this->collisionDistance = 0.0f;
}
@ -47,15 +47,15 @@ bool Ray::Intersects( const ICollideable &target ) const
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, this->collisionDistance, ((const Ray&)target).collisionDistance );
case Type_sphere: return Utility::Intersect( (const Sphere&)target, *this, this->collisionDistance );
case Type_plane: return Utility::Intersect( (const Plane&)target, *this, this->collisionDistance );
// case Type_triangle: return false; // TODO:
//case Type_triangle: return false; // TODO:
case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this, this->collisionDistance );
case Type_box: return Utility::Intersect( (const Box&)target, *this, this->collisionDistance );
case Type_frustrum: return false; // TODO:
//case Type_frustrum: return false; // TODO:
default: return false;
}
}
bool Ray::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const
bool Ray::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
{
switch( target.type )
{

View File

@ -21,10 +21,10 @@ namespace Oyster { namespace Collision3D
{
struct
{
::Oyster::Math::Float3 origin,
::Oyster::Math::Float4 origin,
direction; /// Assumed to be normalized
};
char byte[2*sizeof(::Oyster::Math::Float3)];
char byte[2*sizeof(::Oyster::Math::Float4)];
};
mutable float collisionDistance;
@ -36,7 +36,7 @@ namespace Oyster { namespace Collision3D
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable &target ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float3 &worldPointOfContact ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
bool Contains( const ICollideable &target ) const;
};
} }

View File

@ -119,12 +119,12 @@ void RigidBody::Update_LeapFrog( Float deltaTime )
rotationAxis /= deltaRadian;
// using rotationAxis, deltaRadian and deltaPos to create a matrix to update the box
this->box.center += deltaPos;
this->box.center.xyz += deltaPos;
TransformMatrix( RotationMatrix(deltaRadian, rotationAxis), this->box.rotation, this->box.rotation );
}
else
{ // no rotation, only use deltaPos to translate the RigidBody
this->box.center += deltaPos;
this->box.center.xyz += deltaPos;
}
// update momentums and clear impulseForceSum and impulseTorqueSum
@ -141,7 +141,7 @@ void RigidBody::ApplyImpulseForce( const Float3 &worldF )
void RigidBody::ApplyImpulseForceAt( const Float3 &worldF, const Float3 &worldPos )
{ // by Dan Andersson
Float3 worldOffset = worldPos - this->box.center;
Float3 worldOffset = worldPos - this->box.center.xyz;
if( worldOffset != Float3::null )
{
this->impulseForceSum += VectorProjection( worldF, worldOffset );
@ -160,7 +160,7 @@ void RigidBody::ApplyLinearImpulseAcceleration( const Float3 &worldA )
void RigidBody::ApplyLinearImpulseAccelerationAt( const Float3 &worldA, const Float3 &worldPos )
{ // by Dan Andersson
Float3 worldOffset = worldPos - this->box.center;
Float3 worldOffset = worldPos - this->box.center.xyz;
if( worldOffset != Float3::null )
{
this->impulseForceSum += Formula::ImpulseForce( this->mass, VectorProjection(worldA, worldOffset) );
@ -188,22 +188,22 @@ void RigidBody::ApplyAngularImpulseAcceleration( const Float3 &worldA )
Float3 & RigidBody::AccessBoundingReach()
{ // by Dan Andersson
return this->box.boundingOffset;
return this->box.boundingOffset.xyz;
}
const Float3 & RigidBody::AccessBoundingReach() const
{ // by Dan Andersson
return this->box.boundingOffset;
return this->box.boundingOffset.xyz;
}
Float3 & RigidBody::AccessCenter()
{ // by Dan Andersson
return this->box.center;
return this->box.center.xyz;
}
const Float3 & RigidBody::AccessCenter() const
{ // by Dan Andersson
return this->box.center;
return this->box.center.xyz;
}
const Float4x4 & RigidBody::GetMomentOfInertia() const
@ -218,7 +218,7 @@ const Float & RigidBody::GetMass() const
const Float4x4 RigidBody::GetOrientation() const
{ // by Dan Andersson
return OrientationMatrix( this->box.rotation, this->box.center );
return OrientationMatrix( this->box.rotation, this->box.center.xyz );
}
Float4x4 RigidBody::GetView() const
@ -228,17 +228,17 @@ Float4x4 RigidBody::GetView() const
const Float3 & RigidBody::GetBoundingReach() const
{ // by Dan Andersson
return this->box.boundingOffset;
return this->box.boundingOffset.xyz;
}
Float3 RigidBody::GetSize() const
{ // by Dan Andersson
return 2.0f * this->box.boundingOffset;
return 2.0f * this->box.boundingOffset.xyz;
}
const Float3 & RigidBody::GetCenter() const
{ // by Dan Andersson
return this->box.center;
return this->box.center.xyz;
}
const Float3 & RigidBody::GetImpulsTorque() const
@ -283,7 +283,7 @@ Float3 RigidBody::GetLinearVelocity() const
void RigidBody::GetMomentumAt( const Float3 &worldPos, const Float3 &surfaceNormal, Float3 &normalMomentum, Float3 &tangentialMomentum ) const
{ // by Dan Andersson
Float3 worldOffset = worldPos - this->box.center;
Float3 worldOffset = worldPos - this->box.center.xyz;
Float3 momentum = Formula::TangentialLinearMomentum( this->angularMomentum, worldOffset );
momentum += this->linearMomentum;
@ -391,21 +391,21 @@ void RigidBody::SetLinearVelocity( const Float3 &worldV )
void RigidBody::SetImpulseForceAt( const Float3 &worldForce, const Float3 &worldPos )
{ // by Dan Andersson
Float3 worldOffset = worldPos - this->box.center;
Float3 worldOffset = worldPos - this->box.center.xyz;
this->impulseForceSum = VectorProjection( worldForce, worldOffset );
this->impulseTorqueSum = Formula::ImpulseTorque( worldForce, worldOffset );
}
void RigidBody::SetLinearMomentumAt( const Float3 &worldG, const Float3 &worldPos )
{ // by Dan Andersson
Float3 worldOffset = worldPos - this->box.center;
Float3 worldOffset = worldPos - this->box.center.xyz;
this->linearMomentum = VectorProjection( worldG, worldOffset );
this->angularMomentum = Formula::AngularMomentum( worldG, worldOffset );
}
void RigidBody::SetImpulseAccelerationAt( const Float3 &worldA, const Float3 &worldPos )
{ // by Dan Andersson
Float3 worldOffset = worldPos - this->box.center;
Float3 worldOffset = worldPos - this->box.center.xyz;
this->impulseForceSum = Formula::ImpulseForce( this->mass, VectorProjection(worldA, worldOffset) );
this->impulseTorqueSum = Formula::ImpulseTorque( this->box.rotation * this->momentOfInertiaTensor,
Formula::AngularImpulseAcceleration(worldA, worldOffset) );
@ -413,7 +413,7 @@ void RigidBody::SetImpulseAccelerationAt( const Float3 &worldA, const Float3 &wo
void RigidBody::SetLinearVelocityAt( const Float3 &worldV, const Float3 &worldPos )
{ // by Dan Andersson
Float3 worldOffset = worldPos - this->box.center;
Float3 worldOffset = worldPos - this->box.center.xyz;
this->linearMomentum = Formula::LinearMomentum( this->mass, VectorProjection(worldV, worldOffset) );
this->angularMomentum = Formula::AngularMomentum( this->box.rotation * this->momentOfInertiaTensor,
Formula::AngularVelocity(worldV, worldOffset) );

View File

@ -6,14 +6,20 @@ using namespace ::Oyster::Math;
Sphere::Sphere( ) : ICollideable(Type_sphere)
{
this->center = Float3::null;
this->center = Float4::standard_unit_w;
this->radius = 0.0f;
}
Sphere::Sphere( const Float3 &_position, const Float &_radius ) : ICollideable(Type_sphere)
Sphere::Sphere( const Float3 &p, const Float &r ) : ICollideable(Type_sphere)
{
this->center = _position;
this->radius = _radius;
this->center = Float4( p, 1.0f );
this->radius = r;
}
Sphere::Sphere( const Float4 &p, const Float &r ) : ICollideable(Type_sphere)
{
this->center = p;
this->radius = r;
}
Sphere::~Sphere( ) {}
@ -47,7 +53,7 @@ bool Sphere::Intersects( const ICollideable &target ) const
}
}
bool Sphere::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const
bool Sphere::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
{
switch( target.type )
{

View File

@ -16,19 +16,20 @@ namespace Oyster { namespace Collision3D
public:
union
{
struct{ ::Oyster::Math::Float3 center; ::Oyster::Math::Float radius; };
char byte[sizeof(::Oyster::Math::Float3) + sizeof(::Oyster::Math::Float)];
struct{ ::Oyster::Math::Float4 center; ::Oyster::Math::Float radius; };
char byte[sizeof(::Oyster::Math::Float4) + sizeof(::Oyster::Math::Float)];
};
Sphere( );
Sphere( const ::Oyster::Math::Float3 &center, const ::Oyster::Math::Float &radius );
Sphere( const ::Oyster::Math::Float4 &center, const ::Oyster::Math::Float &radius );
virtual ~Sphere( );
Sphere & operator = ( const Sphere &sphere );
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable &target ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float3 &worldPointOfContact ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
bool Contains( const ICollideable &target ) const;
};
} }

View File

@ -35,7 +35,7 @@ bool Universe::Intersects( const ICollideable &target ) const
return true;
}
bool Universe::Intersects( const ICollideable &target, Float3 &worldPointOfContact ) const
bool Universe::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
{ // universe touches everything
switch( target.type )
{

View File

@ -21,7 +21,7 @@ namespace Oyster { namespace Collision3D
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
bool Intersects( const ICollideable &target ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float3 &worldPointOfContact ) const;
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
bool Contains( const ICollideable &target ) const;
};
} }