Add Physics2D components and systems (WIP)
This commit is contained in:
parent
9b1583501b
commit
19f6bdf7e0
|
|
@ -0,0 +1,191 @@
|
||||||
|
#include <Nazara/Core.hpp>
|
||||||
|
#include <Nazara/Platform.hpp>
|
||||||
|
#include <Nazara/Graphics.hpp>
|
||||||
|
#include <Nazara/Graphics/TextSprite.hpp>
|
||||||
|
#include <Nazara/Graphics/Components.hpp>
|
||||||
|
#include <Nazara/Graphics/Systems.hpp>
|
||||||
|
#include <Nazara/Math/PidController.hpp>
|
||||||
|
#include <Nazara/Physics2D.hpp>
|
||||||
|
#include <Nazara/Physics2D/Components.hpp>
|
||||||
|
#include <Nazara/Physics2D/Systems.hpp>
|
||||||
|
#include <Nazara/Renderer.hpp>
|
||||||
|
#include <Nazara/Shader.hpp>
|
||||||
|
#include <Nazara/Shader/SpirvConstantCache.hpp>
|
||||||
|
#include <Nazara/Shader/SpirvPrinter.hpp>
|
||||||
|
#include <Nazara/Utility.hpp>
|
||||||
|
#include <Nazara/Utility/Components.hpp>
|
||||||
|
#include <Nazara/Widgets.hpp>
|
||||||
|
#include <entt/entt.hpp>
|
||||||
|
#include <array>
|
||||||
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
NAZARA_REQUEST_DEDICATED_GPU()
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::filesystem::path resourceDir = "resources";
|
||||||
|
if (!std::filesystem::is_directory(resourceDir) && std::filesystem::is_directory(".." / resourceDir))
|
||||||
|
resourceDir = ".." / resourceDir;
|
||||||
|
|
||||||
|
Nz::Renderer::Config rendererConfig;
|
||||||
|
std::cout << "Run using Vulkan? (y/n)" << std::endl;
|
||||||
|
if (std::getchar() != 'n')
|
||||||
|
rendererConfig.preferredAPI = Nz::RenderAPI::Vulkan;
|
||||||
|
else
|
||||||
|
rendererConfig.preferredAPI = Nz::RenderAPI::OpenGL;
|
||||||
|
|
||||||
|
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||||
|
|
||||||
|
Nz::Modules<Nz::Graphics, Nz::Physics2D> nazara(rendererConfig);
|
||||||
|
|
||||||
|
Nz::RenderWindow window;
|
||||||
|
|
||||||
|
std::shared_ptr<Nz::RenderDevice> device = Nz::Graphics::Instance()->GetRenderDevice();
|
||||||
|
|
||||||
|
std::string windowTitle = "Graphics Test";
|
||||||
|
if (!window.Create(device, Nz::VideoMode(1920, 1080, 32), windowTitle))
|
||||||
|
{
|
||||||
|
std::cout << "Failed to create Window" << std::endl;
|
||||||
|
return __LINE__;
|
||||||
|
}
|
||||||
|
|
||||||
|
entt::registry registry;
|
||||||
|
|
||||||
|
Nz::Physics2DSystem physSytem(registry);
|
||||||
|
physSytem.GetPhysWorld().SetGravity({ 0.f, -9.81f });
|
||||||
|
|
||||||
|
Nz::RenderSystem renderSystem(registry);
|
||||||
|
|
||||||
|
entt::entity viewer = registry.create();
|
||||||
|
{
|
||||||
|
registry.emplace<Nz::NodeComponent>(viewer);
|
||||||
|
auto& cameraComponent = registry.emplace<Nz::CameraComponent>(viewer, window.GetRenderTarget(), Nz::ProjectionType::Orthographic);
|
||||||
|
cameraComponent.UpdateRenderMask(1);
|
||||||
|
cameraComponent.UpdateClearColor(Nz::Color(127, 127, 127));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>();
|
||||||
|
|
||||||
|
std::shared_ptr<Nz::MaterialPass> materialPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
|
||||||
|
material->AddPass("ForwardPass", materialPass);
|
||||||
|
|
||||||
|
Nz::TextureSamplerInfo samplerInfo;
|
||||||
|
samplerInfo.anisotropyLevel = 8;
|
||||||
|
|
||||||
|
Nz::TextureParams texParams;
|
||||||
|
texParams.renderDevice = device;
|
||||||
|
texParams.loadFormat = Nz::PixelFormat::RGBA8_SRGB;
|
||||||
|
|
||||||
|
Nz::BasicMaterial basicMat(*materialPass);
|
||||||
|
basicMat.SetDiffuseMap(Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams));
|
||||||
|
basicMat.SetDiffuseSampler(samplerInfo);
|
||||||
|
|
||||||
|
for (std::size_t y = 0; y < 10; ++y)
|
||||||
|
{
|
||||||
|
for (std::size_t x = 0; x < 10; ++x)
|
||||||
|
{
|
||||||
|
entt::entity spriteEntity = registry.create();
|
||||||
|
{
|
||||||
|
std::shared_ptr<Nz::Sprite> sprite = std::make_shared<Nz::Sprite>(material);
|
||||||
|
sprite->SetSize({ 32.f, 32.f });
|
||||||
|
sprite->SetOrigin({ 16.f, 16.f, 0.f });
|
||||||
|
|
||||||
|
registry.emplace<Nz::NodeComponent>(spriteEntity).SetPosition(1920 / 2 + x * 36.f, 1080 / 2 + y * 36.f);
|
||||||
|
registry.emplace<Nz::GraphicsComponent>(spriteEntity).AttachRenderable(sprite, 1);
|
||||||
|
auto& rigidBody = registry.emplace<Nz::RigidBody2DComponent>(spriteEntity, physSytem.CreateRigidBody(50.f, std::make_shared<Nz::BoxCollider2D>(Nz::Vector2f(32.f, 32.f))));
|
||||||
|
rigidBody.SetElasticity(0.99f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entt::entity groundEntity = registry.create();
|
||||||
|
{
|
||||||
|
std::shared_ptr<Nz::Material> whiteMaterial = std::make_shared<Nz::Material>();
|
||||||
|
|
||||||
|
std::shared_ptr<Nz::MaterialPass> materialPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
|
||||||
|
whiteMaterial->AddPass("ForwardPass", materialPass);
|
||||||
|
|
||||||
|
std::shared_ptr<Nz::Sprite> sprite = std::make_shared<Nz::Sprite>(whiteMaterial);
|
||||||
|
sprite->SetSize({ 800.f, 20.f });
|
||||||
|
sprite->SetOrigin({ 400.f, 10.f, 0.f });
|
||||||
|
|
||||||
|
registry.emplace<Nz::NodeComponent>(groundEntity).SetPosition(1920.f / 2.f, 50.f);
|
||||||
|
registry.emplace<Nz::GraphicsComponent>(groundEntity).AttachRenderable(sprite, 1);
|
||||||
|
auto& rigidBody = registry.emplace<Nz::RigidBody2DComponent>(groundEntity, physSytem.CreateRigidBody(0.f, std::make_shared<Nz::BoxCollider2D>(Nz::Vector2f(800.f, 20.f))));
|
||||||
|
rigidBody.SetElasticity(0.99f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Nz::EulerAnglesf camAngles(0.f, 0.f, 0.f);
|
||||||
|
Nz::Quaternionf camQuat(camAngles);
|
||||||
|
|
||||||
|
window.EnableEventPolling(true);
|
||||||
|
|
||||||
|
Nz::Clock updateClock;
|
||||||
|
Nz::Clock secondClock;
|
||||||
|
unsigned int fps = 0;
|
||||||
|
|
||||||
|
//Nz::Mouse::SetRelativeMouseMode(true);
|
||||||
|
|
||||||
|
float elapsedTime = 0.f;
|
||||||
|
Nz::UInt64 time = Nz::GetElapsedMicroseconds();
|
||||||
|
|
||||||
|
Nz::PidController<Nz::Vector3f> headingController(0.5f, 0.f, 0.05f);
|
||||||
|
Nz::PidController<Nz::Vector3f> upController(1.f, 0.f, 0.1f);
|
||||||
|
|
||||||
|
bool showColliders = false;
|
||||||
|
while (window.IsOpen())
|
||||||
|
{
|
||||||
|
Nz::UInt64 now = Nz::GetElapsedMicroseconds();
|
||||||
|
elapsedTime = (now - time) / 1'000'000.f;
|
||||||
|
time = now;
|
||||||
|
|
||||||
|
Nz::WindowEvent event;
|
||||||
|
while (window.PollEvent(&event))
|
||||||
|
{
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case Nz::WindowEventType::Quit:
|
||||||
|
window.Close();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Nz::WindowEventType::KeyPressed:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Nz::WindowEventType::MouseMoved:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateClock.GetMilliseconds() > 1000 / 60)
|
||||||
|
{
|
||||||
|
float updateTime = updateClock.Restart() / 1'000'000.f;
|
||||||
|
|
||||||
|
physSytem.Update(registry, 1000.f / 60.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Nz::RenderFrame frame = window.AcquireFrame();
|
||||||
|
if (!frame)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
renderSystem.Render(registry, frame);
|
||||||
|
|
||||||
|
frame.Present();
|
||||||
|
|
||||||
|
fps++;
|
||||||
|
|
||||||
|
if (secondClock.GetMilliseconds() >= 1000)
|
||||||
|
{
|
||||||
|
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS" + " - " + Nz::NumberToString(registry.alive()) + " entities");
|
||||||
|
|
||||||
|
fps = 0;
|
||||||
|
|
||||||
|
secondClock.Restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
target("Physics2DDemo")
|
||||||
|
set_group("Examples")
|
||||||
|
set_kind("binary")
|
||||||
|
add_deps("NazaraGraphics", "NazaraPhysics2D")
|
||||||
|
add_packages("entt")
|
||||||
|
add_files("main.cpp")
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
// this file was automatically generated and should not be edited
|
||||||
|
|
||||||
|
/*
|
||||||
|
Nazara Engine - Physics2D module
|
||||||
|
|
||||||
|
Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_PHYSICS2D_COMPONENTS_HPP
|
||||||
|
#define NAZARA_PHYSICS2D_COMPONENTS_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Physics2D/Components/RigidBody2DComponent.hpp>
|
||||||
|
|
||||||
|
#endif // NAZARA_PHYSICS2D_COMPONENTS_HPP
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||||
|
// This file is part of the "Nazara Engine - Physics2D module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_PHYSICS2D_COMPONENTS_RIGIDBODY2DCOMPONENT_HPP
|
||||||
|
#define NAZARA_PHYSICS2D_COMPONENTS_RIGIDBODY2DCOMPONENT_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequisites.hpp>
|
||||||
|
#include <Nazara/Physics2D/RigidBody2D.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
class NAZARA_PHYSICS2D_API RigidBody2DComponent : public RigidBody2D
|
||||||
|
{
|
||||||
|
friend class Physics2DSystem;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using RigidBody2D::RigidBody2D;
|
||||||
|
RigidBody2DComponent(const RigidBody2DComponent&) = default;
|
||||||
|
RigidBody2DComponent(RigidBody2DComponent&&) noexcept = default;
|
||||||
|
~RigidBody2DComponent() = default;
|
||||||
|
|
||||||
|
RigidBody2DComponent& operator=(const RigidBody2DComponent&) = default;
|
||||||
|
RigidBody2DComponent& operator=(RigidBody2DComponent&&) noexcept = default;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Physics2D/Components/RigidBody2DComponent.inl>
|
||||||
|
|
||||||
|
#endif // NAZARA_PHYSICS2D_COMPONENTS_RIGIDBODY2DCOMPONENT_HPP
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||||
|
// This file is part of the "Nazara Engine - Physics2D module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Physics2D/Components/RigidBody2DComponent.hpp>
|
||||||
|
#include <Nazara/Physics2D/Debug.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Physics2D/DebugOff.hpp>
|
||||||
|
|
@ -110,9 +110,11 @@ namespace Nz
|
||||||
|
|
||||||
static constexpr std::size_t InvalidShapeIndex = std::numeric_limits<std::size_t>::max();
|
static constexpr std::size_t InvalidShapeIndex = std::numeric_limits<std::size_t>::max();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cpBody* Create(float mass = 1.f, float moment = 1.f);
|
cpBody* Create(float mass = 1.f, float moment = 1.f);
|
||||||
void Destroy();
|
|
||||||
void RegisterToSpace();
|
void RegisterToSpace();
|
||||||
void UnregisterFromSpace();
|
void UnregisterFromSpace();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
// this file was automatically generated and should not be edited
|
||||||
|
|
||||||
|
/*
|
||||||
|
Nazara Engine - Physics2D module
|
||||||
|
|
||||||
|
Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_PHYSICS2D_SYSTEMS_HPP
|
||||||
|
#define NAZARA_PHYSICS2D_SYSTEMS_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Physics2D/Systems/Physics2DSystem.hpp>
|
||||||
|
|
||||||
|
#endif // NAZARA_PHYSICS2D_SYSTEMS_HPP
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||||
|
// This file is part of the "Nazara Engine - Physics2D module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_PHYSICS2D_SYSTEMS_PHYSICS2DSYSTEM_HPP
|
||||||
|
#define NAZARA_PHYSICS2D_SYSTEMS_PHYSICS2DSYSTEM_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequisites.hpp>
|
||||||
|
#include <Nazara/Physics2D/PhysWorld2D.hpp>
|
||||||
|
#include <Nazara/Physics2D/Components/RigidBody2DComponent.hpp>
|
||||||
|
#include <entt/entt.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
class NAZARA_PHYSICS2D_API Physics2DSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Physics2DSystem(entt::registry& registry);
|
||||||
|
Physics2DSystem(const Physics2DSystem&) = delete;
|
||||||
|
Physics2DSystem(Physics2DSystem&&) = delete;
|
||||||
|
~Physics2DSystem();
|
||||||
|
|
||||||
|
template<typename... Args> RigidBody2DComponent CreateRigidBody(Args&&... args);
|
||||||
|
|
||||||
|
inline PhysWorld2D& GetPhysWorld();
|
||||||
|
inline const PhysWorld2D& GetPhysWorld() const;
|
||||||
|
|
||||||
|
void Update(entt::registry& registry, float elapsedTime);
|
||||||
|
|
||||||
|
Physics2DSystem& operator=(const Physics2DSystem&) = delete;
|
||||||
|
Physics2DSystem& operator=(Physics2DSystem&&) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void OnConstruct(entt::registry& registry, entt::entity entity);
|
||||||
|
|
||||||
|
entt::registry& m_registry;
|
||||||
|
entt::connection m_constructConnection;
|
||||||
|
PhysWorld2D m_physWorld;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Physics2D/Systems/Physics2DSystem.inl>
|
||||||
|
|
||||||
|
#endif // NAZARA_PHYSICS2D_SYSTEMS_PHYSICS2DSYSTEM_HPP
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||||
|
// This file is part of the "Nazara Engine - Physics2D module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Physics2D/Systems/Physics2DSystem.hpp>
|
||||||
|
#include <Nazara/Physics2D/Debug.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
template<typename... Args>
|
||||||
|
RigidBody2DComponent Physics2DSystem::CreateRigidBody(Args&&... args)
|
||||||
|
{
|
||||||
|
return RigidBody2DComponent(&m_physWorld, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PhysWorld2D& Physics2DSystem::GetPhysWorld()
|
||||||
|
{
|
||||||
|
return m_physWorld;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const PhysWorld2D& Physics2DSystem::GetPhysWorld() const
|
||||||
|
{
|
||||||
|
return m_physWorld;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Physics2D/DebugOff.hpp>
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||||
|
// This file is part of the "Nazara Engine - Physics2D module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Physics2D/Components/RigidBody2DComponent.hpp>
|
||||||
|
#include <Nazara/Physics2D/Debug.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
@ -620,6 +620,22 @@ namespace Nz
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RigidBody2D::Destroy()
|
||||||
|
{
|
||||||
|
UnregisterFromSpace();
|
||||||
|
|
||||||
|
for (cpShape* shape : m_shapes)
|
||||||
|
cpShapeFree(shape);
|
||||||
|
|
||||||
|
if (m_handle)
|
||||||
|
{
|
||||||
|
cpBodyFree(m_handle);
|
||||||
|
m_handle = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_shapes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
cpBody* RigidBody2D::Create(float mass, float moment)
|
cpBody* RigidBody2D::Create(float mass, float moment)
|
||||||
{
|
{
|
||||||
cpBody* handle;
|
cpBody* handle;
|
||||||
|
|
@ -638,19 +654,6 @@ namespace Nz
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody2D::Destroy()
|
|
||||||
{
|
|
||||||
UnregisterFromSpace();
|
|
||||||
|
|
||||||
for (cpShape* shape : m_shapes)
|
|
||||||
cpShapeFree(shape);
|
|
||||||
|
|
||||||
if (m_handle)
|
|
||||||
cpBodyFree(m_handle);
|
|
||||||
|
|
||||||
m_shapes.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody2D::RegisterToSpace()
|
void RigidBody2D::RegisterToSpace()
|
||||||
{
|
{
|
||||||
if (!m_isRegistered)
|
if (!m_isRegistered)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||||
|
// This file is part of the "Nazara Engine - Physics2D module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Physics2D/Systems/Physics2DSystem.hpp>
|
||||||
|
#include <Nazara/Utility/Components/NodeComponent.hpp>
|
||||||
|
#include <Nazara/Physics2D/Debug.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
inline Nz::RadianAnglef AngleFromQuaternion(const Nz::Quaternionf& quat)
|
||||||
|
{
|
||||||
|
float siny_cosp = 2.f * (quat.w * quat.z + quat.x * quat.y);
|
||||||
|
float cosy_cosp = 1.f - 2.f * (quat.y * quat.y + quat.z * quat.z);
|
||||||
|
|
||||||
|
return std::atan2(siny_cosp, cosy_cosp); //<FIXME: not very efficient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Physics2DSystem::Physics2DSystem(entt::registry& registry) :
|
||||||
|
m_registry(registry)
|
||||||
|
{
|
||||||
|
m_constructConnection = registry.on_construct<RigidBody2DComponent>().connect<OnConstruct>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Physics2DSystem::~Physics2DSystem()
|
||||||
|
{
|
||||||
|
// Ensure every NewtonBody is destroyed before world is
|
||||||
|
auto rigidBodyView = m_registry.view<RigidBody2DComponent>();
|
||||||
|
for (auto [entity, rigidBodyComponent] : rigidBodyView.each())
|
||||||
|
rigidBodyComponent.Destroy();
|
||||||
|
|
||||||
|
m_constructConnection.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Physics2DSystem::Update(entt::registry& registry, float elapsedTime)
|
||||||
|
{
|
||||||
|
m_physWorld.Step(elapsedTime);
|
||||||
|
|
||||||
|
// Replicate rigid body position to their node components
|
||||||
|
auto view = registry.view<NodeComponent, const RigidBody2DComponent>();
|
||||||
|
for (auto [entity, nodeComponent, rigidBodyComponent] : view.each())
|
||||||
|
{
|
||||||
|
if (rigidBodyComponent.IsSleeping())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
nodeComponent.SetPosition(rigidBodyComponent.GetPosition(), CoordSys::Global);
|
||||||
|
nodeComponent.SetRotation(rigidBodyComponent.GetRotation(), CoordSys::Global);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Physics2DSystem::OnConstruct(entt::registry& registry, entt::entity entity)
|
||||||
|
{
|
||||||
|
// If our entity already has a node component when adding a rigid body, initialize it with its position/rotation
|
||||||
|
NodeComponent* node = registry.try_get<NodeComponent>(entity);
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
RigidBody2DComponent& rigidBody = registry.get<RigidBody2DComponent>(entity);
|
||||||
|
rigidBody.SetPosition(Vector2f(node->GetPosition()));
|
||||||
|
rigidBody.SetRotation(AngleFromQuaternion(node->GetRotation()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue