#ifndef PHYSICS_API_H #define PHYSICS_API_H #include "OysterCollision3D.h" #include "OysterMath.h" #if defined PHYSICS_DLL_EXPORT #define PHYSICS_DLL_USAGE __declspec(dllexport) #else #define PHYSICS_DLL_USAGE __declspec(dllimport) #endif namespace Oyster { namespace Physics { class API; class ICustomBody; namespace Struct { struct SimpleBodyDescription; struct SphericalBodyDescription; struct CustomBodyState; struct Gravity; } enum UpdateState { UpdateState_resting, UpdateState_altered }; namespace Constant { const float gravity_constant = (const float)6.67284e-11; //!< The _big_G_! ( N(m/kg)^2 ) Used in real gravityforcefields. const float epsilon = (const float)1.0e-3; } class PHYSICS_DLL_USAGE API { public: typedef Struct::SimpleBodyDescription SimpleBodyDescription; typedef Struct::SphericalBodyDescription SphericalBodyDescription; typedef Struct::Gravity Gravity; typedef void (*EventAction_Destruction)( ::Utility::DynamicMemory::UniquePointer proto ); typedef void (*EventAction_ApplyEffect)(ICustomBody* collidedBody, void* args); /** Gets the Physics instance. */ static API & Instance(); /******************************************************** * Clears all content and reset Engine assetts such as buffers. * @param numObjects: The predicted max number of active objects. * @param numGravityWells: The predicted max number of active gravity wells. * @param worldSize: The size of acceptable physics space. ********************************************************/ virtual void Init() = 0; /******************************************************** * An object in limbo state will be ignored during the physics frame Update. * @param objRef: A pointer to the ICustomBody representing a physical object. * @return true if object is in limbo state. ********************************************************/ virtual bool IsInLimbo( const ICustomBody* objRef ) = 0; /******************************************************** * An object in limbo state will be ignored during the physics frame Update. * This will put an object in Limbo state. * @param objRef: A pointer to the ICustomBody representing a physical object. ********************************************************/ virtual void MoveToLimbo( const ICustomBody* objRef ) = 0; /******************************************************** * An object in limbo state will be ignored during the physics frame Update. * This will clear the accumulated force/torque and remove the Limbo state. * @param objRef: A pointer to the ICustomBody representing a physical object. ********************************************************/ virtual void ReleaseFromLimbo( const ICustomBody* objRef ) = 0; virtual void SetGravityPoint(::Oyster::Math::Float3 gravityPoint) = 0; virtual void SetGravity(float gravity) = 0; // Bullet physics virtual ICustomBody* AddCollisionSphere(float radius, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction) = 0; virtual ICustomBody* AddCollisionBox(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction) = 0; virtual ICustomBody* AddCollisionCylinder(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction) = 0; virtual ICustomBody* AddCharacter(::Oyster::Math::Float height, ::Oyster::Math::Float radius, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction) = 0; virtual ICustomBody* AddTriangleMesh(const std::wstring fileName, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction) = 0; virtual void SetTimeStep(float timeStep) = 0; virtual void UpdateWorld() = 0; /******************************************************** * Applies an effect to objects that collide with the set volume. * @param collideable: An ICollideable that defines the volume of the effect. * @param args: The arguments needed for the hitAction function. * @param hitAction: A function that contains the effect. Parameterlist contains the custom body the collideable hits, and the arguments sent to the function. ********************************************************/ virtual void ApplyEffect(Oyster::Collision3D::ICollideable* collideable, void* args, EventAction_ApplyEffect effect) = 0; protected: virtual ~API() {} }; //! The root interface for all physical representations processable by the engine. class PHYSICS_DLL_USAGE ICustomBody { public: enum SubscriptMessage { SubscriptMessage_none, SubscriptMessage_kineticLoss, SubscriptMessage_ignore_collision_response, SubscriptMessage_player_collision_response }; typedef SubscriptMessage (*EventAction_BeforeCollisionResponse)( const ICustomBody *proto, const ICustomBody *deuter ); typedef void (*EventAction_AfterCollisionResponse)( const ICustomBody *proto, const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ); typedef void (*EventAction_Move)( const ICustomBody *object ); typedef Struct::CustomBodyState State; virtual ~ICustomBody() {}; virtual State GetState() const = 0; virtual State & GetState( State &targetMem ) const = 0; virtual void SetState( const State &state ) = 0; virtual void SetSubscription(EventAction_AfterCollisionResponse function) = 0; virtual void SetSubscription(EventAction_Move function) = 0; virtual void ApplyImpulse(::Oyster::Math::Float3 impulse) = 0; virtual void SetLinearVelocity(::Oyster::Math::Float3 velocity) = 0; virtual void SetPosition(::Oyster::Math::Float3 position) = 0; virtual void SetRotation(::Oyster::Math::Float4 quaternion) = 0; virtual void SetRotation(::Oyster::Math::Quaternion quaternion) = 0; virtual void SetRotation(::Oyster::Math::Float3 eulerAngles) = 0; virtual void SetRotation(::Oyster::Math::Float4x4 rotation) = 0; virtual void AddRotationAroundY(::Oyster::Math::Float angle) = 0; virtual void SetAngularFactor(::Oyster::Math::Float factor) = 0; virtual void SetMass(::Oyster::Math::Float mass) = 0; virtual void SetGravity(::Oyster::Math::Float3 gravity) = 0; virtual void SetUpAndRight(::Oyster::Math::Float3 up, ::Oyster::Math::Float3 right) = 0; virtual void SetUpAndForward(::Oyster::Math::Float3 up, ::Oyster::Math::Float3 forward) = 0; virtual void SetUp(::Oyster::Math::Float3 up) = 0; virtual ::Oyster::Math::Float4x4 GetRotation() const = 0; virtual ::Oyster::Math::Float4 GetRotationAsAngularAxis() = 0; virtual ::Oyster::Math::Float4x4 GetOrientation() const = 0; virtual ::Oyster::Math::Float4x4 GetView() const = 0; virtual ::Oyster::Math::Float4x4 GetView(const ::Oyster::Math::Float3 &offset) const = 0; virtual ::Oyster::Math::Float3 GetGravity() const = 0; virtual ::Oyster::Math::Float3 GetLinearVelocity() const = 0; virtual void CallSubscription_AfterCollisionResponse(ICustomBody* bodyA, ICustomBody* bodyB, Math::Float kineticEnergyLoss) = 0; virtual void CallSubscription_Move() = 0; virtual void MoveToLimbo() = 0; virtual void ReleaseFromLimbo() = 0; /******************************************************** * @return the void pointer set by SetCustomTag. * nullptr if none is set. ********************************************************/ virtual void* GetCustomTag() const = 0; /******************************************************** * Not used by the engine itself. Just a quality of life feature * for developers who want to tag something to the objects. * @param ref: Anything castable to a void pointer, the engine won't care. ********************************************************/ virtual void SetCustomTag( void *ref ) = 0; virtual float GetLambda() const = 0; }; } } #include "PhysicsStructs.h" #endif