ChipmunkPhysics2D: Rework RigidBody2D
This commit is contained in:
parent
8eef44ff76
commit
32f8141bd8
|
|
@ -59,20 +59,24 @@ int main(int argc, char* argv[])
|
|||
std::shared_ptr<Nz::MaterialInstance> spriteMaterial = Nz::Graphics::Instance()->GetDefaultMaterials().phongMaterial->Instantiate();
|
||||
spriteMaterial->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "box.png", texParams));
|
||||
|
||||
Nz::ChipmunkRigidBody2DComponent::DynamicSettings boxSettings;
|
||||
boxSettings.mass = 50.f;
|
||||
boxSettings.geom = std::make_shared<Nz::ChipmunkBoxCollider2D>(Nz::Vector2f(32.f, 32.f));
|
||||
|
||||
std::shared_ptr<Nz::Sprite> boxSprite = std::make_shared<Nz::Sprite>(spriteMaterial);
|
||||
boxSprite->SetSize({ 32.f, 32.f });
|
||||
boxSprite->SetOrigin({ 0.5f, 0.5f });
|
||||
|
||||
for (std::size_t y = 0; y < 30; ++y)
|
||||
{
|
||||
for (std::size_t x = 0; x < 30; ++x)
|
||||
{
|
||||
entt::handle spriteEntity = world.CreateEntity();
|
||||
{
|
||||
std::shared_ptr<Nz::Sprite> sprite = std::make_shared<Nz::Sprite>(spriteMaterial);
|
||||
sprite->SetSize({ 32.f, 32.f });
|
||||
sprite->SetOrigin({ 0.5f, 0.5f });
|
||||
spriteEntity.emplace<Nz::NodeComponent>(Nz::Vector2f(windowSize.x * 0.5f + x * 48.f - 15.f * 48.f, windowSize.y / 2 + y * 48.f));
|
||||
spriteEntity.emplace<Nz::GraphicsComponent>(boxSprite, 1);
|
||||
|
||||
spriteEntity.emplace<Nz::NodeComponent>().SetPosition(windowSize.x * 0.5f + x * 48.f - 15.f * 48.f, windowSize.y / 2 + y * 48.f);
|
||||
|
||||
spriteEntity.emplace<Nz::GraphicsComponent>().AttachRenderable(sprite, 1);
|
||||
auto& rigidBody = spriteEntity.emplace<Nz::ChipmunkRigidBody2DComponent>(physSytem.CreateRigidBody(50.f, std::make_shared<Nz::ChipmunkBoxCollider2D>(Nz::Vector2f(32.f, 32.f))));
|
||||
auto& rigidBody = spriteEntity.emplace<Nz::ChipmunkRigidBody2DComponent>(boxSettings);
|
||||
rigidBody.SetFriction(0.9f);
|
||||
//rigidBody.SetElasticity(0.99f);
|
||||
}
|
||||
|
|
@ -99,9 +103,12 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
Nz::ChipmunkRigidBody2DComponent::StaticSettings groundSettings;
|
||||
groundSettings.geom = std::make_shared<Nz::ChipmunkBoxCollider2D>(tilemap->GetSize());
|
||||
|
||||
groundEntity.emplace<Nz::NodeComponent>().SetPosition(windowSize.x * 0.5f, -windowSize.y * 0.2f);
|
||||
groundEntity.emplace<Nz::GraphicsComponent>().AttachRenderable(tilemap, 1);
|
||||
auto& rigidBody = groundEntity.emplace<Nz::ChipmunkRigidBody2DComponent>(physSytem.CreateRigidBody(0.f, std::make_shared<Nz::ChipmunkBoxCollider2D>(tilemap->GetSize())));
|
||||
auto& rigidBody = groundEntity.emplace<Nz::ChipmunkRigidBody2DComponent>(groundSettings);
|
||||
rigidBody.SetFriction(0.9f);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <Nazara/Core/ObjectLibrary.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <NazaraUtils/FunctionRef.hpp>
|
||||
#include <NazaraUtils/Signal.hpp>
|
||||
#include <NazaraUtils/SparsePtr.hpp>
|
||||
#include <vector>
|
||||
|
|
@ -38,7 +39,7 @@ namespace Nz
|
|||
virtual Vector2f ComputeCenterOfMass() const = 0;
|
||||
virtual float ComputeMomentOfInertia(float mass) const = 0;
|
||||
|
||||
virtual void ForEachPolygon(const std::function<void(const Vector2f* vertices, std::size_t vertexCount)>& callback) const;
|
||||
virtual void ForEachPolygon(const FunctionRef<void(const Vector2f* vertices, std::size_t vertexCount)>& callback) const;
|
||||
|
||||
inline UInt32 GetCategoryMask() const;
|
||||
inline UInt32 GetCollisionGroup() const;
|
||||
|
|
|
|||
|
|
@ -27,17 +27,20 @@ namespace Nz
|
|||
class NAZARA_CHIPMUNKPHYSICS2D_API ChipmunkRigidBody2D
|
||||
{
|
||||
public:
|
||||
struct DynamicSettings;
|
||||
struct StaticSettings;
|
||||
|
||||
using VelocityFunc = std::function<void(ChipmunkRigidBody2D& body2D, const Vector2f& gravity, float damping, float deltaTime)>;
|
||||
|
||||
ChipmunkRigidBody2D(ChipmunkPhysWorld2D* world, float mass);
|
||||
ChipmunkRigidBody2D(ChipmunkPhysWorld2D* world, float mass, std::shared_ptr<ChipmunkCollider2D> geom);
|
||||
inline ChipmunkRigidBody2D(ChipmunkPhysWorld2D& world, const DynamicSettings& settings);
|
||||
inline ChipmunkRigidBody2D(ChipmunkPhysWorld2D& world, const StaticSettings& settings);
|
||||
ChipmunkRigidBody2D(const ChipmunkRigidBody2D& object);
|
||||
ChipmunkRigidBody2D(ChipmunkRigidBody2D&& object) noexcept;
|
||||
~ChipmunkRigidBody2D();
|
||||
inline ~ChipmunkRigidBody2D();
|
||||
|
||||
void AddForce(const Vector2f& force, CoordSys coordSys = CoordSys::Global);
|
||||
inline void AddForce(const Vector2f& force, CoordSys coordSys = CoordSys::Global);
|
||||
void AddForce(const Vector2f& force, const Vector2f& point, CoordSys coordSys = CoordSys::Global);
|
||||
void AddImpulse(const Vector2f& impulse, CoordSys coordSys = CoordSys::Global);
|
||||
inline void AddImpulse(const Vector2f& impulse, CoordSys coordSys = CoordSys::Global);
|
||||
void AddImpulse(const Vector2f& impulse, const Vector2f& point, CoordSys coordSys = CoordSys::Global);
|
||||
void AddTorque(const RadianAnglef& torque);
|
||||
|
||||
|
|
@ -45,40 +48,36 @@ namespace Nz
|
|||
|
||||
void EnableSimulation(bool simulation);
|
||||
|
||||
void ForEachArbiter(std::function<void(ChipmunkArbiter2D& /*arbiter*/)> callback);
|
||||
void ForEachArbiter(const FunctionRef<void(ChipmunkArbiter2D& /*arbiter*/)>& callback);
|
||||
void ForceSleep();
|
||||
|
||||
Rectf GetAABB() const;
|
||||
inline float GetAngularDamping() const;
|
||||
RadianAnglef GetAngularVelocity() const;
|
||||
NAZARA_DEPRECATED("Name error, please use GetMassCenter")
|
||||
inline Vector2f GetCenterOfGravity(CoordSys coordSys = CoordSys::Local) const;
|
||||
float GetElasticity(std::size_t shapeIndex = 0) const;
|
||||
float GetFriction(std::size_t shapeIndex = 0) const;
|
||||
const std::shared_ptr<ChipmunkCollider2D>& GetGeom() const;
|
||||
cpBody* GetHandle() const;
|
||||
float GetMass() const;
|
||||
inline const std::shared_ptr<ChipmunkCollider2D>& GetGeom() const;
|
||||
inline cpBody* GetHandle() const;
|
||||
inline float GetMass() const;
|
||||
Vector2f GetMassCenter(CoordSys coordSys = CoordSys::Local) const;
|
||||
float GetMomentOfInertia() const;
|
||||
Vector2f GetPosition() const;
|
||||
inline const Vector2f& GetPositionOffset() const;
|
||||
RadianAnglef GetRotation() const;
|
||||
inline std::size_t GetShapeCount() const;
|
||||
std::size_t GetShapeIndex(cpShape* shape) const;
|
||||
inline std::size_t GetShapeIndex(cpShape* shape) const;
|
||||
Vector2f GetSurfaceVelocity(std::size_t shapeIndex = 0) const;
|
||||
void* GetUserdata() const;
|
||||
inline void* GetUserdata() const;
|
||||
Vector2f GetVelocity() const;
|
||||
const VelocityFunc& GetVelocityFunction() const;
|
||||
ChipmunkPhysWorld2D* GetWorld() const;
|
||||
inline const VelocityFunc& GetVelocityFunction() const;
|
||||
inline ChipmunkPhysWorld2D* GetWorld() const;
|
||||
|
||||
bool IsKinematic() const;
|
||||
bool IsSimulationEnabled() const;
|
||||
inline bool IsKinematic() const;
|
||||
inline bool IsSimulationEnabled() const;
|
||||
bool IsSleeping() const;
|
||||
bool IsStatic() const;
|
||||
inline bool IsStatic() const;
|
||||
|
||||
void ResetVelocityFunction();
|
||||
|
||||
inline void SetAngularDamping(float angularDamping);
|
||||
void SetAngularVelocity(const RadianAnglef& angularVelocity);
|
||||
void SetElasticity(float elasticity);
|
||||
void SetElasticity(std::size_t shapeIndex, float elasticity);
|
||||
|
|
@ -94,7 +93,7 @@ namespace Nz
|
|||
void SetSurfaceVelocity(const Vector2f& surfaceVelocity);
|
||||
void SetSurfaceVelocity(std::size_t shapeIndex, const Vector2f& surfaceVelocity);
|
||||
void SetStatic(bool setStaticBody = true);
|
||||
void SetUserdata(void* ud);
|
||||
inline void SetUserdata(void* ud);
|
||||
void SetVelocity(const Vector2f& velocity);
|
||||
void SetVelocityFunction(VelocityFunc velocityFunc);
|
||||
|
||||
|
|
@ -112,24 +111,59 @@ namespace Nz
|
|||
|
||||
static constexpr std::size_t InvalidShapeIndex = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
struct CommonSettings
|
||||
{
|
||||
std::shared_ptr<ChipmunkCollider2D> geom;
|
||||
RadianAnglef rotation = RadianAnglef::Zero();
|
||||
Vector2f position = Vector2f::Zero();
|
||||
bool initiallySleeping = false;
|
||||
bool isSimulationEnabled = true;
|
||||
};
|
||||
|
||||
struct DynamicSettings : CommonSettings
|
||||
{
|
||||
DynamicSettings() = default;
|
||||
DynamicSettings(std::shared_ptr<ChipmunkCollider2D> collider, float mass_) :
|
||||
mass(mass_)
|
||||
{
|
||||
geom = std::move(collider);
|
||||
}
|
||||
|
||||
RadianAnglef angularVelocity = RadianAnglef::Zero();
|
||||
Vector2f linearVelocity = Vector2f::Zero();
|
||||
float gravityFactor = 1.f;
|
||||
float mass = 1.f;
|
||||
};
|
||||
|
||||
struct StaticSettings : CommonSettings
|
||||
{
|
||||
StaticSettings() = default;
|
||||
StaticSettings(std::shared_ptr<ChipmunkCollider2D> collider)
|
||||
{
|
||||
geom = std::move(collider);
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
ChipmunkRigidBody2D() = default;
|
||||
void Create(ChipmunkPhysWorld2D& world, const DynamicSettings& settings);
|
||||
void Create(ChipmunkPhysWorld2D& world, const StaticSettings& settings);
|
||||
void Destroy();
|
||||
|
||||
private:
|
||||
cpBody* Create(float mass = 1.f, float moment = 1.f);
|
||||
void RegisterToSpace();
|
||||
void UnregisterFromSpace();
|
||||
|
||||
static void CopyBodyData(cpBody* from, cpBody* to);
|
||||
static void CopyShapeData(cpShape* from, cpShape* to);
|
||||
|
||||
Vector2f m_positionOffset;
|
||||
VelocityFunc m_velocityFunc;
|
||||
std::vector<cpShape*> m_shapes;
|
||||
std::shared_ptr<ChipmunkCollider2D> m_geom;
|
||||
cpBody* m_handle;
|
||||
void* m_userData;
|
||||
ChipmunkPhysWorld2D* m_world;
|
||||
MovablePtr<cpBody> m_handle;
|
||||
MovablePtr<ChipmunkPhysWorld2D> m_world;
|
||||
MovablePtr<void> m_userData;
|
||||
Vector2f m_positionOffset;
|
||||
VelocityFunc m_velocityFunc;
|
||||
bool m_isRegistered;
|
||||
bool m_isSimulationEnabled;
|
||||
bool m_isStatic;
|
||||
|
|
|
|||
|
|
@ -6,14 +6,46 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
inline float ChipmunkRigidBody2D::GetAngularDamping() const
|
||||
inline ChipmunkRigidBody2D::ChipmunkRigidBody2D(ChipmunkPhysWorld2D& world, const DynamicSettings& settings)
|
||||
{
|
||||
return GetMomentOfInertia();
|
||||
Create(world, settings);
|
||||
}
|
||||
|
||||
inline Vector2f ChipmunkRigidBody2D::GetCenterOfGravity(CoordSys coordSys) const
|
||||
inline ChipmunkRigidBody2D::ChipmunkRigidBody2D(ChipmunkPhysWorld2D& world, const StaticSettings& settings)
|
||||
{
|
||||
return GetMassCenter(coordSys);
|
||||
Create(world, settings);
|
||||
}
|
||||
|
||||
inline ChipmunkRigidBody2D::~ChipmunkRigidBody2D()
|
||||
{
|
||||
OnRigidBody2DRelease(this);
|
||||
|
||||
Destroy();
|
||||
}
|
||||
|
||||
inline void ChipmunkRigidBody2D::AddForce(const Vector2f& force, CoordSys coordSys)
|
||||
{
|
||||
return AddForce(force, GetMassCenter(coordSys), coordSys);
|
||||
}
|
||||
|
||||
inline void ChipmunkRigidBody2D::AddImpulse(const Vector2f& impulse, CoordSys coordSys)
|
||||
{
|
||||
return AddImpulse(impulse, GetMassCenter(coordSys), coordSys);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<ChipmunkCollider2D>& ChipmunkRigidBody2D::GetGeom() const
|
||||
{
|
||||
return m_geom;
|
||||
}
|
||||
|
||||
inline cpBody* ChipmunkRigidBody2D::GetHandle() const
|
||||
{
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
inline float ChipmunkRigidBody2D::GetMass() const
|
||||
{
|
||||
return m_mass;
|
||||
}
|
||||
|
||||
inline const Vector2f& ChipmunkRigidBody2D::GetPositionOffset() const
|
||||
|
|
@ -21,14 +53,53 @@ namespace Nz
|
|||
return m_positionOffset;
|
||||
}
|
||||
|
||||
inline std::size_t ChipmunkRigidBody2D::GetShapeIndex(cpShape* shape) const
|
||||
{
|
||||
auto it = std::find(m_shapes.begin(), m_shapes.end(), shape);
|
||||
if (it == m_shapes.end())
|
||||
return InvalidShapeIndex;
|
||||
|
||||
return std::distance(m_shapes.begin(), it);
|
||||
}
|
||||
|
||||
inline std::size_t ChipmunkRigidBody2D::GetShapeCount() const
|
||||
{
|
||||
return m_shapes.size();
|
||||
}
|
||||
|
||||
inline void ChipmunkRigidBody2D::SetAngularDamping(float angularDamping)
|
||||
inline void* ChipmunkRigidBody2D::GetUserdata() const
|
||||
{
|
||||
SetMomentOfInertia(angularDamping);
|
||||
return m_userData;
|
||||
}
|
||||
|
||||
inline const ChipmunkRigidBody2D::VelocityFunc& ChipmunkRigidBody2D::GetVelocityFunction() const
|
||||
{
|
||||
return m_velocityFunc;
|
||||
}
|
||||
|
||||
inline ChipmunkPhysWorld2D* ChipmunkRigidBody2D::GetWorld() const
|
||||
{
|
||||
return m_world;
|
||||
}
|
||||
|
||||
inline bool ChipmunkRigidBody2D::IsKinematic() const
|
||||
{
|
||||
return m_mass <= 0.f;
|
||||
}
|
||||
|
||||
inline bool ChipmunkRigidBody2D::IsSimulationEnabled() const
|
||||
{
|
||||
return m_isSimulationEnabled;
|
||||
}
|
||||
|
||||
inline bool ChipmunkRigidBody2D::IsStatic() const
|
||||
{
|
||||
return m_isStatic;
|
||||
}
|
||||
|
||||
inline void ChipmunkRigidBody2D::SetUserdata(void* ud)
|
||||
{
|
||||
m_userData = ud;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/ChipmunkPhysics2D/ChipmunkRigidBody2D.hpp>
|
||||
#include <variant>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
@ -17,13 +18,20 @@ namespace Nz
|
|||
friend class ChipmunkPhysics2DSystem;
|
||||
|
||||
public:
|
||||
using ChipmunkRigidBody2D::ChipmunkRigidBody2D;
|
||||
inline ChipmunkRigidBody2DComponent(const ChipmunkRigidBody2D::DynamicSettings& settings);
|
||||
inline ChipmunkRigidBody2DComponent(const ChipmunkRigidBody2D::StaticSettings& settings);
|
||||
ChipmunkRigidBody2DComponent(const ChipmunkRigidBody2DComponent&) = default;
|
||||
ChipmunkRigidBody2DComponent(ChipmunkRigidBody2DComponent&&) noexcept = default;
|
||||
~ChipmunkRigidBody2DComponent() = default;
|
||||
|
||||
ChipmunkRigidBody2DComponent& operator=(const ChipmunkRigidBody2DComponent&) = default;
|
||||
ChipmunkRigidBody2DComponent& operator=(ChipmunkRigidBody2DComponent&&) noexcept = default;
|
||||
|
||||
private:
|
||||
inline void Construct(ChipmunkPhysWorld2D& world);
|
||||
|
||||
using Setting = std::variant<ChipmunkRigidBody2D::DynamicSettings, ChipmunkRigidBody2D::StaticSettings>;
|
||||
std::unique_ptr<Setting> m_settings;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,25 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
inline ChipmunkRigidBody2DComponent::ChipmunkRigidBody2DComponent(const ChipmunkRigidBody2D::DynamicSettings& settings)
|
||||
{
|
||||
m_settings = std::make_unique<Setting>(settings);
|
||||
}
|
||||
|
||||
inline ChipmunkRigidBody2DComponent::ChipmunkRigidBody2DComponent(const ChipmunkRigidBody2D::StaticSettings& settings)
|
||||
{
|
||||
m_settings = std::make_unique<Setting>(settings);
|
||||
}
|
||||
|
||||
inline void ChipmunkRigidBody2DComponent::Construct(ChipmunkPhysWorld2D& world)
|
||||
{
|
||||
assert(m_settings);
|
||||
std::visit([&](auto&& arg)
|
||||
{
|
||||
Create(world, arg);
|
||||
}, *m_settings);
|
||||
m_settings.reset();
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/ChipmunkPhysics2D/DebugOff.hpp>
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ namespace Nz
|
|||
ChipmunkPhysics2DSystem(ChipmunkPhysics2DSystem&&) = delete;
|
||||
~ChipmunkPhysics2DSystem();
|
||||
|
||||
template<typename... Args> ChipmunkRigidBody2DComponent CreateRigidBody(Args&&... args);
|
||||
|
||||
inline ChipmunkPhysWorld2D& GetPhysWorld();
|
||||
inline const ChipmunkPhysWorld2D& GetPhysWorld() const;
|
||||
|
||||
|
|
@ -38,9 +36,11 @@ namespace Nz
|
|||
ChipmunkPhysics2DSystem& operator=(ChipmunkPhysics2DSystem&&) = delete;
|
||||
|
||||
private:
|
||||
void OnBodyConstruct(entt::registry& registry, entt::entity entity);
|
||||
|
||||
entt::registry& m_registry;
|
||||
entt::observer m_physicsConstructObserver;
|
||||
entt::scoped_connection m_constructConnection;
|
||||
entt::scoped_connection m_bodyConstructConnection;
|
||||
ChipmunkPhysWorld2D m_physWorld;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,12 +6,6 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
template<typename... Args>
|
||||
ChipmunkRigidBody2DComponent ChipmunkPhysics2DSystem::CreateRigidBody(Args&&... args)
|
||||
{
|
||||
return ChipmunkRigidBody2DComponent(&m_physWorld, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
inline ChipmunkPhysWorld2D& ChipmunkPhysics2DSystem::GetPhysWorld()
|
||||
{
|
||||
return m_physWorld;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace Nz
|
|||
|
||||
ChipmunkCollider2D::~ChipmunkCollider2D() = default;
|
||||
|
||||
void ChipmunkCollider2D::ForEachPolygon(const std::function<void(const Vector2f* vertices, std::size_t vertexCount)>& callback) const
|
||||
void ChipmunkCollider2D::ForEachPolygon(const FunctionRef<void(const Vector2f* vertices, std::size_t vertexCount)>& callback) const
|
||||
{
|
||||
// Currently, the only way to get only the polygons of a shape is to create a temporary cpSpace containing only this shape
|
||||
// A better way to do this would be to reimplement this function in every subclass type in the very same way chipmunk does
|
||||
|
|
|
|||
|
|
@ -13,33 +13,11 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
ChipmunkRigidBody2D::ChipmunkRigidBody2D(ChipmunkPhysWorld2D* world, float mass) :
|
||||
ChipmunkRigidBody2D(world, mass, nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
ChipmunkRigidBody2D::ChipmunkRigidBody2D(ChipmunkPhysWorld2D* world, float mass, std::shared_ptr<ChipmunkCollider2D> geom) :
|
||||
m_positionOffset(Vector2f::Zero()),
|
||||
m_geom(),
|
||||
m_userData(nullptr),
|
||||
m_world(world),
|
||||
m_isRegistered(false),
|
||||
m_isSimulationEnabled(true),
|
||||
m_isStatic(false),
|
||||
m_gravityFactor(1.f),
|
||||
m_mass(mass)
|
||||
{
|
||||
NazaraAssert(m_world, "Invalid world");
|
||||
|
||||
m_handle = Create(mass);
|
||||
SetGeom(std::move(geom));
|
||||
}
|
||||
|
||||
ChipmunkRigidBody2D::ChipmunkRigidBody2D(const ChipmunkRigidBody2D& object) :
|
||||
m_positionOffset(object.m_positionOffset),
|
||||
m_geom(object.m_geom),
|
||||
m_userData(object.m_userData),
|
||||
m_world(object.m_world),
|
||||
m_userData(object.m_userData),
|
||||
m_positionOffset(object.m_positionOffset),
|
||||
m_isRegistered(false),
|
||||
m_isSimulationEnabled(true),
|
||||
m_isStatic(object.m_isStatic),
|
||||
|
|
@ -49,8 +27,11 @@ namespace Nz
|
|||
NazaraAssert(m_world, "Invalid world");
|
||||
NazaraAssert(m_geom, "Invalid geometry");
|
||||
|
||||
m_handle = Create(m_mass, object.GetMomentOfInertia());
|
||||
m_handle = cpBodyNew(m_mass, object.GetMomentOfInertia());
|
||||
cpBodySetUserData(m_handle, this);
|
||||
|
||||
SetGeom(object.GetGeom(), false, false);
|
||||
SetVelocityFunction(object.m_velocityFunc);
|
||||
|
||||
CopyBodyData(object.GetHandle(), m_handle);
|
||||
|
||||
|
|
@ -64,12 +45,12 @@ namespace Nz
|
|||
ChipmunkRigidBody2D::ChipmunkRigidBody2D(ChipmunkRigidBody2D&& object) noexcept :
|
||||
OnRigidBody2DMove(std::move(object.OnRigidBody2DMove)),
|
||||
OnRigidBody2DRelease(std::move(object.OnRigidBody2DRelease)),
|
||||
m_positionOffset(std::move(object.m_positionOffset)),
|
||||
m_shapes(std::move(object.m_shapes)),
|
||||
m_geom(std::move(object.m_geom)),
|
||||
m_handle(object.m_handle),
|
||||
m_userData(object.m_userData),
|
||||
m_world(object.m_world),
|
||||
m_userData(object.m_userData),
|
||||
m_positionOffset(std::move(object.m_positionOffset)),
|
||||
m_isRegistered(object.m_isRegistered),
|
||||
m_isSimulationEnabled(object.m_isSimulationEnabled),
|
||||
m_isStatic(object.m_isStatic),
|
||||
|
|
@ -85,18 +66,6 @@ namespace Nz
|
|||
OnRigidBody2DMove(&object, this);
|
||||
}
|
||||
|
||||
ChipmunkRigidBody2D::~ChipmunkRigidBody2D()
|
||||
{
|
||||
OnRigidBody2DRelease(this);
|
||||
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void ChipmunkRigidBody2D::AddForce(const Vector2f& force, CoordSys coordSys)
|
||||
{
|
||||
return AddForce(force, GetMassCenter(coordSys), coordSys);
|
||||
}
|
||||
|
||||
void ChipmunkRigidBody2D::AddForce(const Vector2f& force, const Vector2f& point, CoordSys coordSys)
|
||||
{
|
||||
switch (coordSys)
|
||||
|
|
@ -111,11 +80,6 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void ChipmunkRigidBody2D::AddImpulse(const Vector2f& impulse, CoordSys coordSys)
|
||||
{
|
||||
return AddImpulse(impulse, GetMassCenter(coordSys), coordSys);
|
||||
}
|
||||
|
||||
void ChipmunkRigidBody2D::AddImpulse(const Vector2f& impulse, const Vector2f& point, CoordSys coordSys)
|
||||
{
|
||||
switch (coordSys)
|
||||
|
|
@ -179,19 +143,19 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void ChipmunkRigidBody2D::ForEachArbiter(std::function<void(ChipmunkArbiter2D&)> callback)
|
||||
void ChipmunkRigidBody2D::ForEachArbiter(const FunctionRef<void(ChipmunkArbiter2D&)>& callback)
|
||||
{
|
||||
using CallbackType = decltype(callback);
|
||||
using CallbackType = std::remove_reference_t<decltype(callback)>;
|
||||
|
||||
auto RealCallback = [](cpBody* /*body*/, cpArbiter* arbiter, void* data)
|
||||
auto Trampoline = [](cpBody* /*body*/, cpArbiter* arbiter, void* data)
|
||||
{
|
||||
CallbackType& cb = *static_cast<CallbackType*>(data);
|
||||
|
||||
ChipmunkArbiter2D nzArbiter(arbiter);
|
||||
cb(nzArbiter);
|
||||
ChipmunkArbiter2D wrappedArbiter(arbiter);
|
||||
cb(wrappedArbiter);
|
||||
};
|
||||
|
||||
cpBodyEachArbiter(m_handle, RealCallback, &callback);
|
||||
cpBodyEachArbiter(m_handle, Trampoline, const_cast<void*>(static_cast<const void*>(&callback)));
|
||||
}
|
||||
|
||||
void ChipmunkRigidBody2D::ForceSleep()
|
||||
|
|
@ -233,21 +197,6 @@ namespace Nz
|
|||
return float(cpShapeGetFriction(m_shapes[shapeIndex]));
|
||||
}
|
||||
|
||||
const std::shared_ptr<ChipmunkCollider2D>& ChipmunkRigidBody2D::GetGeom() const
|
||||
{
|
||||
return m_geom;
|
||||
}
|
||||
|
||||
cpBody* ChipmunkRigidBody2D::GetHandle() const
|
||||
{
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
float ChipmunkRigidBody2D::GetMass() const
|
||||
{
|
||||
return m_mass;
|
||||
}
|
||||
|
||||
Vector2f ChipmunkRigidBody2D::GetMassCenter(CoordSys coordSys) const
|
||||
{
|
||||
cpVect massCenter = cpBodyGetCenterOfGravity(m_handle);
|
||||
|
|
@ -281,15 +230,6 @@ namespace Nz
|
|||
return float(cpBodyGetAngle(m_handle));
|
||||
}
|
||||
|
||||
std::size_t ChipmunkRigidBody2D::GetShapeIndex(cpShape* shape) const
|
||||
{
|
||||
auto it = std::find(m_shapes.begin(), m_shapes.end(), shape);
|
||||
if (it == m_shapes.end())
|
||||
return InvalidShapeIndex;
|
||||
|
||||
return std::distance(m_shapes.begin(), it);
|
||||
}
|
||||
|
||||
Vector2f ChipmunkRigidBody2D::GetSurfaceVelocity(std::size_t shapeIndex) const
|
||||
{
|
||||
assert(shapeIndex < m_shapes.size());
|
||||
|
|
@ -297,47 +237,17 @@ namespace Nz
|
|||
return Vector2f(static_cast<float>(vel.x), static_cast<float>(vel.y));
|
||||
}
|
||||
|
||||
void* ChipmunkRigidBody2D::GetUserdata() const
|
||||
{
|
||||
return m_userData;
|
||||
}
|
||||
|
||||
Vector2f ChipmunkRigidBody2D::GetVelocity() const
|
||||
{
|
||||
cpVect vel = cpBodyGetVelocity(m_handle);
|
||||
return Vector2f(static_cast<float>(vel.x), static_cast<float>(vel.y));
|
||||
}
|
||||
|
||||
const ChipmunkRigidBody2D::VelocityFunc& ChipmunkRigidBody2D::GetVelocityFunction() const
|
||||
{
|
||||
return m_velocityFunc;
|
||||
}
|
||||
|
||||
ChipmunkPhysWorld2D* ChipmunkRigidBody2D::GetWorld() const
|
||||
{
|
||||
return m_world;
|
||||
}
|
||||
|
||||
bool ChipmunkRigidBody2D::IsKinematic() const
|
||||
{
|
||||
return m_mass <= 0.f;
|
||||
}
|
||||
|
||||
bool ChipmunkRigidBody2D::IsSimulationEnabled() const
|
||||
{
|
||||
return m_isSimulationEnabled;
|
||||
}
|
||||
|
||||
bool ChipmunkRigidBody2D::IsSleeping() const
|
||||
{
|
||||
return cpBodyIsSleeping(m_handle) != 0;
|
||||
}
|
||||
|
||||
bool ChipmunkRigidBody2D::IsStatic() const
|
||||
{
|
||||
return m_isStatic;
|
||||
}
|
||||
|
||||
void ChipmunkRigidBody2D::ResetVelocityFunction()
|
||||
{
|
||||
m_handle->velocity_func = cpBodyUpdateVelocity;
|
||||
|
|
@ -383,7 +293,8 @@ namespace Nz
|
|||
cpFloat mass = cpBodyGetMass(m_handle);
|
||||
cpFloat moment = cpBodyGetMoment(m_handle);
|
||||
|
||||
cpBody* newHandle = Create(static_cast<float>(mass), static_cast<float>(moment));
|
||||
cpBody* newHandle = cpBodyNew(static_cast<float>(mass), static_cast<float>(moment));
|
||||
cpBodySetUserData(newHandle, this);
|
||||
|
||||
CopyBodyData(m_handle, newHandle);
|
||||
|
||||
|
|
@ -538,11 +449,6 @@ namespace Nz
|
|||
});
|
||||
}
|
||||
|
||||
void ChipmunkRigidBody2D::SetUserdata(void* ud)
|
||||
{
|
||||
m_userData = ud;
|
||||
}
|
||||
|
||||
void ChipmunkRigidBody2D::SetVelocity(const Vector2f& velocity)
|
||||
{
|
||||
cpBodySetVelocity(m_handle, cpv(velocity.x, velocity.y));
|
||||
|
|
@ -637,6 +543,48 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
void ChipmunkRigidBody2D::Create(ChipmunkPhysWorld2D& world, const DynamicSettings& settings)
|
||||
{
|
||||
m_isRegistered = false;
|
||||
m_isSimulationEnabled = settings.isSimulationEnabled;
|
||||
m_isStatic = false;
|
||||
m_gravityFactor = settings.gravityFactor;
|
||||
m_mass = settings.mass;
|
||||
m_positionOffset = Vector2f::Zero();
|
||||
m_userData = nullptr;
|
||||
m_world = &world;
|
||||
|
||||
m_handle = cpBodyNew(m_mass, 0.f); // moment will be recomputed by SetGeom
|
||||
cpBodySetUserData(m_handle, this);
|
||||
if (m_mass <= 0.f)
|
||||
cpBodySetType(m_handle, CP_BODY_TYPE_KINEMATIC);
|
||||
|
||||
SetGeom(settings.geom);
|
||||
SetAngularVelocity(settings.angularVelocity);
|
||||
SetPosition(settings.position);
|
||||
SetRotation(settings.rotation);
|
||||
SetVelocity(settings.linearVelocity);
|
||||
}
|
||||
|
||||
void ChipmunkRigidBody2D::Create(ChipmunkPhysWorld2D& world, const StaticSettings& settings)
|
||||
{
|
||||
m_gravityFactor = 1.f;
|
||||
m_isRegistered = false;
|
||||
m_isSimulationEnabled = settings.isSimulationEnabled;
|
||||
m_isStatic = true;
|
||||
m_mass = 0.f;
|
||||
m_positionOffset = Vector2f::Zero();
|
||||
m_userData = nullptr;
|
||||
m_world = &world;
|
||||
|
||||
m_handle = cpBodyNewStatic();
|
||||
cpBodySetUserData(m_handle, this);
|
||||
|
||||
SetGeom(settings.geom);
|
||||
SetPosition(settings.position);
|
||||
SetRotation(settings.rotation);
|
||||
}
|
||||
|
||||
void ChipmunkRigidBody2D::Destroy()
|
||||
{
|
||||
UnregisterFromSpace();
|
||||
|
|
@ -653,24 +601,6 @@ namespace Nz
|
|||
m_shapes.clear();
|
||||
}
|
||||
|
||||
cpBody* ChipmunkRigidBody2D::Create(float mass, float moment)
|
||||
{
|
||||
cpBody* handle;
|
||||
if (IsKinematic())
|
||||
{
|
||||
if (IsStatic())
|
||||
handle = cpBodyNewStatic();
|
||||
else
|
||||
handle = cpBodyNewKinematic();
|
||||
}
|
||||
else
|
||||
handle = cpBodyNew(mass, moment);
|
||||
|
||||
cpBodySetUserData(handle, this);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void ChipmunkRigidBody2D::RegisterToSpace()
|
||||
{
|
||||
if (!m_isRegistered)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ namespace Nz
|
|||
m_registry(registry),
|
||||
m_physicsConstructObserver(m_registry, entt::collector.group<ChipmunkRigidBody2DComponent, NodeComponent>())
|
||||
{
|
||||
m_bodyConstructConnection = registry.on_construct<ChipmunkRigidBody2DComponent>().connect<&ChipmunkPhysics2DSystem::OnBodyConstruct>(this);
|
||||
}
|
||||
|
||||
ChipmunkPhysics2DSystem::~ChipmunkPhysics2DSystem()
|
||||
|
|
@ -59,4 +60,10 @@ namespace Nz
|
|||
nodeComponent.SetTransform(rigidBodyComponent.GetPosition(), rigidBodyComponent.GetRotation());
|
||||
}
|
||||
}
|
||||
|
||||
void ChipmunkPhysics2DSystem::OnBodyConstruct(entt::registry& registry, entt::entity entity)
|
||||
{
|
||||
ChipmunkRigidBody2DComponent& rigidBody = registry.get<ChipmunkRigidBody2DComponent>(entity);
|
||||
rigidBody.Construct(m_physWorld);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,20 +114,20 @@ SCENARIO("PhysWorld2D", "[PHYSICS2D][PHYSWORLD2D]")
|
|||
Nz::Rectf characterAABB(0.f, 0.f, 1.f, 1.f);
|
||||
std::shared_ptr<Nz::ChipmunkCollider2D> characterBox = std::make_shared<Nz::ChipmunkBoxCollider2D>(characterAABB);
|
||||
characterBox->SetCollisionId(CHARACTER_COLLISION_ID);
|
||||
Nz::ChipmunkRigidBody2D character(&world, 1.f, characterBox);
|
||||
Nz::ChipmunkRigidBody2D character(world, Nz::ChipmunkRigidBody2D::DynamicSettings(characterBox, 1.f));
|
||||
character.SetPosition(Nz::Vector2f::Zero());
|
||||
|
||||
Nz::Rectf wallAABB(0.f, 0.f, 1.f, 2.f);
|
||||
std::shared_ptr<Nz::ChipmunkCollider2D> wallBox = std::make_shared<Nz::ChipmunkBoxCollider2D>(wallAABB);
|
||||
wallBox->SetCollisionId(WALL_COLLISION_ID);
|
||||
Nz::ChipmunkRigidBody2D wall(&world, 0.f, wallBox);
|
||||
Nz::ChipmunkRigidBody2D wall(world, Nz::ChipmunkRigidBody2D::StaticSettings(wallBox));
|
||||
wall.SetPosition(Nz::Vector2f(5.f, 0.f));
|
||||
|
||||
Nz::Rectf triggerAABB(0.f, 0.f, 1.f, 1.f);
|
||||
std::shared_ptr<Nz::ChipmunkCollider2D> triggerBox = std::make_shared<Nz::ChipmunkBoxCollider2D>(triggerAABB);
|
||||
triggerBox->SetTrigger(true);
|
||||
triggerBox->SetCollisionId(TRIGGER_COLLISION_ID);
|
||||
Nz::ChipmunkRigidBody2D trigger(&world, 0.f, triggerBox);
|
||||
Nz::ChipmunkRigidBody2D trigger(world, Nz::ChipmunkRigidBody2D::StaticSettings(triggerBox));
|
||||
trigger.SetPosition(Nz::Vector2f(2.f, 0.f));
|
||||
|
||||
world.Step(Nz::Time::Zero());
|
||||
|
|
@ -199,8 +199,11 @@ Nz::ChipmunkRigidBody2D CreateBody(Nz::ChipmunkPhysWorld2D& world, const Nz::Vec
|
|||
std::shared_ptr<Nz::ChipmunkCollider2D> box = std::make_shared<Nz::ChipmunkBoxCollider2D>(aabb);
|
||||
box->SetCategoryMask(categoryMask);
|
||||
box->SetCollisionMask(collisionMask);
|
||||
float mass = isMoving ? 1.f : 0.f;
|
||||
Nz::ChipmunkRigidBody2D rigidBody(&world, mass, box);
|
||||
rigidBody.SetPosition(position);
|
||||
return rigidBody;
|
||||
|
||||
Nz::ChipmunkRigidBody2D::DynamicSettings settings;
|
||||
settings.geom = std::move(box);
|
||||
settings.mass = isMoving ? 1.f : 0.f;
|
||||
settings.position = position;
|
||||
|
||||
return Nz::ChipmunkRigidBody2D(world, settings);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,12 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
|
||||
Nz::Vector2f positionAABB(3.f, 4.f);
|
||||
Nz::Rectf aabb(positionAABB.x, positionAABB.y, 1.f, 2.f);
|
||||
std::shared_ptr<Nz::ChipmunkCollider2D> box = std::make_shared<Nz::ChipmunkBoxCollider2D>(aabb);
|
||||
float mass = 1.f;
|
||||
Nz::ChipmunkRigidBody2D body(&world, mass, box);
|
||||
|
||||
Nz::ChipmunkRigidBody2D::DynamicSettings dynamicSettings;
|
||||
dynamicSettings.geom = std::make_shared<Nz::ChipmunkBoxCollider2D>(aabb);
|
||||
dynamicSettings.mass = 1.f;
|
||||
|
||||
Nz::ChipmunkRigidBody2D body(world, dynamicSettings);
|
||||
float angularVelocity = 0.2f;
|
||||
body.SetAngularVelocity(angularVelocity);
|
||||
Nz::Vector2f massCenter(5.f, 7.f);
|
||||
|
|
@ -36,6 +39,8 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
|
||||
world.Step(Nz::Time::Second());
|
||||
|
||||
Nz::ChipmunkRigidBody2D::StaticSettings staticSettings;
|
||||
|
||||
WHEN("We copy construct the body")
|
||||
{
|
||||
body.AddForce(Nz::Vector2f(3.f, 5.f));
|
||||
|
|
@ -54,7 +59,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
|
||||
WHEN("We copy assign the body")
|
||||
{
|
||||
Nz::ChipmunkRigidBody2D copiedBody(&world, 0.f);
|
||||
Nz::ChipmunkRigidBody2D copiedBody(world, staticSettings);
|
||||
copiedBody = body;
|
||||
EQUALITY(copiedBody, body);
|
||||
}
|
||||
|
|
@ -62,7 +67,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
WHEN("We move assign the body")
|
||||
{
|
||||
Nz::ChipmunkRigidBody2D copiedBody(body);
|
||||
Nz::ChipmunkRigidBody2D movedBody(&world, 0.f);
|
||||
Nz::ChipmunkRigidBody2D movedBody(world, staticSettings);
|
||||
movedBody = std::move(body);
|
||||
EQUALITY(movedBody, copiedBody);
|
||||
}
|
||||
|
|
@ -113,9 +118,13 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
|
||||
Nz::Vector2f positionAABB(3.f, 4.f);
|
||||
Nz::Rectf aabb(positionAABB.x, positionAABB.y, 1.f, 2.f);
|
||||
std::shared_ptr<Nz::ChipmunkCollider2D> box = std::make_shared<Nz::ChipmunkBoxCollider2D>(aabb);
|
||||
float mass = 1.f;
|
||||
Nz::ChipmunkRigidBody2D body(&world, mass);
|
||||
|
||||
Nz::ChipmunkRigidBody2D::DynamicSettings dynamicSettings;
|
||||
dynamicSettings.mass = 1.f;
|
||||
|
||||
auto box = std::make_shared<Nz::ChipmunkBoxCollider2D>(aabb);
|
||||
|
||||
Nz::ChipmunkRigidBody2D body(world, dynamicSettings);
|
||||
body.SetGeom(box, true, false);
|
||||
|
||||
bool userData = false;
|
||||
|
|
@ -134,7 +143,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
CHECK(body.GetAngularVelocity() == 0.f);
|
||||
CHECK(body.GetMassCenter(Nz::CoordSys::Global) == position);
|
||||
CHECK(body.GetGeom() == box);
|
||||
CHECK(body.GetMass() == Catch::Approx(mass));
|
||||
CHECK(body.GetMass() == Catch::Approx(dynamicSettings.mass));
|
||||
CHECK(body.GetPosition() == position);
|
||||
CHECK(body.GetRotation().value == Catch::Approx(0.f));
|
||||
CHECK(body.GetUserdata() == &userData);
|
||||
|
|
@ -216,9 +225,10 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
|
||||
Nz::Vector2f position(3.f, 4.f);
|
||||
float radius = 5.f;
|
||||
|
||||
std::shared_ptr<Nz::ChipmunkCollider2D> circle = std::make_shared<Nz::ChipmunkCircleCollider2D>(radius, position);
|
||||
float mass = 1.f;
|
||||
Nz::ChipmunkRigidBody2D body(&world, mass);
|
||||
|
||||
Nz::ChipmunkRigidBody2D body(world, Nz::ChipmunkRigidBody2D::DynamicSettings({}, 1.f));
|
||||
body.SetGeom(circle, true, false);
|
||||
|
||||
world.Step(Nz::Time::Second());
|
||||
|
|
@ -249,7 +259,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
std::shared_ptr<Nz::ChipmunkCompoundCollider2D> compound = std::make_shared<Nz::ChipmunkCompoundCollider2D>(colliders);
|
||||
|
||||
float mass = 1.f;
|
||||
Nz::ChipmunkRigidBody2D body(&world, mass);
|
||||
Nz::ChipmunkRigidBody2D body(world, Nz::ChipmunkRigidBody2D::DynamicSettings({}, mass));
|
||||
body.SetGeom(compound, true, false);
|
||||
|
||||
world.Step(Nz::Time::Second());
|
||||
|
|
@ -278,7 +288,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
Nz::SparsePtr<const Nz::Vector2f> sparsePtr(vertices.data());
|
||||
std::shared_ptr<Nz::ChipmunkConvexCollider2D> convex = std::make_shared<Nz::ChipmunkConvexCollider2D>(sparsePtr, vertices.size());
|
||||
float mass = 1.f;
|
||||
Nz::ChipmunkRigidBody2D body(&world, mass);
|
||||
Nz::ChipmunkRigidBody2D body(world, Nz::ChipmunkRigidBody2D::DynamicSettings({}, mass));
|
||||
body.SetGeom(convex, true, false);
|
||||
|
||||
world.Step(Nz::Time::Second());
|
||||
|
|
@ -302,7 +312,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
Nz::Vector2f positionB(1.f, -4.f);
|
||||
std::shared_ptr<Nz::ChipmunkCollider2D> segment = std::make_shared<Nz::ChipmunkSegmentCollider2D>(positionA, positionB, 0.f);
|
||||
float mass = 1.f;
|
||||
Nz::ChipmunkRigidBody2D body(&world, mass);
|
||||
Nz::ChipmunkRigidBody2D body(world, Nz::ChipmunkRigidBody2D::DynamicSettings({}, mass));
|
||||
body.SetGeom(segment, true, false);
|
||||
|
||||
world.Step(Nz::Time::Second());
|
||||
|
|
@ -325,7 +335,7 @@ Nz::ChipmunkRigidBody2D CreateBody(Nz::ChipmunkPhysWorld2D& world)
|
|||
std::shared_ptr<Nz::ChipmunkCollider2D> box = std::make_shared<Nz::ChipmunkBoxCollider2D>(aabb);
|
||||
float mass = 1.f;
|
||||
|
||||
Nz::ChipmunkRigidBody2D body(&world, mass, box);
|
||||
Nz::ChipmunkRigidBody2D body(world, Nz::ChipmunkRigidBody2D::DynamicSettings(box, mass));
|
||||
body.SetPosition(Nz::Vector2f::Zero());
|
||||
|
||||
return body;
|
||||
|
|
|
|||
Loading…
Reference in New Issue