diff --git a/GamePhysics/GamePhysics.vcxproj b/GamePhysics/GamePhysics.vcxproj new file mode 100644 index 00000000..78b667ef --- /dev/null +++ b/GamePhysics/GamePhysics.vcxproj @@ -0,0 +1,150 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {104FA3E9-94D9-4E1D-A941-28A03BC8A095} + GamePhysics + + + + DynamicLibrary + true + v110 + MultiByte + + + DynamicLibrary + true + v110 + MultiByte + + + DynamicLibrary + false + v110 + true + MultiByte + + + DynamicLibrary + false + v110 + true + MultiByte + + + + + + + + + + + + + + + + + + + $(SolutionDir)..\External\Bin\DLL\ + $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ + $(ProjectName)_$(PlatformShortName)D + + + $(SolutionDir)..\External\Bin\DLL\ + $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ + $(ProjectName)_$(PlatformShortName) + + + $(SolutionDir)..\External\Bin\DLL\ + $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ + $(ProjectName)_$(PlatformShortName)D + + + $(SolutionDir)..\External\Bin\DLL\ + $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ + $(ProjectName)_$(PlatformShortName) + + + + Level3 + Disabled + $(SolutionDir)Misc;$(SolutionDir)OysterMath;$(SolutionDir)OysterPhysics3D;%(AdditionalIncludeDirectories) + + + true + + + + + Level3 + Disabled + $(SolutionDir)Misc;$(SolutionDir)OysterMath;$(SolutionDir)OysterPhysics3D;%(AdditionalIncludeDirectories) + + + true + + + + + Level3 + MaxSpeed + true + true + $(SolutionDir)Misc;$(SolutionDir)OysterMath;$(SolutionDir)OysterPhysics3D;%(AdditionalIncludeDirectories) + + + true + true + true + + + + + Level3 + MaxSpeed + true + true + $(SolutionDir)Misc;$(SolutionDir)OysterMath;$(SolutionDir)OysterPhysics3D;%(AdditionalIncludeDirectories) + + + true + true + true + + + + + {2ec4dded-8f75-4c86-a10b-e1e8eb29f3ee} + + + {f10cbc03-9809-4cba-95d8-327c287b18ee} + + + {4285bd3f-3c6c-4670-b7af-a29afef5f6a8} + + + + + + \ No newline at end of file diff --git a/GamePhysics/GamePhysics.vcxproj.filters b/GamePhysics/GamePhysics.vcxproj.filters new file mode 100644 index 00000000..435a7286 --- /dev/null +++ b/GamePhysics/GamePhysics.vcxproj.filters @@ -0,0 +1,23 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {f2cb55b8-47a0-45c7-8dce-5b93f945a57b} + + + {cac9a78f-f09b-4850-b1aa-ea87e8368678} + + + \ No newline at end of file diff --git a/OysterMath/LinearMath.h b/OysterMath/LinearMath.h index fdd39006..8ee69154 100644 --- a/OysterMath/LinearMath.h +++ b/OysterMath/LinearMath.h @@ -284,30 +284,38 @@ namespace LinearAlgebra3D } template - ::LinearAlgebra::Matrix4x4 & OrientationMatrix( const ::LinearAlgebra::Vector3 &sumDeltaAngularAxis, const ::LinearAlgebra::Vector3 &sumTranslation, ::LinearAlgebra::Matrix4x4 &targetMem = ::LinearAlgebra::Matrix4x4() ) - { /// TODO: not tested - ScalarType radian = sumDeltaAngularAxis.Dot( sumDeltaAngularAxis ); - if( radian > 0 ) - { - radian = ::std::sqrt( radian ); - ::LinearAlgebra::Vector3 axis = sumDeltaAngularAxis / radian; - RotationMatrix( axis, radian, targetMem ); - } - else targetMem = ::LinearAlgebra::Matrix4x4::identity; - + ::LinearAlgebra::Matrix4x4 & OrientationMatrix( const ::LinearAlgebra::Vector3 &normalizedAxis, const ScalarType &deltaRadian, const ::LinearAlgebra::Vector3 &sumTranslation, ::LinearAlgebra::Matrix4x4 &targetMem = ::LinearAlgebra::Matrix4x4() ) + { /** @todo TODO: not tested */ + RotationMatrix( normalizedAxis, deltaRadian, targetMem ); targetMem.v[3].xyz = sumTranslation; return targetMem; } template - ::LinearAlgebra::Matrix4x4 & OrientationMatrix( const ::LinearAlgebra::Vector3 &sumDeltaAngularAxis, const ::LinearAlgebra::Vector3 &sumTranslation, const ::LinearAlgebra::Vector3 ¢erOfRotation, ::LinearAlgebra::Matrix4x4 &targetMem = ::LinearAlgebra::Matrix4x4() ) - { /// TODO: not tested + ::LinearAlgebra::Matrix4x4 & OrientationMatrix( const ::LinearAlgebra::Vector3 &sumDeltaAngularAxis, const ::LinearAlgebra::Vector3 &sumTranslation, ::LinearAlgebra::Matrix4x4 &targetMem = ::LinearAlgebra::Matrix4x4() ) + { /** @todo TODO: not tested */ ScalarType radian = sumDeltaAngularAxis.Dot( sumDeltaAngularAxis ); if( radian > 0 ) { radian = ::std::sqrt( radian ); - ::LinearAlgebra::Vector3 axis = sumDeltaAngularAxis / radian; - RotationMatrix( axis, radian, targetMem ); + return OrientationMatrix( sumDeltaAngularAxis / radian, radian, targetMem ); + } + else + { + targetMem = ::LinearAlgebra::Matrix4x4::identity; + targetMem.v[3].xyz = sumTranslation; + return targetMem; + } + } + + template + ::LinearAlgebra::Matrix4x4 & OrientationMatrix( const ::LinearAlgebra::Vector3 &sumDeltaAngularAxis, const ::LinearAlgebra::Vector3 &sumTranslation, const ::LinearAlgebra::Vector3 ¢erOfRotation, ::LinearAlgebra::Matrix4x4 &targetMem = ::LinearAlgebra::Matrix4x4() ) + { /** @todo TODO: not tested */ + ScalarType radian = sumDeltaAngularAxis.Dot( sumDeltaAngularAxis ); + if( radian > 0 ) + { + radian = ::std::sqrt( radian ); + RotationMatrix( sumDeltaAngularAxis / radian, radian, targetMem ); } else targetMem = ::LinearAlgebra::Matrix4x4::identity; @@ -337,7 +345,7 @@ namespace LinearAlgebra3D */ template ::LinearAlgebra::Matrix4x4 & ProjectionMatrix_Orthographic( const ScalarType &width, const ScalarType &height, const ScalarType &nearClip, const ScalarType &farClip, ::LinearAlgebra::Matrix4x4 &targetMem = ::LinearAlgebra::Matrix4x4() ) - { /// TODO: not tested + { /** @todo TODO: not tested */ ScalarType c = 1 / (nearClip - farClip); return targetMem = ::LinearAlgebra::Matrix4x4( 2/width, 0, 0, 0, 0, 2/height, 0, 0, @@ -354,7 +362,7 @@ namespace LinearAlgebra3D */ template ::LinearAlgebra::Matrix4x4 & ProjectionMatrix_Perspective( const ScalarType &vertFoV, const ScalarType &aspect, const ScalarType &nearClip, const ScalarType &farClip, ::LinearAlgebra::Matrix4x4 &targetMem = ::LinearAlgebra::Matrix4x4() ) - { /// TODO: not tested + { /** @todo TODO: not tested */ ScalarType fov = 1 / ::std::tan( vertFoV * 0.5f ), dDepth = farClip / (farClip - nearClip); return targetMem = ::LinearAlgebra::Matrix4x4( fov / aspect, 0, 0, 0, diff --git a/OysterMath/OysterMath.cpp b/OysterMath/OysterMath.cpp index fee94545..4ec6da58 100644 --- a/OysterMath/OysterMath.cpp +++ b/OysterMath/OysterMath.cpp @@ -63,6 +63,9 @@ namespace Oyster { namespace Math3D Float4x4 & RotationMatrix( const Float &radian, const Float3 &normalizedAxis, Float4x4 &targetMem ) { return ::LinearAlgebra3D::RotationMatrix( normalizedAxis, radian, targetMem ); } + Float4x4 & OrientationMatrix( const Float3 &normalizedAxis, const Float & deltaRadian, const Float3 &sumTranslation, Float4x4 &targetMem ) + { return ::LinearAlgebra3D::OrientationMatrix( normalizedAxis, deltaRadian, sumTranslation, targetMem ); } + Float4x4 & OrientationMatrix( const Float3 &sumDeltaAngularAxis, const Float3 &sumTranslation, Float4x4 &targetMem ) { return ::LinearAlgebra3D::OrientationMatrix( sumDeltaAngularAxis, sumTranslation, targetMem ); } diff --git a/OysterMath/OysterMath.h b/OysterMath/OysterMath.h index 899ab033..c66f44cc 100644 --- a/OysterMath/OysterMath.h +++ b/OysterMath/OysterMath.h @@ -26,6 +26,8 @@ namespace Oyster { namespace Math /// Oyster's native math library typedef Float3 Vector3; // by popular demand typedef Float4 Vector4; // by popular demand + const Float pi = 3.1415926535897932384626433832795f; + /// Function Highly recommended to check at start, just in case current version is using a feature that might be available. /// @todo TODO: create a template UniquePointer to use here bool IsSupported(); @@ -146,48 +148,63 @@ namespace Oyster { namespace Math3D /// Oyster's native math library specialized /// Please make sure normalizedAxis is normalized. Float4x4 & RotationMatrix( const Float &radian, const Float3 &normalizedAxis, Float4x4 &targetMem = Float4x4() ); - /** Sets and returns targetMem as an orientation Matrix - * @param targetMem: is set to a rigibody matrix that rotate counterclockwise and then translates. + /******************************************************************* + * Sets and returns targetMem as an orientation Matrix + * @param normalizedAxis: The normalized vector parallell with the rotationAxis. + * @param deltaRadian: The rotation angle. + * @param sumTranslation: sum of all the translation vectors. + * @param targetMem: is set to a rigibody matrix that rotate counterclockwise and then translates. + * @return targetMem + * @todo TODO: not tested + *******************************************************************/ + Float4x4 & OrientationMatrix( const Float3 &normalizedAxis, const Float & deltaRadian, const Float3 &sumTranslation, Float4x4 &targetMem = Float4x4() ); + + /******************************************************************* + * Sets and returns targetMem as an orientation Matrix * @param sumDeltaAngularAxis: sum of all ( (1/I) * ( L x D ) )-vectorproducts. There I is known as "moment of inertia", L as "angular momentum vector" and D the "lever vector". * @param sumTranslation: sum of all the translation vectors. + * @param targetMem: is set to a rigibody matrix that rotate counterclockwise and then translates. * @return targetMem - @todo TODO: not tested - */ + * @todo TODO: not tested + *******************************************************************/ Float4x4 & OrientationMatrix( const Float3 &sumDeltaAngularAxis, const Float3 &sumTranslation, Float4x4 &targetMem = Float4x4() ); - /** Sets and returns targetMem as an orientation Matrix - * @param targetMem: is set to a rigibody matrix that revolve/rotate counterclockwise around centerOfMass and then translates. + /******************************************************************* + * Sets and returns targetMem as an orientation Matrix * @param sumDeltaAngularAxis: sum of all ( (1/I) * ( L x D ) )-vectorproducts. There I is known as "moment of inertia", L as "angular momentum vector" and D the "lever vector". * @param sumTranslation: sum of all the translation vectors. * @param centerOfMass: the point the particles is to revolve around, prior to translation. Default set to null vector aka origo. + * @param targetMem: is set to a rigibody matrix that revolve/rotate counterclockwise around centerOfMass and then translates. * @return targetMem - @todo TODO: not tested - */ + * @todo TODO: not tested + *******************************************************************/ Float4x4 & OrientationMatrix( const Float3 &sumDeltaAngularAxis, const Float3 &sumTranslation, const Float3 ¢erOfMass, Float4x4 &targetMem = Float4x4() ); /// If orientationMatrix is assumed to be by all definitions a rigid orientation matrix aka rigid body matrix. Then this is a much faster inverse method. Float4x4 & InverseOrientationMatrix( const Float4x4 &orientationMatrix, Float4x4 &targetMem = Float4x4() ); - /** Creates an orthographic projection matrix designed for DirectX enviroment. - * @param targetMem; is set to an orthographic projection matrix. + /******************************************************************* + * Creates an orthographic projection matrix designed for DirectX enviroment. * @param width; of the projection sample volume. * @param height; of the projection sample volume. * @param nearClip: Distance to the nearPlane. * @param farClip: Distance to the farPlane. + * @param targetMem; is set to an orthographic projection matrix. * @return targetMem - @todo TODO: not tested - */ + * @todo TODO: not tested + *******************************************************************/ Float4x4 & ProjectionMatrix_Orthographic( const Float &width, const Float &height, const Float &nearClip = ::std::numeric_limits::epsilon(), const Float &farClip = ::std::numeric_limits::max(), Float4x4 &targetMem = Float4x4() ); - /** Creates a perspective projection matrix designed for DirectX enviroment. - * @param targetMem; is set to a perspective transform matrix. + /******************************************************************* + * Creates a perspective projection matrix designed for DirectX enviroment. * @param vertFoV; is the vertical field of vision in radians. (lookup FoV Hor+ ) * @param aspect; is the screenratio width/height (example 16/9 or 16/10 ) * @param nearClip: Distance to the nearPlane * @param farClip: Distance to the farPlane + * @param targetMem; is set to a perspective transform matrix. * @return targetMem - @todo TODO: not tested - */ + * @todo TODO: not tested + *******************************************************************/ Float4x4 & ProjectionMatrix_Perspective( const Float &verticalFoV, const Float &aspectRatio, const Float &nearClip = ::std::numeric_limits::epsilon(), const Float &farClip = ::std::numeric_limits::max(), Float4x4 &targetMem = Float4x4() ); /// returns the component vector of vector that is parallell with axis diff --git a/OysterPhysics3D/Collision/Box.cpp b/OysterPhysics3D/Collision/Box.cpp index 76c425a1..9c27ed63 100644 --- a/OysterPhysics3D/Collision/Box.cpp +++ b/OysterPhysics3D/Collision/Box.cpp @@ -3,7 +3,7 @@ ///////////////////////////////////////////////////////////////////// #include "Box.h" -#include "OysterCollision.h" +#include "..\OysterCollision3D.h" using namespace ::Oyster::Collision3D; using namespace ::Oyster::Math3D; diff --git a/OysterPhysics3D/Collision/BoxAxisAligned.cpp b/OysterPhysics3D/Collision/BoxAxisAligned.cpp index ee46ee88..ae5ebafe 100644 --- a/OysterPhysics3D/Collision/BoxAxisAligned.cpp +++ b/OysterPhysics3D/Collision/BoxAxisAligned.cpp @@ -3,7 +3,7 @@ ///////////////////////////////////////////////////////////////////// #include "BoxAxisAligned.h" -#include "OysterCollision.h" +#include "..\OysterCollision3D.h" using namespace ::Oyster::Collision3D; using namespace ::Oyster::Math3D; diff --git a/OysterPhysics3D/Collision/Line.cpp b/OysterPhysics3D/Collision/Line.cpp index bda0e715..989fb55b 100644 --- a/OysterPhysics3D/Collision/Line.cpp +++ b/OysterPhysics3D/Collision/Line.cpp @@ -3,7 +3,7 @@ ///////////////////////////////////////////////////////////////////// #include "Line.h" -#include "OysterCollision.h" +#include "..\OysterCollision3D.h" using namespace ::Oyster::Collision3D; using namespace ::Oyster::Math3D; diff --git a/OysterPhysics3D/Collision/OysterCollision.cpp b/OysterPhysics3D/Collision/OysterCollision3D.cpp similarity index 99% rename from OysterPhysics3D/Collision/OysterCollision.cpp rename to OysterPhysics3D/Collision/OysterCollision3D.cpp index a96a418e..d5295e33 100644 --- a/OysterPhysics3D/Collision/OysterCollision.cpp +++ b/OysterPhysics3D/Collision/OysterCollision3D.cpp @@ -2,7 +2,7 @@ // Created by Dan Andersson 2013 ///////////////////////////////////////////////////////////////////// -#include "OysterCollision.h" +#include "..\OysterCollision3D.h" #include "Utilities.h" #include diff --git a/OysterPhysics3D/Collision/Plane.cpp b/OysterPhysics3D/Collision/Plane.cpp index 619fdc99..374ad605 100644 --- a/OysterPhysics3D/Collision/Plane.cpp +++ b/OysterPhysics3D/Collision/Plane.cpp @@ -3,7 +3,7 @@ ///////////////////////////////////////////////////////////////////// #include "Plane.h" -#include "OysterCollision.h" +#include "..\OysterCollision3D.h" using namespace ::Oyster::Collision3D; using namespace ::Oyster::Math; diff --git a/OysterPhysics3D/Collision/Point.cpp b/OysterPhysics3D/Collision/Point.cpp index d951b2a5..3673dc2c 100644 --- a/OysterPhysics3D/Collision/Point.cpp +++ b/OysterPhysics3D/Collision/Point.cpp @@ -3,7 +3,7 @@ ///////////////////////////////////////////////////////////////////// #include "Point.h" -#include "OysterCollision.h" +#include "..\OysterCollision3D.h" using namespace ::Oyster::Collision3D; using namespace ::Oyster::Math3D; diff --git a/OysterPhysics3D/Collision/Ray.cpp b/OysterPhysics3D/Collision/Ray.cpp index 96d9911a..99c8094a 100644 --- a/OysterPhysics3D/Collision/Ray.cpp +++ b/OysterPhysics3D/Collision/Ray.cpp @@ -3,7 +3,7 @@ ///////////////////////////////////////////////////////////////////// #include "Ray.h" -#include "OysterCollision.h" +#include "..\OysterCollision3D.h" using namespace ::Oyster::Collision3D; using namespace ::Oyster::Math3D; diff --git a/OysterPhysics3D/Collision/Sphere.cpp b/OysterPhysics3D/Collision/Sphere.cpp index 6b9b706e..2250aa04 100644 --- a/OysterPhysics3D/Collision/Sphere.cpp +++ b/OysterPhysics3D/Collision/Sphere.cpp @@ -1,5 +1,5 @@ #include "Sphere.h" -#include "OysterCollision.h" +#include "..\OysterCollision3D.h" using namespace ::Oyster::Collision3D; using namespace ::Oyster::Math; diff --git a/OysterPhysics3D/Collision/Universe.cpp b/OysterPhysics3D/Collision/Universe.cpp index c25c0454..4a8bcf94 100644 --- a/OysterPhysics3D/Collision/Universe.cpp +++ b/OysterPhysics3D/Collision/Universe.cpp @@ -1,5 +1,5 @@ #include "Universe.h" -#include "OysterCollision.h" +#include "..\OysterCollision3D.h" using namespace ::Oyster::Collision3D; using namespace ::Utility::Memory; @@ -29,6 +29,6 @@ bool Universe::Intersects( const ICollideable *target ) const return true; } -bool Sphere::Contains( const ICollideable *target ) const +bool Universe::Contains( const ICollideable *target ) const { return true; } // universe contains everything diff --git a/OysterPhysics3D/Collision/OysterCollision.h b/OysterPhysics3D/OysterCollision3D.h similarity index 93% rename from OysterPhysics3D/Collision/OysterCollision.h rename to OysterPhysics3D/OysterCollision3D.h index 24d6a568..405d3013 100644 --- a/OysterPhysics3D/Collision/OysterCollision.h +++ b/OysterPhysics3D/OysterCollision3D.h @@ -6,17 +6,17 @@ #ifndef OYSTER_COLLISION_3D_UTILITY_H #define OYSTER_COLLISION_3D_UTILITY_H -#include "ICollideable.h" -#include "Universe.h" -#include "Point.h" -#include "Ray.h" -#include "Sphere.h" -#include "Plane.h" -//#include "Triangle.h" -#include "BoxAxisAligned.h" -#include "Box.h" -#include "Frustrum.h" -#include "Line.h" +#include "Collision\ICollideable.h" +#include "Collision\Universe.h" +#include "Collision\Point.h" +#include "Collision\Ray.h" +#include "Collision\Sphere.h" +#include "Collision\Plane.h" +//#include "Collision\Triangle.h" +#include "Collision\BoxAxisAligned.h" +#include "Collision\Box.h" +#include "Collision\Frustrum.h" +#include "Collision\Line.h" namespace Oyster { namespace Collision3D { namespace Utility { diff --git a/OysterPhysics3D/OysterPhysics3D.h b/OysterPhysics3D/OysterPhysics3D.h new file mode 100644 index 00000000..6b7ec136 --- /dev/null +++ b/OysterPhysics3D/OysterPhysics3D.h @@ -0,0 +1,103 @@ +///////////////////////////////////////////////////////////////////// +// Created by Dan Andersson 2013 +///////////////////////////////////////////////////////////////////// + +#ifndef OYSTER_PHYSICS_3D_H +#define OYSTER_PHYSICS_3D_H + +#include "OysterMath.h" + +namespace Oyster { namespace Physics3D +{ /// Library of 3D physics related components, alghorithms and formulas + namespace Formula + { /// Library of 3D physics related formulas + + /****************************************************************** + * Returns the linear kinetic energy of a mass in motion. + * @todo TODO: improve doc + ******************************************************************/ + inline ::Oyster::Math::Float LinearKineticEnergy( const ::Oyster::Math::Float &mass, const ::Oyster::Math::Float3 &linearVelocity ) + { return (0.5f * mass) * linearVelocity.Dot( linearVelocity ); } + + /****************************************************************** + * Returns the angular kinetic energy of a mass in rotation. + * @todo TODO: improve doc + ******************************************************************/ + inline ::Oyster::Math::Float AngularKineticEnergy( const ::Oyster::Math::Float &momentOfInertia, const ::Oyster::Math::Float3 &angularVelocity ) + { return (0.5f * momentOfInertia) * angularVelocity.Dot( angularVelocity ); } + + /****************************************************************** + * Returns the linear momentum of a mass in motion. + * @todo TODO: improve doc + ******************************************************************/ + inline ::Oyster::Math::Float3 LinearMomentum( const ::Oyster::Math::Float &mass, const ::Oyster::Math::Float3 &linearVelocity ) + { return mass * linearVelocity; } + + /****************************************************************** + * Returns the linear velocity of a mass with momentum. + * @todo TODO: improve doc + ******************************************************************/ + inline ::Oyster::Math::Float3 LinearVelocity( const ::Oyster::Math::Float &mass, const ::Oyster::Math::Float3 &linearMomentum ) + { return linearMomentum / mass; } + + /****************************************************************** + * Returns the local angular momentum of a mass in rotation. + * @todo TODO: improve doc + ******************************************************************/ + inline ::Oyster::Math::Float3 AngularMomentum( const ::Oyster::Math::Float &momentOfInertia, const ::Oyster::Math::Float3 &angularVelocity ) + { return momentOfInertia * angularVelocity; } + + /****************************************************************** + * Returns the local tangential momentum at localPos, of a mass in rotation. + * @todo TODO: improve doc + ******************************************************************/ + inline ::Oyster::Math::Float3 & TangentialLinearMomentum( const ::Oyster::Math::Float &localAngularMomentum, const ::Oyster::Math::Float3 &localPosition, ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) + { return targetMem = localAngularMomentum * ::Oyster::Math::Float3( -localPosition.y, localPosition.x ); } + + /****************************************************************** + * Returns the local tangential momentum at localPos, of a mass in rotation. + * @todo TODO: improve doc + ******************************************************************/ + inline ::Oyster::Math::Float3 & TangentialLinearMomentum( const ::Oyster::Math::Float &momentOfInertia, const ::Oyster::Math::Float3 &angularVelocity, const ::Oyster::Math::Float3 &localPosition, ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) + { return targetMem = AngularMomentum( momentOfInertia, angularVelocity ).Cross( localPosition ); } + + /****************************************************************** + * Returns the local angular velocity of a mass in rotation. + * @todo TODO: improve doc + ******************************************************************/ + inline ::Oyster::Math::Float3 AngularVelocity( const ::Oyster::Math::Float &momentOfInertia, const ::Oyster::Math::Float3 &angularMomentum ) + { return angularMomentum / momentOfInertia; } + + /****************************************************************** + * Returns the local tangential velocity at localPos, of a mass in rotation. + * @todo TODO: improve doc + ******************************************************************/ + inline ::Oyster::Math::Float3 & TangentialLinearVelocity( const ::Oyster::Math::Float3 &angularVelocity, const ::Oyster::Math::Float3 &localPosition, ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) + { return targetMem = angularVelocity.Cross( localPosition ); } + + /****************************************************************** + * + * @todo TODO: improve doc + ******************************************************************/ + inline ::Oyster::Math::Float3 LinearImpulseAcceleration( ::Oyster::Math::Float mass, const ::Oyster::Math::Float3 &impulseForce ) + { return impulseForce / mass; } + + /****************************************************************** + * + * @todo TODO: improve doc + ******************************************************************/ + inline ::Oyster::Math::Float3 ImpulseForce( ::Oyster::Math::Float mass, const ::Oyster::Math::Float3 &linearImpulseAcceleration ) + { return linearImpulseAcceleration * mass; } + + namespace MomentOfInertia + { /// Library of Formulas to calculate moment of inerta for simple shapes + /** @todo TODO: add MomentOfInertia formulas */ + } + } +} } + +#include "Particle.h" +#include "RigidBody.h" +#include "Spring.h" + +#endif \ No newline at end of file diff --git a/OysterPhysics3D/OysterPhysics3D.vcxproj b/OysterPhysics3D/OysterPhysics3D.vcxproj index 3ca7593b..2cb566d1 100644 --- a/OysterPhysics3D/OysterPhysics3D.vcxproj +++ b/OysterPhysics3D/OysterPhysics3D.vcxproj @@ -140,7 +140,8 @@ - + + @@ -148,11 +149,14 @@ + + + + - @@ -161,6 +165,12 @@ + + + + + + diff --git a/OysterPhysics3D/OysterPhysics3D.vcxproj.filters b/OysterPhysics3D/OysterPhysics3D.vcxproj.filters index 4287c2b6..b4f1cf5c 100644 --- a/OysterPhysics3D/OysterPhysics3D.vcxproj.filters +++ b/OysterPhysics3D/OysterPhysics3D.vcxproj.filters @@ -54,7 +54,22 @@ Source Files\Collision - + + Source Files\Collision + + + Source Files\Physics + + + Source Files\Physics + + + Source Files\Physics + + + Source Files\Physics + + Source Files\Collision @@ -89,8 +104,23 @@ Header Files\Collision - - Header Files\Collision + + Header Files\Physics + + + Header Files\Physics + + + Header Files\Physics + + + Header Files\Physics + + + Header Files + + + Header Files \ No newline at end of file diff --git a/OysterPhysics3D/Physics/FluidDrag.cpp b/OysterPhysics3D/Physics/FluidDrag.cpp new file mode 100644 index 00000000..44919882 --- /dev/null +++ b/OysterPhysics3D/Physics/FluidDrag.cpp @@ -0,0 +1,26 @@ +///////////////////////////////////////////////////////////////////// +// Created by Dan Andersson 2013 +///////////////////////////////////////////////////////////////////// + +#include "FluidDrag.h" + +using namespace ::Oyster::Physics3D; +using namespace ::Oyster::Math3D; + +FluidDrag::FluidDrag( Float _density, Float _dragCoeff ) + : density(_density), dragCoeff(_dragCoeff) {} + +FluidDrag & FluidDrag::operator = ( const FluidDrag &fluid ) +{ + this->density = fluid.density; + this->dragCoeff = fluid.dragCoeff; + return *this; +} +void FluidDrag::SetDensity( ::Oyster::Math::Float d ) +{ this->density = d; } + +void FluidDrag::SetDragCoefficient( ::Oyster::Math::Float c ) +{ this->dragCoeff = c; } + +Float3 & FluidDrag::GetDragForce( const Float3 &deltaVelocity, Float crossSectionalArea, Float3 &targetMem ) const +{ return targetMem = (0.5f * this->density * this->dragCoeff * crossSectionalArea * deltaVelocity.GetMagnitude() ) * deltaVelocity; } \ No newline at end of file diff --git a/OysterPhysics3D/Physics/FluidDrag.h b/OysterPhysics3D/Physics/FluidDrag.h new file mode 100644 index 00000000..70cfdf66 --- /dev/null +++ b/OysterPhysics3D/Physics/FluidDrag.h @@ -0,0 +1,41 @@ +///////////////////////////////////////////////////////////////////// +// Created by Dan Andersson 2013 +///////////////////////////////////////////////////////////////////// + +#ifndef OYSTER_PHYSICS_3D_FLUID_DRAG_H +#define OYSTER_PHYSICS_3D_FLUID_DRAG_H + +#include "OysterMath.h" +#include "..\OysterPhysics3D.h" + +namespace Oyster { namespace Physics3D +{ + struct FluidDrag + { /// A struct representing fluids* interaction with objects. + /// *including gas + public: + FluidDrag( ::Oyster::Math::Float density = 1.0f, ::Oyster::Math::Float coeff = 1.0f ); + + FluidDrag & operator = ( const FluidDrag &fluid ); + + void SetDensity( ::Oyster::Math::Float d ); + void SetDragCoefficient( ::Oyster::Math::Float c ); + + /****************************************************************** + * Returns the resistance force when object is moving through fluid. + * @param deltaVelocity: (fluid's velocity) - (the object's velocity) + * @param crossSectionalArea: The max area of crosssectional surfaces orthogonal to deltaVelocity + * @param targetMem: Allocated memory where result is written. default: temporary allocation + * @return targetMem + ******************************************************************/ + ::Oyster::Math::Float3 & GetDragForce( const ::Oyster::Math::Float3 &deltaVelocity, ::Oyster::Math::Float crossSectionalArea, ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const; + + /** @todo TODO: Add GetMagnusForce ? */ + + private: + ::Oyster::Math::Float density, /// density of the fluid (kg/m^3) + dragCoeff; + }; +} } + +#endif \ No newline at end of file diff --git a/OysterPhysics3D/Physics/Particle.cpp b/OysterPhysics3D/Physics/Particle.cpp new file mode 100644 index 00000000..830e13b5 --- /dev/null +++ b/OysterPhysics3D/Physics/Particle.cpp @@ -0,0 +1,169 @@ +///////////////////////////////////////////////////////////////////// +// Created by Dan Andersson 2013 +///////////////////////////////////////////////////////////////////// + +#include "Particle.h" +#include "Utilities.h" + +using namespace ::Oyster::Math3D; +using namespace ::Oyster::Collision3D; +using namespace ::Oyster::Physics3D; + +Particle::Particle( const Sphere &s, Float m ) + : sphere(s), linearMomentum(Float3::null), impulseForceSum(Float3::null) +{ + if( m == 0.0f ) + { + this->mass = ::Utility::Value::numeric_limits::epsilon(); + } + else + { + this->mass = m; + } +} + +Particle & Particle::operator = ( const Particle &particle ) +{ + this->sphere = particle.sphere; + this->linearMomentum = particle.linearMomentum; + this->impulseForceSum = particle.impulseForceSum; + this->mass = particle.mass; + return *this; +} + +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->linearMomentum += Formula::LinearMomentum( this->mass, this->impulseForceSum ); + this->impulseForceSum = Float3::null; + + /* Fun notation + the operations above can be written like this + p = p0 + dt*( v0 + dt*(F/m)/2 ) + = p0 + dt*v0 + dt^2*(F/m)/2 + there: + * dt = deltaTime + * p = this->sphere.position at the end of deltaTime + * p0 = this->sphere.position at beginning of deltaTime + * v0 = this->velocity at beginning of deltaTime + * m = this->mass + * F = this->sumForces pushing during deltaTime + + It is the law of motion with constant acceleration. + */ +} + +void Particle::ApplyImpulseForce( const Float3 &f ) +{ + this->impulseForceSum += f; +} + +void Particle::ApplyLinearImpulseAcceleration( const Float3 &a ) +{ + this->impulseForceSum += this->mass * a; +} + +Float3 & Particle::AccessCenter() +{ + return this->sphere.center; +} + +const Float3 & Particle::AccessCenter() const +{ + return this->sphere.center; +} + +Float & Particle::AccessRadius() +{ + return this->sphere.radius; +} + +const Float & Particle::AccessRadius() const +{ + return this->sphere.radius; +} + +const Float & Particle::GetMass() const +{ + return this->mass; +} + +const Float3 & Particle::GetCenter() const +{ + return this->sphere.center; +} + +const Float & Particle::GetRadius() const +{ + return this->sphere.radius; +} + +const Float3 & Particle::GetImpulseForce() const +{ + return this->impulseForceSum; +} + +const Float3 & Particle::GetLinearMomentum() const +{ + return this->linearMomentum; +} + +Float3 Particle::GetLinearImpulseAcceleration() const +{ + return Formula::LinearImpulseAcceleration( this->mass, this->impulseForceSum ); +} + +Float3 Particle::GetLinearVelocity() const +{ + return Formula::LinearVelocity( this->mass, this->linearMomentum ); +} + +void Particle::SetMass_KeepVelocity( Float m ) +{ + Float3 velocity = Formula::LinearVelocity( this->mass, this->linearMomentum ); + this->SetMass_KeepMomentum( m ); + this->linearMomentum = Formula::LinearMomentum( this->mass, velocity ); +} + +void Particle::SetMass_KeepMomentum( Float m ) +{ + if( m == 0.0f ) + { + this->mass = ::Utility::Value::numeric_limits::epsilon(); + } + else + { + this->mass = m; + } +} + +void Particle::SetCenter( const Float3 &p ) +{ + this->sphere.center = p; +} + +void Particle::SetRadius( Float r ) +{ + this->sphere.radius = r; +} + +void Particle::SetImpulseForce( const Float3 &f ) +{ + this->impulseForceSum = f; +} + +void Particle::SetLinearMomentum( const Float3 &g ) +{ + this->linearMomentum = g; +} + +void Particle::SetLinearImpulseAcceleration( const Float3 &a ) +{ + this->impulseForceSum = Formula::ImpulseForce( this->mass, a ); +} + +void Particle::SetLinearVelocity( const Float3 &v ) +{ + this->linearMomentum = Formula::LinearMomentum( this->mass, v ); +} diff --git a/OysterPhysics3D/Physics/Particle.h b/OysterPhysics3D/Physics/Particle.h new file mode 100644 index 00000000..4c619749 --- /dev/null +++ b/OysterPhysics3D/Physics/Particle.h @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////// +// Created by Dan Andersson 2013 +///////////////////////////////////////////////////////////////////// + +#ifndef OYSTER_PHYSICS_3D_PARTICLE_H +#define OYSTER_PHYSICS_3D_PARTICLE_H + +#include "OysterMath.h" +#include "..\OysterCollision3D.h" +#include "..\OysterPhysics3D.h" + +namespace Oyster { namespace Physics3D +{ + struct Particle + { /// A struct of a simple particle. + public: + ::Oyster::Collision3D::Sphere sphere; + ::Oyster::Math::Float3 linearMomentum, /// The linear momentum G (kg*m/s). + impulseForceSum; /// The impulse force F (N) that will be consumed each update. + + Particle( const ::Oyster::Collision3D::Sphere &sphere = ::Oyster::Collision3D::Sphere(), ::Oyster::Math::Float mass = 1.0f ); + + Particle & operator = ( const Particle &particle ); + + void Update_LeapFrog( ::Oyster::Math::Float deltaTime ); + void ApplyImpulseForce( const ::Oyster::Math::Float3 &f ); + void ApplyLinearImpulseAcceleration( const ::Oyster::Math::Float3 &a ); + + // ACCESS METHODS ///////////////////////////// + + ::Oyster::Math::Float3 & AccessCenter(); + const ::Oyster::Math::Float3 & AccessCenter() const; + ::Oyster::Math::Float & AccessRadius(); + const ::Oyster::Math::Float & AccessRadius() const; + + // GET METHODS //////////////////////////////// + + const ::Oyster::Math::Float & GetMass() const; + const ::Oyster::Math::Float3 & GetCenter() const; + const ::Oyster::Math::Float & GetRadius() const; + + const ::Oyster::Math::Float3 & GetImpulseForce() const; + const ::Oyster::Math::Float3 & GetLinearMomentum() const; + ::Oyster::Math::Float3 GetLinearImpulseAcceleration() const; + ::Oyster::Math::Float3 GetLinearVelocity() const; + + // SET METHODS //////////////////////////////// + + void SetMass_KeepVelocity( ::Oyster::Math::Float m ); + void SetMass_KeepMomentum( ::Oyster::Math::Float m ); + void SetCenter( const ::Oyster::Math::Float3 &p ); + void SetRadius( ::Oyster::Math::Float r ); + + void SetImpulseForce( const ::Oyster::Math::Float3 &f ); + void SetLinearMomentum( const ::Oyster::Math::Float3 &g ); + void SetLinearImpulseAcceleration( const ::Oyster::Math::Float3 &a ); + void SetLinearVelocity( const ::Oyster::Math::Float3 &v ); + + private: + ::Oyster::Math::Float mass; /// m (kg) + }; +} } + +#endif \ No newline at end of file diff --git a/OysterPhysics3D/Physics/Spring.cpp b/OysterPhysics3D/Physics/Spring.cpp new file mode 100644 index 00000000..c5a9bc9e --- /dev/null +++ b/OysterPhysics3D/Physics/Spring.cpp @@ -0,0 +1,54 @@ +///////////////////////////////////////////////////////////////////// +// Created by Dan Andersson 2013 +///////////////////////////////////////////////////////////////////// + +#include "Spring.h" + +using namespace ::Oyster::Math3D; +using namespace ::Oyster::Physics3D; + +Spring::Spring( Float r, Float s, Float d ) + : restingLength(r), springCoefficiant(s), dampeningCoefficiant(d) {} + +Spring & Spring::operator = ( const Spring &spring ) +{ + this->restingLength = spring.restingLength; + this->springCoefficiant = spring.springCoefficiant; + this->dampeningCoefficiant = spring.dampeningCoefficiant; + return *this; +} + +Float3 & Spring::GetSpringForce( const Float3 &deltaPosition, Float3 &targetMem ) const +{ + Float length = deltaPosition.Dot( deltaPosition ); + if( length != 0.0f ) + { + length = sqrt( length ); + return targetMem = deltaPosition * ( this->springCoefficiant * (length - this->restingLength) / length ); + } + else return targetMem = Float3::null; +} + +Float3 & Spring::GetDampeningForce( const Float3 &deltaPosition, const Float3 &deltaLinearVelocity, Float3 &targetMem ) const +{ + Float projectedSpeed = deltaPosition.Dot(deltaPosition); + if( projectedSpeed != 0.0f ) + { + projectedSpeed = deltaLinearVelocity.Dot(deltaPosition) / projectedSpeed; + return targetMem = deltaPosition * ( this->dampeningCoefficiant * projectedSpeed ); + } + else return targetMem = Float3::null; +} + +Float3 & Spring::GetSpringDampeningForce( const Float3 &deltaPosition, const Float3 &deltaLinearVelocity, Float3 &targetMem) const +{ + Float length = deltaPosition.Dot( deltaPosition ); + if( length != 0.0f ) + { // f = sprCoeff * (|dP| - rL) + (dV dot dP) * (dampCoeff / |dP|) * (dP / |dP|) + length = sqrt( length ); + Float force = this->springCoefficiant * (length - this->restingLength); + force += deltaLinearVelocity.Dot(deltaPosition) * (this->dampeningCoefficiant / length); + return targetMem = deltaPosition * (force / length); + } + else return targetMem = Float3::null; +} \ No newline at end of file diff --git a/OysterPhysics3D/Physics/Spring.h b/OysterPhysics3D/Physics/Spring.h new file mode 100644 index 00000000..a74925b7 --- /dev/null +++ b/OysterPhysics3D/Physics/Spring.h @@ -0,0 +1,29 @@ +///////////////////////////////////////////////////////////////////// +// Created by Dan Andersson 2013 +///////////////////////////////////////////////////////////////////// + +#ifndef OYSTER_PHYSICS_3D_SPRING_H +#define OYSTER_PHYSICS_3D_SPRING_H + +#include "OysterMath.h" + +namespace Oyster { namespace Physics3D +{ + struct Spring + { /// A struct of a spring able to generate push and pull forces + public: + ::Oyster::Math::Float restingLength, /// the resting length of the spring in meters + springCoefficiant, /// kg/s^2 + dampeningCoefficiant; + + Spring( ::Oyster::Math::Float restingLength = 1.0f, ::Oyster::Math::Float springCoefficiant = 1.0f, ::Oyster::Math::Float dampingCoefficiant = 0.0f ); + + Spring & operator = ( const Spring &spring ); + + ::Oyster::Math::Float3 & GetSpringForce( const ::Oyster::Math::Float3 &deltaPosition, ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const; + ::Oyster::Math::Float3 & GetDampeningForce( const ::Oyster::Math::Float3 &deltaPosition, const ::Oyster::Math::Float3 &deltaLinearVelocity, ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const; + ::Oyster::Math::Float3 & GetSpringDampeningForce( const ::Oyster::Math::Float3 &deltaPosition, const ::Oyster::Math::Float3 &deltaLinearVelocity, ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const; + }; +} } + +#endif \ No newline at end of file