diff --git a/Bin/DLL/GamePhysics_x86D.pdb b/Bin/DLL/GamePhysics_x86D.pdb new file mode 100644 index 00000000..d19b70c2 Binary files /dev/null and b/Bin/DLL/GamePhysics_x86D.pdb differ diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index d01d95f7..02f5317b 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -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 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 ); diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h index 5de9c05a..aea4c013 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h @@ -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 ); diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp index 80e352ea..49309a99 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -44,12 +44,12 @@ UniquePointer 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(); diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.h b/Code/GamePhysics/Implementation/SimpleRigidBody.h index 9eefeb48..40448292 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.h +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.h @@ -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; diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp index ce31456e..6b63a699 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp @@ -46,12 +46,12 @@ UniquePointer 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(); diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.h b/Code/GamePhysics/Implementation/SphericalRigidBody.h index 4d003f99..cf02a10c 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.h +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.h @@ -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; diff --git a/Code/GamePhysics/PhysicsAPI.h b/Code/GamePhysics/PhysicsAPI.h index 6c43a754..46c8c70d 100644 --- a/Code/GamePhysics/PhysicsAPI.h +++ b/Code/GamePhysics/PhysicsAPI.h @@ -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. diff --git a/Code/GamePhysics/PhysicsFormula.h b/Code/GamePhysics/PhysicsFormula.h index c015e571..156b9e45 100644 --- a/Code/GamePhysics/PhysicsFormula.h +++ b/Code/GamePhysics/PhysicsFormula.h @@ -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 ); } } } } diff --git a/Code/GamePhysics/PhysicsStructs-Impl.h b/Code/GamePhysics/PhysicsStructs-Impl.h index 3de46ee2..daf108bb 100644 --- a/Code/GamePhysics/PhysicsStructs-Impl.h +++ b/Code/GamePhysics/PhysicsStructs-Impl.h @@ -28,12 +28,13 @@ namespace Oyster { namespace Physics this->ignoreGravity = false; } - - inline CustomBodyState::CustomBodyState( const ::Oyster::Math::Float3 &reach, const ::Oyster::Math::Float3 ¢erPos, const ::Oyster::Math::Float3 &rotation ) + inline CustomBodyState::CustomBodyState( const ::Oyster::Math::Float3 &reach, const ::Oyster::Math::Float3 ¢erPos, 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; diff --git a/Code/GamePhysics/PhysicsStructs.h b/Code/GamePhysics/PhysicsStructs.h index c1f74640..e3c20fea 100644 --- a/Code/GamePhysics/PhysicsStructs.h +++ b/Code/GamePhysics/PhysicsStructs.h @@ -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 ¢erPos = ::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 ¢erPos = ::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 ¢erPos ); 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; }; diff --git a/Code/OysterPhysics3D/Box.cpp b/Code/OysterPhysics3D/Box.cpp index 7d67754c..94f948a6 100644 --- a/Code/OysterPhysics3D/Box.cpp +++ b/Code/OysterPhysics3D/Box.cpp @@ -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 ) { diff --git a/Code/OysterPhysics3D/Box.h b/Code/OysterPhysics3D/Box.h index bdef2f9a..3259908f 100644 --- a/Code/OysterPhysics3D/Box.h +++ b/Code/OysterPhysics3D/Box.h @@ -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 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; }; } } diff --git a/Code/OysterPhysics3D/BoxAxisAligned.cpp b/Code/OysterPhysics3D/BoxAxisAligned.cpp index a0ebdd63..bd10016f 100644 --- a/Code/OysterPhysics3D/BoxAxisAligned.cpp +++ b/Code/OysterPhysics3D/BoxAxisAligned.cpp @@ -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 ); diff --git a/Code/OysterPhysics3D/BoxAxisAligned.h b/Code/OysterPhysics3D/BoxAxisAligned.h index 374c888f..2ff39463 100644 --- a/Code/OysterPhysics3D/BoxAxisAligned.h +++ b/Code/OysterPhysics3D/BoxAxisAligned.h @@ -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 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; }; } } diff --git a/Code/OysterPhysics3D/Frustrum.cpp b/Code/OysterPhysics3D/Frustrum.cpp index e8aa65fa..54e6a67f 100644 --- a/Code/OysterPhysics3D/Frustrum.cpp +++ b/Code/OysterPhysics3D/Frustrum.cpp @@ -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 ); diff --git a/Code/OysterPhysics3D/Frustrum.h b/Code/OysterPhysics3D/Frustrum.h index c59d89f5..ba5656c5 100644 --- a/Code/OysterPhysics3D/Frustrum.h +++ b/Code/OysterPhysics3D/Frustrum.h @@ -39,7 +39,7 @@ namespace Oyster { namespace Collision3D virtual ::Utility::DynamicMemory::UniquePointer 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; }; diff --git a/Code/OysterPhysics3D/ICollideable.h b/Code/OysterPhysics3D/ICollideable.h index a8eb9464..b3f61671 100644 --- a/Code/OysterPhysics3D/ICollideable.h +++ b/Code/OysterPhysics3D/ICollideable.h @@ -35,7 +35,7 @@ namespace Oyster { namespace Collision3D //! Contains a collection of 3D shapes virtual ~ICollideable(); virtual ::Utility::DynamicMemory::UniquePointer 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; }; diff --git a/Code/OysterPhysics3D/Line.cpp b/Code/OysterPhysics3D/Line.cpp index 0d3c3dcd..cebceaff 100644 --- a/Code/OysterPhysics3D/Line.cpp +++ b/Code/OysterPhysics3D/Line.cpp @@ -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 ) { diff --git a/Code/OysterPhysics3D/Line.h b/Code/OysterPhysics3D/Line.h index e90e7ac4..2e6d2d55 100644 --- a/Code/OysterPhysics3D/Line.h +++ b/Code/OysterPhysics3D/Line.h @@ -30,7 +30,7 @@ namespace Oyster { namespace Collision3D virtual ::Utility::DynamicMemory::UniquePointer 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; }; } } diff --git a/Code/OysterPhysics3D/OysterCollision3D.cpp b/Code/OysterPhysics3D/OysterCollision3D.cpp index 835be03a..526f87e7 100644 --- a/Code/OysterPhysics3D/OysterCollision3D.cpp +++ b/Code/OysterPhysics3D/OysterCollision3D.cpp @@ -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 ¢erDistance, 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); @@ -511,22 +524,10 @@ 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::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::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; diff --git a/Code/OysterPhysics3D/OysterCollision3D.h b/Code/OysterPhysics3D/OysterCollision3D.h index 603dfc7c..20a55a18 100644 --- a/Code/OysterPhysics3D/OysterCollision3D.h +++ b/Code/OysterPhysics3D/OysterCollision3D.h @@ -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 ); diff --git a/Code/OysterPhysics3D/Particle.cpp b/Code/OysterPhysics3D/Particle.cpp index 830e13b5..c84b1e31 100644 --- a/Code/OysterPhysics3D/Particle.cpp +++ b/Code/OysterPhysics3D/Particle.cpp @@ -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 diff --git a/Code/OysterPhysics3D/Plane.cpp b/Code/OysterPhysics3D/Plane.cpp index 863b0c5a..59ffbc47 100644 --- a/Code/OysterPhysics3D/Plane.cpp +++ b/Code/OysterPhysics3D/Plane.cpp @@ -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 ) { diff --git a/Code/OysterPhysics3D/Plane.h b/Code/OysterPhysics3D/Plane.h index 35b68261..f148ed8e 100644 --- a/Code/OysterPhysics3D/Plane.h +++ b/Code/OysterPhysics3D/Plane.h @@ -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 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; }; } } diff --git a/Code/OysterPhysics3D/Point.cpp b/Code/OysterPhysics3D/Point.cpp index 7a40c7cc..788ab32d 100644 --- a/Code/OysterPhysics3D/Point.cpp +++ b/Code/OysterPhysics3D/Point.cpp @@ -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 ) { diff --git a/Code/OysterPhysics3D/Point.h b/Code/OysterPhysics3D/Point.h index ca6f4082..60486373 100644 --- a/Code/OysterPhysics3D/Point.h +++ b/Code/OysterPhysics3D/Point.h @@ -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 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; }; } } diff --git a/Code/OysterPhysics3D/Ray.cpp b/Code/OysterPhysics3D/Ray.cpp index 6d65fe7f..b68ee68e 100644 --- a/Code/OysterPhysics3D/Ray.cpp +++ b/Code/OysterPhysics3D/Ray.cpp @@ -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 ) { diff --git a/Code/OysterPhysics3D/Ray.h b/Code/OysterPhysics3D/Ray.h index bae600e4..79be0c21 100644 --- a/Code/OysterPhysics3D/Ray.h +++ b/Code/OysterPhysics3D/Ray.h @@ -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 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; }; } } diff --git a/Code/OysterPhysics3D/RigidBody.cpp b/Code/OysterPhysics3D/RigidBody.cpp index 182a5a17..eed27b52 100644 --- a/Code/OysterPhysics3D/RigidBody.cpp +++ b/Code/OysterPhysics3D/RigidBody.cpp @@ -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) ); diff --git a/Code/OysterPhysics3D/Sphere.cpp b/Code/OysterPhysics3D/Sphere.cpp index 8c786f54..c402b2ef 100644 --- a/Code/OysterPhysics3D/Sphere.cpp +++ b/Code/OysterPhysics3D/Sphere.cpp @@ -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 ) { diff --git a/Code/OysterPhysics3D/Sphere.h b/Code/OysterPhysics3D/Sphere.h index e2719328..2f483ecd 100644 --- a/Code/OysterPhysics3D/Sphere.h +++ b/Code/OysterPhysics3D/Sphere.h @@ -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 ¢er, const ::Oyster::Math::Float &radius ); + Sphere( const ::Oyster::Math::Float4 ¢er, const ::Oyster::Math::Float &radius ); virtual ~Sphere( ); Sphere & operator = ( const Sphere &sphere ); virtual ::Utility::DynamicMemory::UniquePointer 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; }; } } diff --git a/Code/OysterPhysics3D/Universe.cpp b/Code/OysterPhysics3D/Universe.cpp index c2308690..7eb788ae 100644 --- a/Code/OysterPhysics3D/Universe.cpp +++ b/Code/OysterPhysics3D/Universe.cpp @@ -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 ) { diff --git a/Code/OysterPhysics3D/Universe.h b/Code/OysterPhysics3D/Universe.h index aa497cbc..5f009e0b 100644 --- a/Code/OysterPhysics3D/Universe.h +++ b/Code/OysterPhysics3D/Universe.h @@ -21,7 +21,7 @@ namespace Oyster { namespace Collision3D virtual ::Utility::DynamicMemory::UniquePointer 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; }; } }