Physics2D/RigidBody2D: Add possibility to setup a custom velocity function
This commit is contained in:
parent
40cd8a7987
commit
662ccbd5d0
|
|
@ -159,6 +159,7 @@ Nazara Engine:
|
|||
- Fixed LuaCoroutine movement assignation operator
|
||||
- Added Arbiter2D::GetBodies
|
||||
- Added RigidBody2D::ForEachArbiter
|
||||
- Added possibility to change the RigidBody2D velocity function called by the physics engine
|
||||
|
||||
Nazara Development Kit:
|
||||
- Added ImageWidget (#139)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ namespace Ndk
|
|||
friend class ConstraintComponent2D;
|
||||
|
||||
public:
|
||||
using VelocityFunc = Nz::RigidBody2D::VelocityFunc;
|
||||
|
||||
PhysicsComponent2D();
|
||||
PhysicsComponent2D(const PhysicsComponent2D& physics);
|
||||
~PhysicsComponent2D() = default;
|
||||
|
|
@ -55,10 +57,13 @@ namespace Ndk
|
|||
inline Nz::Vector2f GetSurfaceVelocity(std::size_t shapeIndex = 0) const;
|
||||
inline std::size_t GetShapeCount() const;
|
||||
inline Nz::Vector2f GetVelocity() const;
|
||||
const VelocityFunc& GetVelocityFunction() const;
|
||||
|
||||
inline bool IsNodeSynchronizationEnabled() const;
|
||||
inline bool IsSleeping() const;
|
||||
|
||||
inline void ResetVelocityFunction();
|
||||
|
||||
inline void SetAngularDamping(float angularDamping);
|
||||
inline void SetAngularVelocity(const Nz::RadianAnglef& angularVelocity);
|
||||
inline void SetElasticity(float elasticity);
|
||||
|
|
@ -73,6 +78,9 @@ namespace Ndk
|
|||
inline void SetSurfaceVelocity(const Nz::Vector2f& velocity);
|
||||
inline void SetSurfaceVelocity(std::size_t shapeIndex, const Nz::Vector2f& velocity);
|
||||
inline void SetVelocity(const Nz::Vector2f& velocity);
|
||||
inline void SetVelocityFunction(VelocityFunc velocityFunc);
|
||||
|
||||
inline void UpdateVelocity(const Nz::Vector2f& gravity, float damping, float deltaTime);
|
||||
|
||||
static ComponentIndex componentIndex;
|
||||
|
||||
|
|
|
|||
|
|
@ -338,7 +338,6 @@ namespace Ndk
|
|||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
|
||||
inline Nz::Vector2f PhysicsComponent2D::GetVelocity() const
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
|
|
@ -346,6 +345,19 @@ namespace Ndk
|
|||
return m_object->GetVelocity();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the custom velocity function of the physics object
|
||||
* \return Velocity function of the object (may be empty if default function is used)
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
inline auto PhysicsComponent2D::GetVelocityFunction() const -> const VelocityFunc&
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
|
||||
return m_object->GetVelocityFunction();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks if position & rotation are synchronized with NodeComponent
|
||||
* \return true If synchronization is enabled
|
||||
|
|
@ -370,6 +382,18 @@ namespace Ndk
|
|||
return m_object->IsSleeping();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reset velocity function to default one
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the physics object is invalid
|
||||
*/
|
||||
inline void PhysicsComponent2D::ResetVelocityFunction()
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
|
||||
return m_object->ResetVelocityFunction();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the angular damping or moment of inertia of the physics object
|
||||
*
|
||||
|
|
@ -580,6 +604,39 @@ namespace Ndk
|
|||
m_object->SetVelocity(velocity);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets a custom velocity function for the physics object
|
||||
*
|
||||
* A velocity function is called (for non-kinematic and non-static objects) at every physics update to compute the new velocity of the object.
|
||||
* You may call UpdateVelocity (the default velocity function) to let the physics engine compute that itself and then adjust it using GetVelocity/SetVelocity as you need.
|
||||
*
|
||||
* \param velocityFunc New custom velocity function
|
||||
*
|
||||
* \remark Passing an empty VelocityFunc has the same effect as calling ResetVelocityFunction
|
||||
* \see ResetVelocityFunction
|
||||
* \see UpdateVelocity
|
||||
*/
|
||||
inline void PhysicsComponent2D::SetVelocityFunction(VelocityFunc velocityFunc)
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
|
||||
m_object->SetVelocityFunction(std::move(velocityFunc));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calls the physics engine default velocity function
|
||||
*
|
||||
* \param gravity Physics system gravity
|
||||
* \param damping Physics system damping (adjusted to deltaTime)
|
||||
* \param deltaTime Elapsed time since last physics update
|
||||
*/
|
||||
inline void PhysicsComponent2D::UpdateVelocity(const Nz::Vector2f& gravity, float damping, float deltaTime)
|
||||
{
|
||||
NazaraAssert(m_object, "Invalid physics object");
|
||||
|
||||
m_object->UpdateVelocity(gravity, damping, deltaTime);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the underlying physics object
|
||||
* \return A reference to the physics object
|
||||
|
|
|
|||
|
|
@ -14,17 +14,21 @@
|
|||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Physics2D/Config.hpp>
|
||||
#include <Nazara/Physics2D/Collider2D.hpp>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
|
||||
struct cpBody;
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class Arbiter2D;
|
||||
class PhysWorld2D;
|
||||
|
||||
class NAZARA_PHYSICS2D_API RigidBody2D
|
||||
{
|
||||
public:
|
||||
using VelocityFunc = std::function<void(RigidBody2D& body2D, const Nz::Vector2f& gravity, float damping, float deltaTime)>;
|
||||
|
||||
RigidBody2D(PhysWorld2D* world, float mass);
|
||||
RigidBody2D(PhysWorld2D* world, float mass, Collider2DRef geom);
|
||||
RigidBody2D(const RigidBody2D& object);
|
||||
|
|
@ -62,6 +66,7 @@ namespace Nz
|
|||
Vector2f GetSurfaceVelocity(std::size_t shapeIndex = 0) const;
|
||||
void* GetUserdata() const;
|
||||
Vector2f GetVelocity() const;
|
||||
const VelocityFunc& GetVelocityFunction() const;
|
||||
PhysWorld2D* GetWorld() const;
|
||||
|
||||
bool IsKinematic() const;
|
||||
|
|
@ -69,6 +74,8 @@ namespace Nz
|
|||
bool IsSleeping() const;
|
||||
bool IsStatic() const;
|
||||
|
||||
void ResetVelocityFunction();
|
||||
|
||||
inline void SetAngularDamping(float angularDamping);
|
||||
void SetAngularVelocity(const RadianAnglef& angularVelocity);
|
||||
void SetElasticity(float elasticity);
|
||||
|
|
@ -86,6 +93,9 @@ namespace Nz
|
|||
void SetStatic(bool setStaticBody = true);
|
||||
void SetUserdata(void* ud);
|
||||
void SetVelocity(const Vector2f& velocity);
|
||||
void SetVelocityFunction(VelocityFunc velocityFunc);
|
||||
|
||||
void UpdateVelocity(const Nz::Vector2f& gravity, float damping, float deltaTime);
|
||||
|
||||
RigidBody2D& operator=(const RigidBody2D& object);
|
||||
RigidBody2D& operator=(RigidBody2D&& object);
|
||||
|
|
@ -104,6 +114,7 @@ namespace Nz
|
|||
static void CopyBodyData(cpBody* from, cpBody* to);
|
||||
static void CopyShapeData(cpShape* from, cpShape* to);
|
||||
|
||||
VelocityFunc m_velocityFunc;
|
||||
std::vector<cpShape*> m_shapes;
|
||||
Collider2DRef m_geom;
|
||||
cpBody* m_handle;
|
||||
|
|
|
|||
|
|
@ -296,6 +296,11 @@ namespace Nz
|
|||
return Vector2f(static_cast<float>(vel.x), static_cast<float>(vel.y));
|
||||
}
|
||||
|
||||
const RigidBody2D::VelocityFunc& RigidBody2D::GetVelocityFunction() const
|
||||
{
|
||||
return m_velocityFunc;
|
||||
}
|
||||
|
||||
PhysWorld2D* RigidBody2D::GetWorld() const
|
||||
{
|
||||
return m_world;
|
||||
|
|
@ -321,6 +326,11 @@ namespace Nz
|
|||
return m_isStatic;
|
||||
}
|
||||
|
||||
void RigidBody2D::ResetVelocityFunction()
|
||||
{
|
||||
m_handle->velocity_func = cpBodyUpdateVelocity;
|
||||
}
|
||||
|
||||
void RigidBody2D::SetAngularVelocity(const RadianAnglef& angularVelocity)
|
||||
{
|
||||
cpBodySetAngularVelocity(m_handle, angularVelocity.value);
|
||||
|
|
@ -516,6 +526,30 @@ namespace Nz
|
|||
cpBodySetVelocity(m_handle, cpv(velocity.x, velocity.y));
|
||||
}
|
||||
|
||||
void RigidBody2D::SetVelocityFunction(VelocityFunc velocityFunc)
|
||||
{
|
||||
m_velocityFunc = std::move(velocityFunc);
|
||||
|
||||
if (m_velocityFunc)
|
||||
{
|
||||
m_handle->velocity_func = [](cpBody* body, cpVect gravity, cpFloat damping, cpFloat dt)
|
||||
{
|
||||
RigidBody2D* rigidBody = static_cast<RigidBody2D*>(cpBodyGetUserData(body));
|
||||
const auto& callback = rigidBody->GetVelocityFunction();
|
||||
assert(callback);
|
||||
|
||||
callback(*rigidBody, Nz::Vector2f(float(gravity.x), float(gravity.y)), float(damping), float(dt));
|
||||
};
|
||||
}
|
||||
else
|
||||
m_handle->velocity_func = cpBodyUpdateVelocity;
|
||||
}
|
||||
|
||||
void RigidBody2D::UpdateVelocity(const Nz::Vector2f & gravity, float damping, float deltaTime)
|
||||
{
|
||||
cpBodyUpdateVelocity(m_handle, cpv(gravity.x, gravity.y), damping, deltaTime);
|
||||
}
|
||||
|
||||
RigidBody2D& RigidBody2D::operator=(const RigidBody2D& object)
|
||||
{
|
||||
RigidBody2D physObj(object);
|
||||
|
|
@ -538,6 +572,7 @@ namespace Nz
|
|||
m_mass = object.m_mass;
|
||||
m_shapes = std::move(object.m_shapes);
|
||||
m_userData = object.m_userData;
|
||||
m_velocityFunc = std::move(object.m_velocityFunc);
|
||||
m_world = object.m_world;
|
||||
|
||||
cpBodySetUserData(m_handle, this);
|
||||
|
|
|
|||
Loading…
Reference in New Issue