Remove BulletPhysics3D module

Having two physics engine seems redundant, Bullet3 development seems to have halted and JoltPhysics seems to be a better fit to Nazara
This commit is contained in:
Lynix 2024-02-06 20:45:06 +01:00 committed by Jérôme Leclercq
parent cb484a2432
commit 139bed2b0a
40 changed files with 31 additions and 2503 deletions

View File

@ -29,9 +29,6 @@ Nazara also uses the following libraries at its core and for external tools, we
- [minimp3](https://github.com/lieff/minimp3): Minimalistic MP3 decoder single header library
- [OpenAL Soft](https://openal-soft.org): OpenAL Soft is a software implementation of the OpenAL 3D audio API
**Nazara Bullet physics module**:
- [Bullet Physics](http://bulletphysics.org): Bullet Physics SDK
**Nazara Chipmunk physics module**:
- [Chipmunk Physics](https://chipmunk-physics.net/): A fast and lightweight 2D game physics library

View File

@ -2,7 +2,6 @@
#include <Nazara/Core.hpp>
#include <Nazara/Graphics.hpp>
#include <Nazara/Network.hpp>
#include <Nazara/BulletPhysics3D.hpp>
#include <Nazara/Renderer.hpp>
#include <Nazara/Utility.hpp>
#include <NazaraSDK/Application.hpp>

View File

@ -2,7 +2,7 @@
#include <Nazara/Platform.hpp>
#include <Nazara/Graphics.hpp>
#include <Nazara/Math/PidController.hpp>
#include <Nazara/BulletPhysics3D.hpp>
#include <Nazara/JoltPhysics3D.hpp>
#include <Nazara/Renderer.hpp>
#include <Nazara/Utility.hpp>
#include <entt/entt.hpp>
@ -20,14 +20,14 @@ int main(int argc, char* argv[])
if (!std::filesystem::is_directory(resourceDir) && std::filesystem::is_directory("../.." / resourceDir))
resourceDir = "../.." / resourceDir;
Nz::Application<Nz::Graphics, Nz::BulletPhysics3D> app(argc, argv);
Nz::Application<Nz::Graphics, Nz::JoltPhysics3D> app(argc, argv);
auto& windowing = app.AddComponent<Nz::WindowingAppComponent>();
auto& ecs = app.AddComponent<Nz::EntitySystemAppComponent>();
auto& world = ecs.AddWorld<Nz::EnttWorld>();
Nz::BulletPhysics3DSystem& physSytem = world.AddSystem<Nz::BulletPhysics3DSystem>();
Nz::JoltPhysics3DSystem& physSytem = world.AddSystem<Nz::JoltPhysics3DSystem>();
physSytem.GetPhysWorld().SetGravity(Nz::Vector3f::Zero());
Nz::RenderSystem& renderSystem = world.AddSystem<Nz::RenderSystem>();
@ -101,7 +101,7 @@ int main(int argc, char* argv[])
cameraComponent.UpdateClearColor(Nz::Color(0.5f, 0.5f, 0.5f));
}
auto shipCollider = std::make_shared<Nz::BulletConvexCollider3D>(vertices, vertexMapper.GetVertexCount());
auto shipCollider = std::make_shared<Nz::JoltConvexHullCollider3D>(vertices, vertexMapper.GetVertexCount());
std::shared_ptr<Nz::MaterialInstance> colliderMat = Nz::MaterialInstance::Instantiate(Nz::MaterialType::Basic);
colliderMat->SetValueProperty("BaseColor", Nz::Color::Green());
@ -139,7 +139,11 @@ int main(int argc, char* argv[])
auto& entityNode = playerEntity.emplace<Nz::NodeComponent>();
entityNode.SetPosition(Nz::Vector3f(12.5f, 0.f, 25.f));
auto& entityPhys = playerEntity.emplace<Nz::BulletRigidBody3DComponent>(physSytem.CreateRigidBody(shipCollider));
Nz::JoltRigidBody3D::DynamicSettings settings;
settings.geom = shipCollider;
settings.mass = 100.f;
auto& entityPhys = playerEntity.emplace<Nz::JoltRigidBody3DComponent>(settings);
entityPhys.SetMass(50.f);
entityPhys.SetAngularDamping(0.1f);
entityPhys.SetLinearDamping(0.5f);
@ -178,7 +182,11 @@ int main(int argc, char* argv[])
entityNode.SetPosition(Nz::Vector3f(x * 2.f, y * 1.5f, z * 2.f));
entityNode.SetRotation(Nz::EulerAnglesf(0.f, Nz::TurnAnglef(0.5f), 0.f));
auto& entityPhys = entity.emplace<Nz::BulletRigidBody3DComponent>(physSytem.CreateRigidBody(shipCollider));
Nz::JoltRigidBody3D::DynamicSettings settings;
settings.geom = shipCollider;
settings.mass = 100.f;
auto& entityPhys = entity.emplace<Nz::JoltRigidBody3DComponent>(settings);
entityPhys.SetMass(1.f);
entityPhys.SetAngularDamping(0.f);
entityPhys.SetLinearDamping(0.f);
@ -213,13 +221,13 @@ int main(int argc, char* argv[])
showColliders = !showColliders;
if (showColliders)
{
auto view = world.GetRegistry().view<Nz::GraphicsComponent, Nz::BulletRigidBody3DComponent>();
auto view = world.GetRegistry().view<Nz::GraphicsComponent, Nz::JoltRigidBody3DComponent>();
for (auto [entity, gfxComponent, _] : view.each())
gfxComponent.AttachRenderable(colliderModel, 1);
}
else
{
auto view = world.GetRegistry().view<Nz::GraphicsComponent, Nz::BulletRigidBody3DComponent>();
auto view = world.GetRegistry().view<Nz::GraphicsComponent, Nz::JoltRigidBody3DComponent>();
for (auto [entity, gfxComponent, _] : view.each())
gfxComponent.DetachRenderable(colliderModel);
}
@ -234,7 +242,11 @@ int main(int argc, char* argv[])
entity.emplace<Nz::NodeComponent>();
auto& entityPhys = entity.emplace<Nz::BulletRigidBody3DComponent>(physSytem.CreateRigidBody(shipCollider));
Nz::JoltRigidBody3D::DynamicSettings settings;
settings.geom = shipCollider;
settings.mass = 100.f;
auto& entityPhys = entity.emplace<Nz::JoltRigidBody3DComponent>(settings);
entityPhys.SetMass(1.f);
entityPhys.SetAngularDamping(0.f);
entityPhys.SetLinearDamping(0.f);
@ -261,7 +273,7 @@ int main(int argc, char* argv[])
{
float elapsedTime = deltaTime->AsSeconds();
auto spaceshipView = world.GetRegistry().view<Nz::NodeComponent, Nz::BulletRigidBody3DComponent>();
auto spaceshipView = world.GetRegistry().view<Nz::NodeComponent, Nz::JoltRigidBody3DComponent>();
for (auto&& [entity, node, _] : spaceshipView.each())
{
if (entity == playerEntity)
@ -272,7 +284,7 @@ int main(int argc, char* argv[])
world.GetRegistry().destroy(entity);
}
Nz::BulletRigidBody3DComponent& playerShipBody = playerEntity.get<Nz::BulletRigidBody3DComponent>();
Nz::JoltRigidBody3DComponent& playerShipBody = playerEntity.get<Nz::JoltRigidBody3DComponent>();
Nz::Quaternionf currentRotation = playerShipBody.GetRotation();
Nz::Vector3f desiredHeading = headingEntity.get<Nz::NodeComponent>().GetForward();

View File

@ -1,5 +1,5 @@
target("PhysicsDemo")
add_deps("NazaraGraphics", "NazaraBulletPhysics3D")
add_deps("NazaraGraphics", "NazaraJoltPhysics3D")
add_packages("entt")
add_files("main.cpp")
add_defines("NAZARA_ENTT")

View File

@ -1,15 +1,7 @@
// Sources pour https://github.com/NazaraEngine/NazaraEngine/wiki/(FR)-Tutoriel:-%5B01%5D-Hello-World
#define USE_JOLT 1
#include <Nazara/Core.hpp>
#include <Nazara/Graphics.hpp>
#include <Nazara/Platform/WindowingAppComponent.hpp>
#if USE_JOLT
#include <Nazara/JoltPhysics3D.hpp>
#else
#include <Nazara/BulletPhysics3D.hpp>
#endif
#include <Nazara/Renderer.hpp>
#include <Nazara/Utility.hpp>
#include <iostream>
@ -24,11 +16,7 @@ int main(int argc, char* argv[])
Nz::Renderer::Config renderConfig;
renderConfig.validationLevel = Nz::RenderAPIValidationLevel::None;
#if USE_JOLT
Nz::Application<Nz::Graphics, Nz::JoltPhysics3D> app(argc, argv, renderConfig);
#else
Nz::Application<Nz::Graphics, Nz::BulletPhysics3D> app(argc, argv, renderConfig);
#endif
auto& windowing = app.AddComponent<Nz::WindowingAppComponent>();
Nz::Window& mainWindow = windowing.CreateWindow(Nz::VideoMode(1280, 720), "Physics playground");
@ -45,11 +33,7 @@ int main(int argc, char* argv[])
auto& ecs = app.AddComponent<Nz::EntitySystemAppComponent>();
auto& world = ecs.AddWorld<Nz::EnttWorld>();
#if USE_JOLT
auto& physSystem = world.AddSystem<Nz::JoltPhysics3DSystem>();
#else
auto& physSystem = world.AddSystem<Nz::BulletPhysics3DSystem>();
#endif
physSystem.GetPhysWorld().SetMaxStepCount(1);
physSystem.GetPhysWorld().SetStepSize(Nz::Time::TickDuration(30));
physSystem.GetPhysWorld().SetGravity(Nz::Vector3f::Down() * 9.81f);
@ -96,46 +80,24 @@ int main(int argc, char* argv[])
boxColliderEntity.emplace<Nz::NodeComponent>();
#if USE_JOLT
float thickness = 1.f;
std::shared_ptr<Nz::JoltBoxCollider3D> wallCollider = std::make_shared<Nz::JoltBoxCollider3D>(Nz::Vector3f(BoxDims + thickness * 2.f, BoxDims + thickness * 2.f, thickness));
#else
std::shared_ptr<Nz::BulletBoxCollider3D> wallCollider = std::make_shared<Nz::BulletBoxCollider3D>(Nz::Vector3f(BoxDims, BoxDims, 1.f));
#endif
#if USE_JOLT
std::vector<Nz::JoltCompoundCollider3D::ChildCollider> colliders;
#else
std::vector<Nz::BulletCompoundCollider3D::ChildCollider> colliders;
#endif
for (Nz::Vector3f normal : { Nz::Vector3f::Forward(), Nz::Vector3f::Backward(), Nz::Vector3f::Left(), Nz::Vector3f::Right(), Nz::Vector3f::Up(), Nz::Vector3f::Down() })
{
auto& colliderEntry = colliders.emplace_back();
colliderEntry.collider = wallCollider;
#if USE_JOLT
colliderEntry.rotation = Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), normal);
colliderEntry.offset = normal * BoxDims * 0.5f + normal * 0.5f;
#else
colliderEntry.offsetMatrix = Nz::Matrix4f::Transform(normal * BoxDims * 0.5f + normal * 0.5f, Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), normal));
#endif
}
#if USE_JOLT
std::shared_ptr<Nz::JoltCompoundCollider3D> boxCollider = std::make_shared<Nz::JoltCompoundCollider3D>(std::move(colliders));
#else
std::shared_ptr<Nz::BulletCompoundCollider3D> boxCollider = std::make_shared<Nz::BulletCompoundCollider3D>(std::move(colliders));
#endif
#if USE_JOLT
Nz::JoltRigidBody3D::StaticSettings settings;
settings.geom = boxCollider;
boxColliderEntity.emplace<Nz::JoltRigidBody3DComponent>(settings);
#else
auto& boxBody = boxColliderEntity.emplace<Nz::BulletRigidBody3DComponent>(physSystem.CreateRigidBody(boxCollider));
boxBody.SetMass(0.f);
#endif
std::shared_ptr<Nz::Model> colliderModel;
{
@ -163,11 +125,7 @@ int main(int argc, char* argv[])
float radius = radiusDis(rd);
std::uniform_real_distribution<float> positionRandom(-BoxDims * 0.5f + radius, BoxDims * 0.5f - radius);
#if USE_JOLT
std::shared_ptr<Nz::JoltSphereCollider3D> sphereCollider = std::make_shared<Nz::JoltSphereCollider3D>(radius);
#else
std::shared_ptr<Nz::BulletSphereCollider3D> sphereCollider = std::make_shared<Nz::BulletSphereCollider3D>(radius);
#endif
entt::handle ballEntity = world.CreateEntity();
@ -184,15 +142,11 @@ int main(int argc, char* argv[])
ballNode.SetPosition(positionRandom(rd), positionRandom(rd), positionRandom(rd));
ballNode.SetScale(radius);
#if USE_JOLT
Nz::JoltRigidBody3D::DynamicSettings settings;
settings.geom = sphereCollider;
settings.mass = 4.f / 3.f * Nz::Pi<float> * Nz::IntegralPow(radius, 3);
ballEntity.emplace<Nz::JoltRigidBody3DComponent>(settings);
#else
ballEntity.emplace<Nz::BulletRigidBody3DComponent>(physSystem.CreateRigidBody(sphereCollider));
#endif
}
std::uniform_real_distribution<float> lengthDis(0.2f, 1.5f);
@ -223,21 +177,13 @@ int main(int argc, char* argv[])
ballNode.SetPosition(xRandom(rd), yRandom(rd), zRandom(rd));
ballNode.SetScale(width, height, depth);
#if USE_JOLT
std::shared_ptr<Nz::JoltBoxCollider3D> boxCollider = std::make_shared<Nz::JoltBoxCollider3D>(Nz::Vector3f(width, height, depth));
#else
std::shared_ptr<Nz::BulletBoxCollider3D> boxCollider = std::make_shared<Nz::BulletBoxCollider3D>(Nz::Vector3f(width, height, depth));
#endif
#if USE_JOLT
Nz::JoltRigidBody3D::DynamicSettings settings;
settings.geom = boxCollider;
settings.mass = width * height * depth;
boxEntity.emplace<Nz::JoltRigidBody3DComponent>(settings);
#else
boxEntity.emplace<Nz::BulletRigidBody3DComponent>(physSystem.CreateRigidBody(boxCollider));
#endif
}
// Spaceships
@ -281,11 +227,7 @@ int main(int argc, char* argv[])
Nz::VertexMapper vertexMapper(*spaceshipMesh->GetSubMesh(0));
Nz::SparsePtr<Nz::Vector3f> vertices = vertexMapper.GetComponentPtr<Nz::Vector3f>(Nz::VertexComponent::Position);
#if USE_JOLT
auto shipCollider = std::make_shared<Nz::JoltConvexHullCollider3D>(vertices, vertexMapper.GetVertexCount(), 0.1f);
#else
auto shipCollider = std::make_shared<Nz::BulletConvexCollider3D>(vertices, vertexMapper.GetVertexCount());
#endif
std::shared_ptr<Nz::Model> colliderModel;
{
@ -307,15 +249,11 @@ int main(int argc, char* argv[])
auto& shipNode = shipEntity.emplace<Nz::NodeComponent>();
shipNode.SetPosition(xRandom(rd), yRandom(rd), zRandom(rd));
#if USE_JOLT
Nz::JoltRigidBody3D::DynamicSettings settings;
settings.geom = shipCollider;
settings.mass = 100.f;
shipEntity.emplace<Nz::JoltRigidBody3DComponent>(settings);
#else
shipEntity.emplace<Nz::BulletRigidBody3DComponent>(physSystem.CreateRigidBody(shipCollider));
#endif
//shipEntity.get<Nz::GraphicsComponent>().AttachRenderable(colliderModel);
}
@ -363,7 +301,7 @@ int main(int argc, char* argv[])
NazaraSlot(Nz::WindowEventHandler, OnMouseMoved, cameraMove);
NazaraSlot(Nz::WindowEventHandler, OnMouseMoved, grabbedObjectMove);
#if USE_JOLT
struct GrabConstraint
{
GrabConstraint(Nz::JoltRigidBody3D& body, const Nz::Vector3f& grabPos) :
@ -401,9 +339,6 @@ int main(int argc, char* argv[])
};
std::optional<GrabConstraint> grabConstraint;
#else
std::optional<Nz::BulletPivotConstraint3D> grabConstraint;
#endif
auto mouseMoveCallback = [&](const Nz::WindowEventHandler*, const Nz::WindowEvent::MouseMoveEvent& event)
{
@ -430,11 +365,7 @@ int main(int argc, char* argv[])
Nz::Vector3f from = cameraComponent.Unproject({ float(event.x), float(event.y), 0.f });
Nz::Vector3f to = cameraComponent.Unproject({ float(event.x), float(event.y), 1.f });
#if USE_JOLT
Nz::JoltPhysics3DSystem::RaycastHit lastHitInfo;
#else
Nz::BulletPhysics3DSystem::RaycastHit lastHitInfo;
#endif
auto callback = [&](const decltype(lastHitInfo)& hitInfo) -> std::optional<float>
{
if (hitInfo.hitEntity == boxColliderEntity)
@ -455,12 +386,7 @@ int main(int argc, char* argv[])
{
if (lastHitInfo.hitBody && lastHitInfo.hitEntity != boxColliderEntity)
{
#if USE_JOLT
grabConstraint.emplace(static_cast<Nz::JoltRigidBody3D&>(*lastHitInfo.hitBody), lastHitInfo.hitPosition);
#else
grabConstraint.emplace(*lastHitInfo.hitBody, lastHitInfo.hitPosition);
grabConstraint->SetImpulseClamp(30.f);
#endif
grabbedObjectMove.Connect(eventHandler.OnMouseMoved, [&, distance = Nz::Vector3f::Distance(from, lastHitInfo.hitPosition)](const Nz::WindowEventHandler*, const Nz::WindowEvent::MouseMoveEvent& event)
{
@ -468,11 +394,7 @@ int main(int argc, char* argv[])
Nz::Vector3f to = cameraComponent.Unproject({ float(event.x), float(event.y), 1.f });
Nz::Vector3f newPosition = from + (to - from).Normalize() * distance;
#if USE_JOLT
grabConstraint->SetPosition(newPosition);
#else
grabConstraint->SetSecondAnchor(newPosition);
#endif
});
}
else

View File

@ -1,5 +1,5 @@
target("PhysicsPlayground")
add_deps("NazaraGraphics", "NazaraBulletPhysics3D", "NazaraJoltPhysics3D")
add_deps("NazaraGraphics", "NazaraJoltPhysics3D")
add_packages("entt")
add_files("main.cpp")
add_defines("NAZARA_ENTT")

View File

@ -2,7 +2,6 @@
#include <Nazara/Platform.hpp>
#include <Nazara/Graphics.hpp>
#include <Nazara/Math/PidController.hpp>
#include <Nazara/BulletPhysics3D.hpp>
#include <Nazara/JoltPhysics3D.hpp>
#include <Nazara/Renderer.hpp>
#include <Nazara/Utility.hpp>
@ -597,7 +596,7 @@ int main(int argc, char* argv[])
//renderBuffer->Fill(skeletalBufferMem.data(), 0, skeletalBufferMem.size());
/*auto spaceshipView = registry.view<Nz::NodeComponent, Nz::RigidBody3DComponent>();
/*auto spaceshipView = registry.view<Nz::NodeComponent, Nz::JoltRigidBody3DComponent>();
for (auto&& [entity, node, _] : spaceshipView.each())
{
if (entity == playerEntity)
@ -608,7 +607,7 @@ int main(int argc, char* argv[])
registry.destroy(entity);
}
Nz::RigidBody3DComponent& playerShipBody = registry.get<Nz::RigidBody3DComponent>(playerEntity);
Nz::JoltRigidBody3DComponent& playerShipBody = registry.get<Nz::JoltRigidBody3DComponent>(playerEntity);
Nz::Quaternionf currentRotation = playerShipBody.GetRotation();
Nz::Vector3f desiredHeading = registry.get<Nz::NodeComponent>(headingEntity).GetForward();

View File

@ -5,7 +5,7 @@ end
target("Showcase")
set_group("Examples")
set_kind("binary")
add_deps("NazaraAudio", "NazaraGraphics", "NazaraChipmunkPhysics2D", "NazaraBulletPhysics3D", "NazaraJoltPhysics3D", "NazaraWidgets")
add_deps("NazaraAudio", "NazaraGraphics", "NazaraChipmunkPhysics2D", "NazaraJoltPhysics3D", "NazaraWidgets")
if has_config("embed_plugins", "static") then
add_deps("PluginAssimp")
else

View File

@ -2,7 +2,6 @@
#include <Nazara/Core.hpp>
#include <Nazara/Graphics.hpp>
#include <Nazara/Network.hpp>
#include <Nazara/BulletPhysics3D.hpp>
#include <Nazara/ChipmunkPhysics2D.hpp>
#include <Nazara/Renderer.hpp>
#include <Nazara/Utility.hpp>
@ -12,7 +11,7 @@ int main(int argc, char* argv[])
{
// This "example" has only one purpose: Giving an empty project for you to test whatever you want
// If you wish to have multiple test projects, you only have to copy/paste this directory and change the name in the xmake.lua
Nz::Application<Nz::Audio, Nz::Core, Nz::Graphics, Nz::Network, Nz::ChipmunkPhysics2D, Nz::BulletPhysics3D, Nz::Renderer, Nz::Utility> app(argc, argv);
Nz::Application<Nz::Audio, Nz::Core, Nz::Graphics, Nz::Network, Nz::ChipmunkPhysics2D, Nz::Renderer, Nz::Utility> app(argc, argv);
return EXIT_SUCCESS;
}

View File

@ -1,3 +1,3 @@
target("Tut00_EmptyProject")
add_deps("NazaraAudio", "NazaraGraphics", "NazaraNetwork", "NazaraChipmunkPhysics2D", "NazaraBulletPhysics3D", "NazaraRenderer", "NazaraUtility")
add_deps("NazaraAudio", "NazaraGraphics", "NazaraNetwork", "NazaraChipmunkPhysics2D", "NazaraRenderer", "NazaraUtility")
add_files("main.cpp")

View File

@ -1,47 +0,0 @@
// this file was automatically generated and should not be edited
/*
Nazara Engine - BulletPhysics3D module
Copyright (C) 2024 Jérôme "SirLynix" 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_GLOBAL_BULLETPHYSICS3D_HPP
#define NAZARA_GLOBAL_BULLETPHYSICS3D_HPP
#include <Nazara/BulletPhysics3D/BulletCollider3D.hpp>
#include <Nazara/BulletPhysics3D/BulletConstraint3D.hpp>
#include <Nazara/BulletPhysics3D/BulletPhysics3D.hpp>
#include <Nazara/BulletPhysics3D/BulletPhysWorld3D.hpp>
#include <Nazara/BulletPhysics3D/BulletRigidBody3D.hpp>
#include <Nazara/BulletPhysics3D/Config.hpp>
#include <Nazara/BulletPhysics3D/Enums.hpp>
#ifdef NAZARA_ENTT
#include <Nazara/BulletPhysics3D/Components.hpp>
#include <Nazara/BulletPhysics3D/Systems.hpp>
#endif
#endif // NAZARA_GLOBAL_BULLETPHYSICS3D_HPP

View File

@ -1,240 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_BULLETPHYSICS3D_BULLETCOLLIDER3D_HPP
#define NAZARA_BULLETPHYSICS3D_BULLETCOLLIDER3D_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/BulletPhysics3D/Config.hpp>
#include <Nazara/BulletPhysics3D/Enums.hpp>
#include <Nazara/Core/ObjectLibrary.hpp>
#include <Nazara/Math/Box.hpp>
#include <Nazara/Math/Plane.hpp>
#include <Nazara/Math/Quaternion.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <NazaraUtils/Signal.hpp>
#include <NazaraUtils/SparsePtr.hpp>
#include <memory>
class btBoxShape;
class btCapsuleShape;
class btCompoundShape;
class btCollisionShape;
class btConeShape;
class btConvexHullShape;
class btCylinderShape;
class btEmptyShape;
class btSphereShape;
class btStaticPlaneShape;
namespace Nz
{
class PrimitiveList;
class StaticMesh;
struct Primitive;
class NAZARA_BULLETPHYSICS3D_API BulletCollider3D
{
public:
BulletCollider3D() = default;
BulletCollider3D(const BulletCollider3D&) = delete;
BulletCollider3D(BulletCollider3D&&) = delete;
virtual ~BulletCollider3D();
virtual void BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix = Matrix4f::Identity()) const = 0;
Boxf ComputeAABB(const Vector3f& translation, const Quaternionf& rotation, const Vector3f& scale) const;
virtual Boxf ComputeAABB(const Matrix4f& offsetMatrix = Matrix4f::Identity(), const Vector3f& scale = Vector3f::Unit()) const;
virtual void ComputeInertia(float mass, Vector3f* inertia) const;
virtual std::shared_ptr<StaticMesh> GenerateDebugMesh() const;
virtual btCollisionShape* GetShape() const = 0;
virtual BulletColliderType3D GetType() const = 0;
BulletCollider3D& operator=(const BulletCollider3D&) = delete;
BulletCollider3D& operator=(BulletCollider3D&&) = delete;
static std::shared_ptr<BulletCollider3D> Build(const PrimitiveList& list);
private:
static std::shared_ptr<BulletCollider3D> CreateGeomFromPrimitive(const Primitive& primitive);
};
class NAZARA_BULLETPHYSICS3D_API BulletBoxCollider3D final : public BulletCollider3D
{
public:
BulletBoxCollider3D(const Vector3f& lengths);
~BulletBoxCollider3D();
void BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const override;
Vector3f GetLengths() const;
btCollisionShape* GetShape() const override;
BulletColliderType3D GetType() const override;
private:
std::unique_ptr<btBoxShape> m_shape;
Vector3f m_lengths;
};
class NAZARA_BULLETPHYSICS3D_API BulletCapsuleCollider3D final : public BulletCollider3D
{
public:
BulletCapsuleCollider3D(float length, float radius);
~BulletCapsuleCollider3D();
void BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const override;
float GetLength() const;
float GetRadius() const;
btCollisionShape* GetShape() const override;
BulletColliderType3D GetType() const override;
private:
std::unique_ptr<btCapsuleShape> m_shape;
float m_length;
float m_radius;
};
class NAZARA_BULLETPHYSICS3D_API BulletCompoundCollider3D final : public BulletCollider3D
{
public:
struct ChildCollider;
BulletCompoundCollider3D(std::vector<ChildCollider> childs);
~BulletCompoundCollider3D();
void BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const override;
const std::vector<ChildCollider>& GetGeoms() const;
btCollisionShape* GetShape() const override;
BulletColliderType3D GetType() const override;
struct ChildCollider
{
std::shared_ptr<BulletCollider3D> collider;
Matrix4f offsetMatrix;
};
private:
std::unique_ptr<btCompoundShape> m_shape;
std::vector<ChildCollider> m_childs;
};
class NAZARA_BULLETPHYSICS3D_API BulletConeCollider3D final : public BulletCollider3D
{
public:
BulletConeCollider3D(float length, float radius);
~BulletConeCollider3D();
void BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const override;
float GetLength() const;
float GetRadius() const;
btCollisionShape* GetShape() const override;
BulletColliderType3D GetType() const override;
private:
std::unique_ptr<btConeShape> m_shape;
float m_length;
float m_radius;
};
class NAZARA_BULLETPHYSICS3D_API BulletConvexCollider3D final : public BulletCollider3D
{
public:
BulletConvexCollider3D(SparsePtr<const Vector3f> vertices, unsigned int vertexCount);
~BulletConvexCollider3D();
void BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const override;
btCollisionShape* GetShape() const override;
BulletColliderType3D GetType() const override;
private:
std::unique_ptr<btConvexHullShape> m_shape;
};
class NAZARA_BULLETPHYSICS3D_API BulletCylinderCollider3D final : public BulletCollider3D
{
public:
BulletCylinderCollider3D(float length, float radius);
~BulletCylinderCollider3D();
void BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const override;
float GetLength() const;
float GetRadius() const;
btCollisionShape* GetShape() const override;
BulletColliderType3D GetType() const override;
private:
std::unique_ptr<btCylinderShape> m_shape;
Matrix4f m_matrix;
float m_length;
float m_radius;
};
class NAZARA_BULLETPHYSICS3D_API BulletNullCollider3D final : public BulletCollider3D
{
public:
BulletNullCollider3D();
~BulletNullCollider3D();
void BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const override;
void ComputeInertia(float mass, Vector3f* inertia) const override;
btCollisionShape* GetShape() const override;
BulletColliderType3D GetType() const override;
private:
std::unique_ptr<btEmptyShape> m_shape;
};
class NAZARA_BULLETPHYSICS3D_API BulletSphereCollider3D final : public BulletCollider3D
{
public:
BulletSphereCollider3D(float radius);
~BulletSphereCollider3D();
void BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const override;
float GetRadius() const;
btCollisionShape* GetShape() const override;
BulletColliderType3D GetType() const override;
private:
std::unique_ptr<btSphereShape> m_shape;
Vector3f m_position;
float m_radius;
};
class NAZARA_BULLETPHYSICS3D_API BulletStaticPlaneCollider3D final : public BulletCollider3D
{
public:
BulletStaticPlaneCollider3D(const Planef& plane);
BulletStaticPlaneCollider3D(const Vector3f& normal, float distance);
~BulletStaticPlaneCollider3D();
void BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const override;
float GetDistance() const;
const Vector3f& GetNormal() const;
btCollisionShape* GetShape() const override;
BulletColliderType3D GetType() const override;
private:
std::unique_ptr<btStaticPlaneShape> m_shape;
Vector3f m_normal;
float m_distance;
};
}
#include <Nazara/BulletPhysics3D/BulletCollider3D.inl>
#endif // NAZARA_BULLETPHYSICS3D_BULLETCOLLIDER3D_HPP

View File

@ -1,12 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <memory>
#include <Nazara/BulletPhysics3D/Debug.hpp>
namespace Nz
{
}
#include <Nazara/BulletPhysics3D/DebugOff.hpp>

View File

@ -1,82 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_BULLETPHYSICS3D_BULLETCONSTRAINT3D_HPP
#define NAZARA_BULLETPHYSICS3D_BULLETCONSTRAINT3D_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/BulletPhysics3D/BulletPhysWorld3D.hpp>
#include <Nazara/BulletPhysics3D/BulletRigidBody3D.hpp>
#include <Nazara/BulletPhysics3D/Config.hpp>
#include <Nazara/Core/HandledObject.hpp>
#include <Nazara/Core/ObjectHandle.hpp>
class btTypedConstraint;
namespace Nz
{
class BulletConstraint3D;
using BulletConstraint3DHandle = ObjectHandle<BulletConstraint3D>;
class NAZARA_BULLETPHYSICS3D_API BulletConstraint3D : public HandledObject<BulletConstraint3D>
{
public:
BulletConstraint3D(const BulletConstraint3D&) = delete;
BulletConstraint3D(BulletConstraint3D&& constraint) noexcept;
virtual ~BulletConstraint3D();
BulletRigidBody3D& GetBodyA();
const BulletRigidBody3D& GetBodyA() const;
BulletRigidBody3D& GetBodyB();
const BulletRigidBody3D& GetBodyB() const;
BulletPhysWorld3D& GetWorld();
const BulletPhysWorld3D& GetWorld() const;
inline bool IsBodyCollisionEnabled() const;
bool IsSingleBody() const;
BulletConstraint3D& operator=(const BulletConstraint3D&) = delete;
BulletConstraint3D& operator=(BulletConstraint3D&& constraint) noexcept;
protected:
BulletConstraint3D(std::unique_ptr<btTypedConstraint> constraint, bool disableCollisions = false);
template<typename T> T* GetConstraint();
template<typename T> const T* GetConstraint() const;
private:
void Destroy();
std::unique_ptr<btTypedConstraint> m_constraint;
bool m_bodyCollisionEnabled;
};
class NAZARA_BULLETPHYSICS3D_API BulletPivotConstraint3D : public BulletConstraint3D
{
public:
BulletPivotConstraint3D(BulletRigidBody3D& first, const Vector3f& pivot);
BulletPivotConstraint3D(BulletRigidBody3D& first, BulletRigidBody3D& second, const Vector3f& pivot, bool disableCollisions = false);
BulletPivotConstraint3D(BulletRigidBody3D& first, BulletRigidBody3D& second, const Vector3f& firstAnchor, const Vector3f& secondAnchor, bool disableCollisions = false);
~BulletPivotConstraint3D() = default;
Vector3f GetFirstAnchor() const;
Vector3f GetSecondAnchor() const;
float GetDamping() const;
float GetImpulseClamp() const;
void SetFirstAnchor(const Vector3f& firstAnchor);
void SetSecondAnchor(const Vector3f& secondAnchor);
void SetDamping(float damping);
void SetImpulseClamp(float impulseClamp);
};
}
#include <Nazara/BulletPhysics3D/BulletConstraint3D.inl>
#endif // NAZARA_BULLETPHYSICS3D_BULLETCONSTRAINT3D_HPP

View File

@ -1,27 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/BulletPhysics3D/Debug.hpp>
namespace Nz
{
inline bool BulletConstraint3D::IsBodyCollisionEnabled() const
{
return m_bodyCollisionEnabled;
}
template<typename T>
T* BulletConstraint3D::GetConstraint()
{
return SafeCast<T*>(m_constraint.get());
}
template<typename T>
const T* BulletConstraint3D::GetConstraint() const
{
return SafeCast<const T*>(m_constraint.get());
}
}
#include <Nazara/BulletPhysics3D/DebugOff.hpp>

View File

@ -1,77 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_BULLETPHYSICS3D_BULLETPHYSWORLD3D_HPP
#define NAZARA_BULLETPHYSICS3D_BULLETPHYSWORLD3D_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/BulletPhysics3D/Config.hpp>
#include <Nazara/Core/Time.hpp>
#include <Nazara/Math/Box.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <NazaraUtils/FunctionRef.hpp>
#include <NazaraUtils/MovablePtr.hpp>
#include <optional>
class btDynamicsWorld;
class btRigidBody;
namespace Nz
{
class BulletRigidBody3D;
class NAZARA_BULLETPHYSICS3D_API BulletPhysWorld3D
{
friend BulletRigidBody3D;
public:
struct RaycastHit;
BulletPhysWorld3D();
BulletPhysWorld3D(const BulletPhysWorld3D&) = delete;
BulletPhysWorld3D(BulletPhysWorld3D&& ph) = delete;
~BulletPhysWorld3D();
btDynamicsWorld* GetDynamicsWorld();
Vector3f GetGravity() const;
std::size_t GetMaxStepCount() const;
Time GetStepSize() const;
bool RaycastQuery(const Vector3f& from, const Vector3f& to, const FunctionRef<std::optional<float>(const RaycastHit& hitInfo)>& callback);
bool RaycastQueryFirst(const Vector3f& from, const Vector3f& to, RaycastHit* hitInfo = nullptr);
void SetGravity(const Vector3f& gravity);
void SetMaxStepCount(std::size_t maxStepCount);
void SetStepSize(Time stepSize);
void Step(Time timestep);
BulletPhysWorld3D& operator=(const BulletPhysWorld3D&) = delete;
BulletPhysWorld3D& operator=(BulletPhysWorld3D&&) = delete;
struct RaycastHit
{
float fraction;
BulletRigidBody3D* hitBody = nullptr;
Vector3f hitPosition;
Vector3f hitNormal;
};
private:
btRigidBody* AddRigidBody(std::size_t& rigidBodyIndex, FunctionRef<void(btRigidBody* body)> constructor);
void RemoveRigidBody(btRigidBody* rigidBody, std::size_t rigidBodyIndex);
struct BulletWorld;
std::size_t m_maxStepCount;
std::unique_ptr<BulletWorld> m_world;
Vector3f m_gravity;
Time m_stepSize;
Time m_timestepAccumulator;
};
}
#endif // NAZARA_BULLETPHYSICS3D_BULLETPHYSWORLD3D_HPP

View File

@ -1,33 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_BULLETPHYSICS3D_HPP
#define NAZARA_BULLETPHYSICS3D_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/BulletPhysics3D/Config.hpp>
#include <Nazara/Core/Core.hpp>
namespace Nz
{
class NAZARA_BULLETPHYSICS3D_API BulletPhysics3D : public ModuleBase<BulletPhysics3D>
{
friend ModuleBase;
public:
using Dependencies = TypeList<Core>;
struct Config {};
BulletPhysics3D(Config /*config*/);
~BulletPhysics3D() = default;
private:
static BulletPhysics3D* s_instance;
};
}
#endif // NAZARA_BULLETPHYSICS3D_HPP

View File

@ -1,96 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_BULLETPHYSICS3D_BULLETRIGIDBODY3D_HPP
#define NAZARA_BULLETPHYSICS3D_BULLETRIGIDBODY3D_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/BulletPhysics3D/BulletCollider3D.hpp>
#include <Nazara/BulletPhysics3D/Config.hpp>
#include <Nazara/Core/Enums.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Math/Quaternion.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <NazaraUtils/MovablePtr.hpp>
class btRigidBody;
namespace Nz
{
class BulletPhysWorld3D;
class NAZARA_BULLETPHYSICS3D_API BulletRigidBody3D
{
public:
BulletRigidBody3D(BulletPhysWorld3D* world, const Matrix4f& mat = Matrix4f::Identity());
BulletRigidBody3D(BulletPhysWorld3D* world, std::shared_ptr<BulletCollider3D> geom, const Matrix4f& mat = Matrix4f::Identity());
BulletRigidBody3D(const BulletRigidBody3D& object) = delete;
BulletRigidBody3D(BulletRigidBody3D&& object) noexcept;
~BulletRigidBody3D();
void AddForce(const Vector3f& force, CoordSys coordSys = CoordSys::Global);
void AddForce(const Vector3f& force, const Vector3f& point, CoordSys coordSys = CoordSys::Global);
void AddTorque(const Vector3f& torque, CoordSys coordSys = CoordSys::Global);
inline void DisableSleeping();
void EnableSleeping(bool enable);
void FallAsleep();
Boxf GetAABB() const;
float GetAngularDamping() const;
Vector3f GetAngularVelocity() const;
inline const std::shared_ptr<BulletCollider3D>& GetGeom() const;
float GetLinearDamping() const;
Vector3f GetLinearVelocity() const;
float GetMass() const;
Vector3f GetMassCenter(CoordSys coordSys = CoordSys::Local) const;
Matrix4f GetMatrix() const;
Vector3f GetPosition() const;
inline btRigidBody* GetRigidBody() const;
Quaternionf GetRotation() const;
inline std::size_t GetUniqueIndex() const;
inline BulletPhysWorld3D* GetWorld() const;
bool IsSimulationEnabled() const;
bool IsSleeping() const;
bool IsSleepingEnabled() const;
void SetAngularDamping(float angularDamping);
void SetAngularVelocity(const Vector3f& angularVelocity);
void SetGeom(std::shared_ptr<BulletCollider3D> geom, bool recomputeInertia = true);
void SetLinearDamping(float damping);
void SetLinearVelocity(const Vector3f& velocity);
void SetMass(float mass);
void SetMassCenter(const Vector3f& center);
void SetPosition(const Vector3f& position);
void SetPositionAndRotation(const Vector3f& position, const Quaternionf& rotation);
void SetRotation(const Quaternionf& rotation);
Quaternionf ToLocal(const Quaternionf& worldRotation);
Vector3f ToLocal(const Vector3f& worldPosition);
Quaternionf ToWorld(const Quaternionf& localRotation);
Vector3f ToWorld(const Vector3f& localPosition);
void WakeUp();
BulletRigidBody3D& operator=(const BulletRigidBody3D& object) = delete;
BulletRigidBody3D& operator=(BulletRigidBody3D&& object) noexcept;
protected:
void Destroy();
private:
std::shared_ptr<BulletCollider3D> m_geom;
std::size_t m_bodyPoolIndex;
btRigidBody* m_body;
BulletPhysWorld3D* m_world;
};
}
#include <Nazara/BulletPhysics3D/BulletRigidBody3D.inl>
#endif // NAZARA_BULLETPHYSICS3D_BULLETRIGIDBODY3D_HPP

View File

@ -1,34 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/BulletPhysics3D/Debug.hpp>
namespace Nz
{
inline void BulletRigidBody3D::DisableSleeping()
{
return EnableSleeping(false);
}
inline const std::shared_ptr<BulletCollider3D>& BulletRigidBody3D::GetGeom() const
{
return m_geom;
}
inline btRigidBody* BulletRigidBody3D::GetRigidBody() const
{
return m_body;
}
inline std::size_t BulletRigidBody3D::GetUniqueIndex() const
{
return m_bodyPoolIndex;
}
inline BulletPhysWorld3D* BulletRigidBody3D::GetWorld() const
{
return m_world;
}
}
#include <Nazara/BulletPhysics3D/DebugOff.hpp>

View File

@ -1,34 +0,0 @@
// this file was automatically generated and should not be edited
/*
Nazara Engine - BulletPhysics3D module
Copyright (C) 2024 Jérôme "SirLynix" 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_BULLETPHYSICS3D_COMPONENTS_HPP
#define NAZARA_BULLETPHYSICS3D_COMPONENTS_HPP
#include <Nazara/BulletPhysics3D/Components/BulletRigidBody3DComponent.hpp>
#endif // NAZARA_BULLETPHYSICS3D_COMPONENTS_HPP

View File

@ -1,32 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_BULLETPHYSICS3D_COMPONENTS_BULLETRIGIDBODY3DCOMPONENT_HPP
#define NAZARA_BULLETPHYSICS3D_COMPONENTS_BULLETRIGIDBODY3DCOMPONENT_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/BulletPhysics3D/BulletRigidBody3D.hpp>
namespace Nz
{
class NAZARA_BULLETPHYSICS3D_API BulletRigidBody3DComponent : public BulletRigidBody3D
{
friend class BulletPhysics3DSystem;
public:
using BulletRigidBody3D::BulletRigidBody3D;
BulletRigidBody3DComponent(const BulletRigidBody3DComponent&) = default;
BulletRigidBody3DComponent(BulletRigidBody3DComponent&&) noexcept = default;
~BulletRigidBody3DComponent() = default;
BulletRigidBody3DComponent& operator=(const BulletRigidBody3DComponent&) = default;
BulletRigidBody3DComponent& operator=(BulletRigidBody3DComponent&&) noexcept = default;
};
}
#include <Nazara/BulletPhysics3D/Components/BulletRigidBody3DComponent.inl>
#endif // NAZARA_BULLETPHYSICS3D_COMPONENTS_BULLETRIGIDBODY3DCOMPONENT_HPP

View File

@ -1,11 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/BulletPhysics3D/Debug.hpp>
namespace Nz
{
}
#include <Nazara/BulletPhysics3D/DebugOff.hpp>

View File

@ -1,48 +0,0 @@
/*
Nazara Engine - BulletPhysics3D module
Copyright (C) 2024 Jérôme "SirLynix" 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_BULLETPHYSICS3D_CONFIG_HPP
#define NAZARA_BULLETPHYSICS3D_CONFIG_HPP
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
#define NAZARA_BULLETPHYSICS3D_SAFE 1
/// Vérification des valeurs et types de certaines constantes
#include <Nazara/BulletPhysics3D/ConfigCheck.hpp>
#if defined(NAZARA_STATIC)
#define NAZARA_BULLETPHYSICS3D_API
#else
#ifdef NAZARA_BULLETPHYSICS3D_BUILD
#define NAZARA_BULLETPHYSICS3D_API NAZARA_EXPORT
#else
#define NAZARA_BULLETPHYSICS3D_API NAZARA_IMPORT
#endif
#endif
#endif // NAZARA_BULLETPHYSICS3D_CONFIG_HPP

View File

@ -1,10 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_BULLETPHYSICS3D_CONFIGCHECK_HPP
#define NAZARA_BULLETPHYSICS3D_CONFIGCHECK_HPP
#endif // NAZARA_BULLETPHYSICS3D_CONFIGCHECK_HPP

View File

@ -1,5 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// no header guards

View File

@ -1,5 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// no header guards

View File

@ -1,30 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_BULLETPHYSICS3D_ENUMS_HPP
#define NAZARA_BULLETPHYSICS3D_ENUMS_HPP
namespace Nz
{
enum class BulletColliderType3D
{
Box,
Capsule,
Cone,
Compound,
ConvexHull,
Cylinder,
Heightfield,
Null,
Scene,
Sphere,
StaticPlane,
Max = StaticPlane
};
}
#endif // NAZARA_BULLETPHYSICS3D_ENUMS_HPP

View File

@ -1,34 +0,0 @@
// this file was automatically generated and should not be edited
/*
Nazara Engine - BulletPhysics3D module
Copyright (C) 2024 Jérôme "SirLynix" 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_BULLETPHYSICS3D_SYSTEMS_HPP
#define NAZARA_BULLETPHYSICS3D_SYSTEMS_HPP
#include <Nazara/BulletPhysics3D/Systems/BulletPhysics3DSystem.hpp>
#endif // NAZARA_BULLETPHYSICS3D_SYSTEMS_HPP

View File

@ -1,73 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_BULLETPHYSICS3D_SYSTEMS_BULLETPHYSICS3DSYSTEM_HPP
#define NAZARA_BULLETPHYSICS3D_SYSTEMS_BULLETPHYSICS3DSYSTEM_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/BulletPhysics3D/BulletPhysWorld3D.hpp>
#include <Nazara/BulletPhysics3D/Components/BulletRigidBody3DComponent.hpp>
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Core/Time.hpp>
#include <NazaraUtils/TypeList.hpp>
#include <entt/entt.hpp>
#include <vector>
namespace Nz
{
class NAZARA_BULLETPHYSICS3D_API BulletPhysics3DSystem
{
public:
static constexpr Int64 ExecutionOrder = 0;
using Components = TypeList<BulletRigidBody3DComponent, class NodeComponent>;
struct RaycastHit;
BulletPhysics3DSystem(entt::registry& registry);
BulletPhysics3DSystem(const BulletPhysics3DSystem&) = delete;
BulletPhysics3DSystem(BulletPhysics3DSystem&&) = delete;
~BulletPhysics3DSystem();
template<typename... Args> BulletRigidBody3DComponent CreateRigidBody(Args&&... args);
void Dump();
inline BulletPhysWorld3D& GetPhysWorld();
inline const BulletPhysWorld3D& GetPhysWorld() const;
bool RaycastQuery(const Vector3f& from, const Vector3f& to, const FunctionRef<std::optional<float>(const RaycastHit& hitInfo)>& callback);
bool RaycastQueryFirst(const Vector3f& from, const Vector3f& to, RaycastHit* hitInfo = nullptr);
void Update(Time elapsedTime);
BulletPhysics3DSystem& operator=(const BulletPhysics3DSystem&) = delete;
BulletPhysics3DSystem& operator=(BulletPhysics3DSystem&&) = delete;
struct RaycastHit : BulletPhysWorld3D::RaycastHit
{
entt::handle hitEntity;
};
private:
void OnConstruct(entt::registry& registry, entt::entity entity);
void OnDestruct(entt::registry& registry, entt::entity entity);
std::size_t m_activeObjectCount;
std::size_t m_stepCount;
std::vector<entt::entity> m_physicsEntities;
entt::registry& m_registry;
entt::observer m_physicsConstructObserver;
entt::scoped_connection m_constructConnection;
entt::scoped_connection m_destructConnection;
BulletPhysWorld3D m_physWorld;
Time m_physicsTime;
Time m_updateTime;
};
}
#include <Nazara/BulletPhysics3D/Systems/BulletPhysics3DSystem.inl>
#endif // NAZARA_BULLETPHYSICS3D_SYSTEMS_BULLETPHYSICS3DSYSTEM_HPP

View File

@ -1,26 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/BulletPhysics3D/Debug.hpp>
namespace Nz
{
template<typename... Args>
BulletRigidBody3DComponent BulletPhysics3DSystem::CreateRigidBody(Args&&... args)
{
return BulletRigidBody3DComponent(&m_physWorld, std::forward<Args>(args)...);
}
inline BulletPhysWorld3D& BulletPhysics3DSystem::GetPhysWorld()
{
return m_physWorld;
}
inline const BulletPhysWorld3D& BulletPhysics3DSystem::GetPhysWorld() const
{
return m_physWorld;
}
}
#include <Nazara/BulletPhysics3D/DebugOff.hpp>

View File

@ -1,470 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/BulletPhysics3D/BulletCollider3D.hpp>
#include <Nazara/BulletPhysics3D/BulletHelper.hpp>
#include <Nazara/Core/PrimitiveList.hpp>
#include <Nazara/Utility/Algorithm.hpp>
#include <Nazara/Utility/IndexBuffer.hpp>
#include <Nazara/Utility/SoftwareBuffer.hpp>
#include <Nazara/Utility/StaticMesh.hpp>
#include <Nazara/Utility/VertexBuffer.hpp>
#include <NazaraUtils/MemoryHelper.hpp>
#include <BulletCollision/CollisionShapes/btBoxShape.h>
#include <BulletCollision/CollisionShapes/btCapsuleShape.h>
#include <BulletCollision/CollisionShapes/btCompoundShape.h>
#include <BulletCollision/CollisionShapes/btConeShape.h>
#include <BulletCollision/CollisionShapes/btConvexHullShape.h>
#include <BulletCollision/CollisionShapes/btCylinderShape.h>
#include <BulletCollision/CollisionShapes/btEmptyShape.h>
#include <BulletCollision/CollisionShapes/btSphereShape.h>
#include <BulletCollision/CollisionShapes/btStaticPlaneShape.h>
#include <unordered_map>
#include <Nazara/BulletPhysics3D/Debug.hpp>
namespace Nz
{
BulletCollider3D::~BulletCollider3D() = default;
Boxf BulletCollider3D::ComputeAABB(const Vector3f& translation, const Quaternionf& rotation, const Vector3f& scale) const
{
return ComputeAABB(Matrix4f::Transform(translation, rotation), scale);
}
Boxf BulletCollider3D::ComputeAABB(const Matrix4f& offsetMatrix, const Vector3f& scale) const
{
btTransform transform = ToBullet(offsetMatrix);
btVector3 min, max;
GetShape()->getAabb(transform, min, max);
return Boxf(scale * FromBullet(min), scale * FromBullet(max));
}
void BulletCollider3D::ComputeInertia(float mass, Vector3f* inertia) const
{
NazaraAssert(inertia, "invalid inertia pointer");
btVector3 inertiaVec;
GetShape()->calculateLocalInertia(mass, inertiaVec);
*inertia = FromBullet(inertiaVec);
}
std::shared_ptr<StaticMesh> BulletCollider3D::GenerateDebugMesh() const
{
std::vector<Vector3f> colliderVertices;
std::vector<UInt16> colliderIndices;
BuildDebugMesh(colliderVertices, colliderIndices);
std::shared_ptr<VertexBuffer> colliderVB = std::make_shared<VertexBuffer>(VertexDeclaration::Get(VertexLayout::XYZ), SafeCast<UInt32>(colliderVertices.size()), BufferUsage::Write, SoftwareBufferFactory, colliderVertices.data());
std::shared_ptr<IndexBuffer> colliderIB = std::make_shared<IndexBuffer>(IndexType::U16, SafeCast<UInt32>(colliderIndices.size()), BufferUsage::Write, SoftwareBufferFactory, colliderIndices.data());
std::shared_ptr<StaticMesh> colliderSubMesh = std::make_shared<StaticMesh>(std::move(colliderVB), std::move(colliderIB));
colliderSubMesh->GenerateAABB();
colliderSubMesh->SetPrimitiveMode(PrimitiveMode::LineList);
return colliderSubMesh;
}
std::shared_ptr<BulletCollider3D> BulletCollider3D::Build(const PrimitiveList& list)
{
std::size_t primitiveCount = list.GetSize();
if (primitiveCount > 1)
{
std::vector<BulletCompoundCollider3D::ChildCollider> childColliders(primitiveCount);
for (unsigned int i = 0; i < primitiveCount; ++i)
{
const Primitive& primitive = list.GetPrimitive(i);
childColliders[i].collider = CreateGeomFromPrimitive(primitive);
childColliders[i].offsetMatrix = primitive.matrix;
}
return std::make_shared<BulletCompoundCollider3D>(std::move(childColliders));
}
else if (primitiveCount > 0)
return CreateGeomFromPrimitive(list.GetPrimitive(0));
else
return std::make_shared<BulletNullCollider3D>();
}
std::shared_ptr<BulletCollider3D> BulletCollider3D::CreateGeomFromPrimitive(const Primitive& primitive)
{
switch (primitive.type)
{
case PrimitiveType::Box:
return std::make_shared<BulletBoxCollider3D>(primitive.box.lengths);
case PrimitiveType::Cone:
return std::make_shared<BulletConeCollider3D>(primitive.cone.length, primitive.cone.radius);
case PrimitiveType::Plane:
return std::make_shared<BulletBoxCollider3D>(Vector3f(primitive.plane.size.x, 0.01f, primitive.plane.size.y));
///TODO: PlaneGeom?
case PrimitiveType::Sphere:
return std::make_shared<BulletSphereCollider3D>(primitive.sphere.size);
}
NazaraErrorFmt("Primitive type not handled ({0:#x})", UnderlyingCast(primitive.type));
return std::shared_ptr<BulletCollider3D>();
}
/********************************** BoxCollider3D **********************************/
BulletBoxCollider3D::BulletBoxCollider3D(const Vector3f& lengths) :
m_lengths(lengths)
{
m_shape = std::make_unique<btBoxShape>(ToBullet(m_lengths * 0.5f));
}
BulletBoxCollider3D::~BulletBoxCollider3D() = default;
void BulletBoxCollider3D::BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const
{
auto InsertVertex = [&](float x, float y, float z) -> UInt16
{
UInt16 index = SafeCast<UInt16>(vertices.size());
vertices.push_back(offsetMatrix * Vector3f(x, y, z));
return index;
};
Vector3f halfLengths = m_lengths * 0.5f;
UInt16 v0 = InsertVertex(-halfLengths.x, -halfLengths.y, -halfLengths.z);
UInt16 v1 = InsertVertex(halfLengths.x, -halfLengths.y, -halfLengths.z);
UInt16 v2 = InsertVertex(halfLengths.x, -halfLengths.y, halfLengths.z);
UInt16 v3 = InsertVertex(-halfLengths.x, -halfLengths.y, halfLengths.z);
UInt16 v4 = InsertVertex(-halfLengths.x, halfLengths.y, -halfLengths.z);
UInt16 v5 = InsertVertex(halfLengths.x, halfLengths.y, -halfLengths.z);
UInt16 v6 = InsertVertex(halfLengths.x, halfLengths.y, halfLengths.z);
UInt16 v7 = InsertVertex(-halfLengths.x, halfLengths.y, halfLengths.z);
auto InsertEdge = [&](UInt16 from, UInt16 to)
{
indices.push_back(from);
indices.push_back(to);
};
InsertEdge(v0, v1);
InsertEdge(v1, v2);
InsertEdge(v2, v3);
InsertEdge(v3, v0);
InsertEdge(v4, v5);
InsertEdge(v5, v6);
InsertEdge(v6, v7);
InsertEdge(v7, v4);
InsertEdge(v0, v4);
InsertEdge(v1, v5);
InsertEdge(v2, v6);
InsertEdge(v3, v7);
}
btCollisionShape* BulletBoxCollider3D::GetShape() const
{
return m_shape.get();
}
Vector3f BulletBoxCollider3D::GetLengths() const
{
return m_lengths;
}
BulletColliderType3D BulletBoxCollider3D::GetType() const
{
return BulletColliderType3D::Box;
}
/******************************** CapsuleCollider3D ********************************/
BulletCapsuleCollider3D::BulletCapsuleCollider3D(float length, float radius) :
m_length(length),
m_radius(radius)
{
m_shape = std::make_unique<btCapsuleShape>(radius, length);
}
BulletCapsuleCollider3D::~BulletCapsuleCollider3D() = default;
void BulletCapsuleCollider3D::BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const
{
}
float BulletCapsuleCollider3D::GetLength() const
{
return m_length;
}
float BulletCapsuleCollider3D::GetRadius() const
{
return m_radius;
}
btCollisionShape* BulletCapsuleCollider3D::GetShape() const
{
return m_shape.get();
}
BulletColliderType3D BulletCapsuleCollider3D::GetType() const
{
return BulletColliderType3D::Capsule;
}
/******************************* CompoundCollider3D ********************************/
BulletCompoundCollider3D::BulletCompoundCollider3D(std::vector<ChildCollider> childs) :
m_childs(std::move(childs))
{
m_shape = std::make_unique<btCompoundShape>();
for (const auto& child : m_childs)
{
btTransform transform = ToBullet(child.offsetMatrix);
m_shape->addChildShape(transform, child.collider->GetShape());
}
}
BulletCompoundCollider3D::~BulletCompoundCollider3D() = default;
void BulletCompoundCollider3D::BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const
{
for (const auto& child : m_childs)
child.collider->BuildDebugMesh(vertices, indices, offsetMatrix * child.offsetMatrix);
}
auto BulletCompoundCollider3D::GetGeoms() const -> const std::vector<ChildCollider>&
{
return m_childs;
}
btCollisionShape* BulletCompoundCollider3D::GetShape() const
{
return m_shape.get();
}
BulletColliderType3D BulletCompoundCollider3D::GetType() const
{
return BulletColliderType3D::Compound;
}
/********************************* ConeCollider3D **********************************/
BulletConeCollider3D::BulletConeCollider3D(float length, float radius) :
m_length(length),
m_radius(radius)
{
m_shape = std::make_unique<btConeShape>(radius, length);
}
BulletConeCollider3D::~BulletConeCollider3D() = default;
void BulletConeCollider3D::BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const
{
}
float BulletConeCollider3D::GetLength() const
{
return m_length;
}
float BulletConeCollider3D::GetRadius() const
{
return m_radius;
}
btCollisionShape* BulletConeCollider3D::GetShape() const
{
return m_shape.get();
}
BulletColliderType3D BulletConeCollider3D::GetType() const
{
return BulletColliderType3D::Cone;
}
/****************************** ConvexCollider3D *******************************/
BulletConvexCollider3D::BulletConvexCollider3D(SparsePtr<const Vector3f> vertices, unsigned int vertexCount)
{
static_assert(std::is_same_v<btScalar, float>);
m_shape = std::make_unique<btConvexHullShape>(reinterpret_cast<const float*>(vertices.GetPtr()), vertexCount, vertices.GetStride());
m_shape->optimizeConvexHull();
}
BulletConvexCollider3D::~BulletConvexCollider3D() = default;
void BulletConvexCollider3D::BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const
{
std::unordered_map<Vector3f, UInt16> vertexCache;
auto InsertVertex = [&](const Vector3f& position) -> UInt16
{
auto it = vertexCache.find(position);
if (it != vertexCache.end())
return it->second;
UInt16 index = SafeCast<UInt16>(vertices.size());
vertices.push_back(offsetMatrix * position);
vertexCache.emplace(position, index);
return index;
};
int edgeCount = m_shape->getNumEdges();
for (int i = 0; i < edgeCount; ++i)
{
btVector3 from, to;
m_shape->getEdge(i, from, to);
indices.push_back(InsertVertex(FromBullet(from)));
indices.push_back(InsertVertex(FromBullet(to)));
}
}
btCollisionShape* BulletConvexCollider3D::GetShape() const
{
return m_shape.get();
}
BulletColliderType3D BulletConvexCollider3D::GetType() const
{
return BulletColliderType3D::ConvexHull;
}
/******************************* CylinderCollider3D ********************************/
BulletCylinderCollider3D::BulletCylinderCollider3D(float length, float radius) :
m_length(length),
m_radius(radius)
{
// TODO: Allow to use two different radius
m_shape = std::make_unique<btCylinderShape>(btVector3{ radius, length, radius });
}
BulletCylinderCollider3D::~BulletCylinderCollider3D() = default;
void BulletCylinderCollider3D::BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const
{
}
float BulletCylinderCollider3D::GetLength() const
{
return m_length;
}
float BulletCylinderCollider3D::GetRadius() const
{
return m_radius;
}
btCollisionShape* BulletCylinderCollider3D::GetShape() const
{
return m_shape.get();
}
BulletColliderType3D BulletCylinderCollider3D::GetType() const
{
return BulletColliderType3D::Cylinder;
}
/********************************* NullCollider3D **********************************/
BulletNullCollider3D::BulletNullCollider3D()
{
m_shape = std::make_unique<btEmptyShape>();
}
BulletNullCollider3D::~BulletNullCollider3D() = default;
void BulletNullCollider3D::BuildDebugMesh(std::vector<Vector3f>& /*vertices*/, std::vector<UInt16>& /*indices*/, const Matrix4f& /*offsetMatrix*/) const
{
}
void BulletNullCollider3D::ComputeInertia(float /*mass*/, Vector3f* inertia) const
{
*inertia = Vector3f::Unit();
}
btCollisionShape* BulletNullCollider3D::GetShape() const
{
return m_shape.get();
}
BulletColliderType3D BulletNullCollider3D::GetType() const
{
return BulletColliderType3D::Null;
}
/******************************** SphereCollider3D *********************************/
BulletSphereCollider3D::BulletSphereCollider3D(float radius) :
m_radius(radius)
{
m_shape = std::make_unique<btSphereShape>(radius);
}
BulletSphereCollider3D::~BulletSphereCollider3D() = default;
void BulletSphereCollider3D::BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const
{
}
float BulletSphereCollider3D::GetRadius() const
{
return m_radius;
}
btCollisionShape* BulletSphereCollider3D::GetShape() const
{
return m_shape.get();
}
BulletColliderType3D BulletSphereCollider3D::GetType() const
{
return BulletColliderType3D::Sphere;
}
/******************************** StaticPlaneCollider3D *********************************/
BulletStaticPlaneCollider3D::BulletStaticPlaneCollider3D(const Planef& plane) :
BulletStaticPlaneCollider3D(plane.normal, plane.distance)
{
}
BulletStaticPlaneCollider3D::BulletStaticPlaneCollider3D(const Vector3f& normal, float distance) :
m_normal(normal),
m_distance(distance)
{
m_shape = std::make_unique<btStaticPlaneShape>(ToBullet(m_normal), m_distance);
}
BulletStaticPlaneCollider3D::~BulletStaticPlaneCollider3D() = default;
void BulletStaticPlaneCollider3D::BuildDebugMesh(std::vector<Vector3f>& vertices, std::vector<UInt16>& indices, const Matrix4f& offsetMatrix) const
{
}
float BulletStaticPlaneCollider3D::GetDistance() const
{
return m_distance;
}
const Vector3f& BulletStaticPlaneCollider3D::GetNormal() const
{
return m_normal;
}
btCollisionShape* BulletStaticPlaneCollider3D::GetShape() const
{
return m_shape.get();
}
BulletColliderType3D BulletStaticPlaneCollider3D::GetType() const
{
return BulletColliderType3D::StaticPlane;
}
}

View File

@ -1,152 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/BulletPhysics3D/BulletConstraint3D.hpp>
#include <Nazara/BulletPhysics3D/BulletHelper.hpp>
#include <BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h>
#include <BulletDynamics/Dynamics/btDynamicsWorld.h>
#include <Nazara/BulletPhysics3D/Debug.hpp>
namespace Nz
{
BulletConstraint3D::BulletConstraint3D(std::unique_ptr<btTypedConstraint> constraint, bool disableCollisions) :
m_constraint(std::move(constraint)),
m_bodyCollisionEnabled(!disableCollisions)
{
m_constraint->setUserConstraintPtr(this);
btDynamicsWorld* world = GetWorld().GetDynamicsWorld();
world->addConstraint(m_constraint.get(), disableCollisions);
}
BulletConstraint3D::BulletConstraint3D(BulletConstraint3D&& constraint) noexcept :
m_constraint(std::move(constraint.m_constraint)),
m_bodyCollisionEnabled(constraint.m_bodyCollisionEnabled)
{
if (m_constraint)
m_constraint->setUserConstraintPtr(this);
}
BulletConstraint3D::~BulletConstraint3D()
{
Destroy();
}
BulletRigidBody3D& BulletConstraint3D::GetBodyA()
{
return *static_cast<BulletRigidBody3D*>(m_constraint->getRigidBodyA().getUserPointer());
}
const BulletRigidBody3D& BulletConstraint3D::GetBodyA() const
{
return *static_cast<BulletRigidBody3D*>(m_constraint->getRigidBodyA().getUserPointer());
}
BulletRigidBody3D& BulletConstraint3D::GetBodyB()
{
NazaraAssert(!IsSingleBody(), "constraint is not attached to a second body");
return *static_cast<BulletRigidBody3D*>(m_constraint->getRigidBodyB().getUserPointer());
}
const BulletRigidBody3D& BulletConstraint3D::GetBodyB() const
{
NazaraAssert(!IsSingleBody(), "constraint is not attached to a second body");
return *static_cast<BulletRigidBody3D*>(m_constraint->getRigidBodyB().getUserPointer());
}
BulletPhysWorld3D& BulletConstraint3D::GetWorld()
{
return *GetBodyA().GetWorld();
}
const BulletPhysWorld3D& BulletConstraint3D::GetWorld() const
{
return *GetBodyA().GetWorld();
}
bool BulletConstraint3D::IsSingleBody() const
{
return &m_constraint->getRigidBodyB() == &btTypedConstraint::getFixedBody();
}
BulletConstraint3D& BulletConstraint3D::operator=(BulletConstraint3D&& constraint) noexcept
{
Destroy();
m_constraint = std::move(constraint.m_constraint);
m_bodyCollisionEnabled = constraint.m_bodyCollisionEnabled;
if (m_constraint)
m_constraint->setUserConstraintPtr(this);
return *this;
}
void BulletConstraint3D::Destroy()
{
if (m_constraint)
{
btDynamicsWorld* world = GetWorld().GetDynamicsWorld();
world->removeConstraint(m_constraint.get());
m_constraint.reset();
}
}
BulletPivotConstraint3D::BulletPivotConstraint3D(BulletRigidBody3D& first, const Vector3f& pivot) :
BulletConstraint3D(std::make_unique<btPoint2PointConstraint>(*first.GetRigidBody(), ToBullet(first.ToLocal(pivot))))
{
}
BulletPivotConstraint3D::BulletPivotConstraint3D(BulletRigidBody3D& first, BulletRigidBody3D& second, const Vector3f& pivot, bool disableCollisions) :
BulletConstraint3D(std::make_unique<btPoint2PointConstraint>(*first.GetRigidBody(), *second.GetRigidBody(), ToBullet(first.ToLocal(pivot)), ToBullet(second.ToLocal(pivot))), disableCollisions)
{
}
BulletPivotConstraint3D::BulletPivotConstraint3D(BulletRigidBody3D& first, BulletRigidBody3D& second, const Vector3f& firstAnchor, const Vector3f& secondAnchor, bool disableCollisions) :
BulletConstraint3D(std::make_unique<btPoint2PointConstraint>(*first.GetRigidBody(), *second.GetRigidBody(), ToBullet(firstAnchor), ToBullet(secondAnchor)), disableCollisions)
{
}
Vector3f BulletPivotConstraint3D::GetFirstAnchor() const
{
return FromBullet(GetConstraint<btPoint2PointConstraint>()->getPivotInA());
}
Vector3f BulletPivotConstraint3D::GetSecondAnchor() const
{
return FromBullet(GetConstraint<btPoint2PointConstraint>()->getPivotInB());
}
float BulletPivotConstraint3D::GetDamping() const
{
return GetConstraint<btPoint2PointConstraint>()->m_setting.m_damping;
}
float BulletPivotConstraint3D::GetImpulseClamp() const
{
return GetConstraint<btPoint2PointConstraint>()->m_setting.m_impulseClamp;
}
void BulletPivotConstraint3D::SetFirstAnchor(const Vector3f& firstAnchor)
{
GetConstraint<btPoint2PointConstraint>()->setPivotA(ToBullet(firstAnchor));
}
void BulletPivotConstraint3D::SetSecondAnchor(const Vector3f& secondAnchor)
{
GetConstraint<btPoint2PointConstraint>()->setPivotB(ToBullet(secondAnchor));
}
void BulletPivotConstraint3D::SetDamping(float damping)
{
GetConstraint<btPoint2PointConstraint>()->m_setting.m_damping = damping;
}
void BulletPivotConstraint3D::SetImpulseClamp(float impulseClamp)
{
GetConstraint<btPoint2PointConstraint>()->m_setting.m_impulseClamp = impulseClamp;
}
}

View File

@ -1,32 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_BULLETPHYSICS3D_BULLETHELPER_HPP
#define NAZARA_BULLETPHYSICS3D_BULLETHELPER_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/BulletPhysics3D/Config.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Math/Quaternion.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <LinearMath/btQuaternion.h>
#include <LinearMath/btTransform.h>
#include <LinearMath/btVector3.h>
namespace Nz
{
inline Quaternionf FromBullet(const btQuaternion& quat);
inline Matrix4f FromBullet(const btTransform& transform);
inline Vector3f FromBullet(const btVector3& vec);
inline btTransform ToBullet(const Matrix4f& transformMatrix);
inline btQuaternion ToBullet(const Quaternionf& rotation);
inline btVector3 ToBullet(const Vector3f& vec);
}
#include <Nazara/BulletPhysics3D/BulletHelper.inl>
#endif // NAZARA_BULLETPHYSICS3D_BULLETHELPER_HPP

View File

@ -1,60 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/BulletPhysics3D/Debug.hpp>
namespace Nz
{
Quaternionf FromBullet(const btQuaternion& quat)
{
return Quaternionf(quat.w(), quat.x(), quat.y(), quat.z());
}
Matrix4f FromBullet(const btTransform& transform)
{
const btMatrix3x3& basisMatrix = transform.getBasis();
const btVector3& origin = transform.getOrigin();
const btVector3& row1 = basisMatrix.getRow(0);
const btVector3& row2 = basisMatrix.getRow(1);
const btVector3& row3 = basisMatrix.getRow(2);
return Matrix4f(
row1.x(), row1.y(), row1.z(), 0.f,
row2.x(), row2.y(), row2.z(), 0.f,
row3.x(), row3.y(), row3.z(), 0.f,
origin.x(), origin.y(), origin.z(), 1.f);
}
inline Vector3f FromBullet(const btVector3& vec)
{
return Vector3f(vec.x(), vec.y(), vec.z());
}
btTransform ToBullet(const Matrix4f& transformMatrix)
{
btTransform transform;
transform.setBasis(btMatrix3x3(
transformMatrix.m11, transformMatrix.m12, transformMatrix.m13,
transformMatrix.m21, transformMatrix.m22, transformMatrix.m23,
transformMatrix.m31, transformMatrix.m32, transformMatrix.m33
));
transform.setOrigin(btVector3(transformMatrix.m41, transformMatrix.m42, transformMatrix.m43));
return transform;
}
btQuaternion ToBullet(const Quaternionf& rotation)
{
return btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w);
}
inline btVector3 ToBullet(const Vector3f& vec)
{
return btVector3(vec.x, vec.y, vec.z);
}
}
#include <Nazara/BulletPhysics3D/DebugOff.hpp>

View File

@ -1,215 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/BulletPhysics3D/BulletPhysWorld3D.hpp>
#include <Nazara/BulletPhysics3D/BulletHelper.hpp>
#include <NazaraUtils/MemoryPool.hpp>
#include <NazaraUtils/StackVector.hpp>
#include <BulletCollision/BroadphaseCollision/btDbvtBroadphase.h>
#include <BulletCollision/CollisionDispatch/btCollisionDispatcher.h>
#include <BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h>
#include <BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h>
#include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
#include <cassert>
#include <Nazara/BulletPhysics3D/Debug.hpp>
namespace Nz
{
namespace NAZARA_ANONYMOUS_NAMESPACE
{
class CallbackHitResult : public btCollisionWorld::RayResultCallback
{
public:
CallbackHitResult(const Vector3f& from, const Vector3f& to, const FunctionRef<std::optional<float>(const BulletPhysWorld3D::RaycastHit& hitInfo)>& callback) :
m_callback(callback),
m_from(from),
m_to(to)
{
}
btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) override
{
m_collisionObject = rayResult.m_collisionObject;
BulletPhysWorld3D::RaycastHit hitInfo;
hitInfo.fraction = rayResult.m_hitFraction;
hitInfo.hitPosition = Lerp(m_from, m_to, rayResult.m_hitFraction);
hitInfo.hitNormal = FromBullet((normalInWorldSpace) ? rayResult.m_hitNormalLocal : m_collisionObject->getWorldTransform().getBasis() * rayResult.m_hitNormalLocal);
if (const btRigidBody* body = btRigidBody::upcast(m_collisionObject))
hitInfo.hitBody = static_cast<BulletRigidBody3D*>(body->getUserPointer());
m_closestHitFraction = std::max(m_callback(hitInfo).value_or(m_closestHitFraction), 0.f);
return m_closestHitFraction;
}
private:
const FunctionRef<std::optional<float>(const BulletPhysWorld3D::RaycastHit& hitInfo)>& m_callback;
Vector3f m_from;
Vector3f m_to;
};
}
struct BulletPhysWorld3D::BulletWorld
{
btDefaultCollisionConfiguration collisionConfiguration;
btCollisionDispatcher dispatcher;
btDbvtBroadphase broadphase;
btSequentialImpulseConstraintSolver constraintSolver;
btDiscreteDynamicsWorld dynamicWorld;
MemoryPool<btRigidBody> rigidBodyPool;
BulletWorld() :
dispatcher(&collisionConfiguration),
dynamicWorld(&dispatcher, &broadphase, &constraintSolver, &collisionConfiguration),
rigidBodyPool(256)
{
}
BulletWorld(const BulletWorld&) = delete;
BulletWorld(BulletWorld&&) = delete;
BulletWorld& operator=(const BulletWorld&) = delete;
BulletWorld& operator=(BulletWorld&&) = delete;
};
BulletPhysWorld3D::BulletPhysWorld3D() :
m_maxStepCount(50),
m_gravity(Vector3f::Zero()),
m_stepSize(Time::TickDuration(120)),
m_timestepAccumulator(Time::Zero())
{
m_world = std::make_unique<BulletWorld>();
}
BulletPhysWorld3D::~BulletPhysWorld3D() = default;
btDynamicsWorld* BulletPhysWorld3D::GetDynamicsWorld()
{
return &m_world->dynamicWorld;
}
Vector3f BulletPhysWorld3D::GetGravity() const
{
return FromBullet(m_world->dynamicWorld.getGravity());
}
std::size_t BulletPhysWorld3D::GetMaxStepCount() const
{
return m_maxStepCount;
}
Time BulletPhysWorld3D::GetStepSize() const
{
return m_stepSize;
}
bool BulletPhysWorld3D::RaycastQuery(const Vector3f& from, const Vector3f& to, const FunctionRef<std::optional<float>(const RaycastHit& hitInfo)>& callback)
{
NAZARA_USE_ANONYMOUS_NAMESPACE
CallbackHitResult resultHandler(from, to, callback);
m_world->dynamicWorld.rayTest(ToBullet(from), ToBullet(to), resultHandler);
return resultHandler.hasHit();
}
bool BulletPhysWorld3D::RaycastQueryFirst(const Vector3f& from, const Vector3f& to, RaycastHit* hitInfo)
{
btCollisionWorld::ClosestRayResultCallback resultHandler(ToBullet(from), ToBullet(to));
m_world->dynamicWorld.rayTest(ToBullet(from), ToBullet(to), resultHandler);
if (!resultHandler.hasHit())
return false;
if (hitInfo)
{
hitInfo->fraction = resultHandler.m_closestHitFraction;
hitInfo->hitNormal = FromBullet(resultHandler.m_hitNormalWorld);
hitInfo->hitPosition = FromBullet(resultHandler.m_hitPointWorld);
if (const btRigidBody* body = btRigidBody::upcast(resultHandler.m_collisionObject))
hitInfo->hitBody = static_cast<BulletRigidBody3D*>(body->getUserPointer());
}
return true;
}
void BulletPhysWorld3D::SetGravity(const Vector3f& gravity)
{
m_world->dynamicWorld.setGravity(ToBullet(gravity));
}
void BulletPhysWorld3D::SetMaxStepCount(std::size_t maxStepCount)
{
m_maxStepCount = maxStepCount;
}
void BulletPhysWorld3D::SetStepSize(Time stepSize)
{
m_stepSize = stepSize;
}
void BulletPhysWorld3D::Step(Time timestep)
{
m_timestepAccumulator += timestep;
btScalar stepSize = m_stepSize.AsSeconds<btScalar>();
std::size_t stepCount = 0;
while (m_timestepAccumulator >= m_stepSize && stepCount < m_maxStepCount)
{
m_world->dynamicWorld.stepSimulation(stepSize, 0, stepSize);
m_timestepAccumulator -= m_stepSize;
stepCount++;
}
}
#define HACK 0
btRigidBody* BulletPhysWorld3D::AddRigidBody(std::size_t& rigidBodyIndex, FunctionRef<void(btRigidBody* body)> constructor)
{
#if HACK
static std::size_t index = 0;
rigidBodyIndex = index++;
btRigidBody* rigidBody = (btRigidBody*) ::operator new(sizeof(btRigidBody));
constructor(rigidBody);
m_world->dynamicWorld.addRigidBody(rigidBody);
#else
btRigidBody* rigidBody = m_world->rigidBodyPool.Allocate(m_world->rigidBodyPool.DeferConstruct, rigidBodyIndex);
constructor(rigidBody);
m_world->dynamicWorld.addRigidBody(rigidBody);
// Small hack to order rigid bodies to make it cache friendly
auto& rigidBodies = m_world->dynamicWorld.getNonStaticRigidBodies();
if (rigidBodies.size() >= 2 && rigidBodies[rigidBodies.size() - 1] == rigidBody)
{
// Sort rigid bodies
btRigidBody** startPtr = &rigidBodies[0];
btRigidBody** endPtr = startPtr + rigidBodies.size();
btRigidBody** lastPtr = endPtr - 1;
auto it = std::lower_bound(startPtr, endPtr, rigidBody);
if (it != lastPtr)
{
std::move_backward(it, lastPtr, endPtr);
*it = rigidBody;
}
}
#endif
return rigidBody;
}
void BulletPhysWorld3D::RemoveRigidBody(btRigidBody* rigidBody, std::size_t rigidBodyIndex)
{
// TODO: Improve deletion (since rigid bodies are sorted)
m_world->dynamicWorld.removeRigidBody(rigidBody); //< this does a linear search
#if HACK
::operator delete(rigidBody);
#else
m_world->rigidBodyPool.Free(rigidBodyIndex);
#endif
}
}

View File

@ -1,21 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/BulletPhysics3D/BulletPhysics3D.hpp>
#include <Nazara/BulletPhysics3D/BulletCollider3D.hpp>
#include <Nazara/BulletPhysics3D/Config.hpp>
#include <Nazara/Core/Core.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/BulletPhysics3D/Debug.hpp>
namespace Nz
{
BulletPhysics3D::BulletPhysics3D(Config /*config*/) :
ModuleBase("BulletPhysics3D", this)
{
}
BulletPhysics3D* BulletPhysics3D::s_instance;
}

View File

@ -1,339 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/BulletPhysics3D/BulletRigidBody3D.hpp>
#include <Nazara/BulletPhysics3D/BulletHelper.hpp>
#include <Nazara/BulletPhysics3D/BulletPhysWorld3D.hpp>
#include <NazaraUtils/MemoryHelper.hpp>
#include <BulletDynamics/Dynamics/btDynamicsWorld.h>
#include <BulletDynamics/Dynamics/btRigidBody.h>
#include <algorithm>
#include <array>
#include <cmath>
#include <Nazara/BulletPhysics3D/Debug.hpp>
namespace Nz
{
BulletRigidBody3D::BulletRigidBody3D(BulletPhysWorld3D* world, const Matrix4f& mat) :
BulletRigidBody3D(world, nullptr, mat)
{
}
BulletRigidBody3D::BulletRigidBody3D(BulletPhysWorld3D* world, std::shared_ptr<BulletCollider3D> geom, const Matrix4f& mat) :
m_geom(std::move(geom)),
m_world(world)
{
NazaraAssert(m_world, "Invalid world");
if (!m_geom)
m_geom = std::make_shared<BulletNullCollider3D>();
Vector3f inertia;
m_geom->ComputeInertia(1.f, &inertia);
btRigidBody::btRigidBodyConstructionInfo constructionInfo(1.f, nullptr, m_geom->GetShape(), ToBullet(inertia));
constructionInfo.m_startWorldTransform = ToBullet(mat);
m_body = m_world->AddRigidBody(m_bodyPoolIndex, [&](btRigidBody* body)
{
PlacementNew(body, constructionInfo);
});
m_body->setUserPointer(this);
}
BulletRigidBody3D::BulletRigidBody3D(BulletRigidBody3D&& object) noexcept :
m_geom(std::move(object.m_geom)),
m_bodyPoolIndex(object.m_bodyPoolIndex),
m_body(object.m_body),
m_world(object.m_world)
{
if (m_body)
m_body->setUserPointer(this);
object.m_body = nullptr;
}
BulletRigidBody3D::~BulletRigidBody3D()
{
Destroy();
}
void BulletRigidBody3D::AddForce(const Vector3f& force, CoordSys coordSys)
{
switch (coordSys)
{
case CoordSys::Global:
WakeUp();
m_body->applyCentralForce(ToBullet(force));
break;
case CoordSys::Local:
WakeUp();
m_body->applyCentralForce(ToBullet(GetRotation() * force));
break;
}
}
void BulletRigidBody3D::AddForce(const Vector3f& force, const Vector3f& point, CoordSys coordSys)
{
switch (coordSys)
{
case CoordSys::Global:
WakeUp();
m_body->applyForce(ToBullet(force), ToBullet(point));
break;
case CoordSys::Local:
{
Matrix4f transformMatrix = GetMatrix();
return AddForce(transformMatrix.Transform(force, 0.f), point, CoordSys::Global);
}
}
}
void BulletRigidBody3D::AddTorque(const Vector3f& torque, CoordSys coordSys)
{
switch (coordSys)
{
case CoordSys::Global:
WakeUp();
m_body->applyTorque(ToBullet(torque));
break;
case CoordSys::Local:
Matrix4f transformMatrix = GetMatrix();
WakeUp();
m_body->applyTorque(ToBullet(transformMatrix.Transform(torque, 0.f)));
break;
}
}
void BulletRigidBody3D::EnableSleeping(bool enable)
{
if (enable)
{
if (m_body->getActivationState() == DISABLE_DEACTIVATION)
m_body->setActivationState(ACTIVE_TAG);
}
else
{
if (m_body->getActivationState() != DISABLE_DEACTIVATION)
m_body->setActivationState(DISABLE_DEACTIVATION);
}
}
void BulletRigidBody3D::FallAsleep()
{
if (m_body->getActivationState() != DISABLE_DEACTIVATION)
m_body->setActivationState(ISLAND_SLEEPING);
}
Boxf BulletRigidBody3D::GetAABB() const
{
btVector3 min, max;
m_body->getAabb(min, max);
return Boxf(FromBullet(min), FromBullet(max));
}
float BulletRigidBody3D::GetAngularDamping() const
{
return m_body->getAngularDamping();
}
Vector3f BulletRigidBody3D::GetAngularVelocity() const
{
return FromBullet(m_body->getAngularVelocity());
}
float BulletRigidBody3D::GetLinearDamping() const
{
return m_body->getLinearDamping();
}
Vector3f BulletRigidBody3D::GetLinearVelocity() const
{
return FromBullet(m_body->getLinearVelocity());
}
float BulletRigidBody3D::GetMass() const
{
return m_body->getMass();
}
Vector3f BulletRigidBody3D::GetMassCenter(CoordSys coordSys) const
{
return FromBullet(m_body->getCenterOfMassPosition());
}
Matrix4f BulletRigidBody3D::GetMatrix() const
{
return FromBullet(m_body->getWorldTransform());
}
Vector3f BulletRigidBody3D::GetPosition() const
{
return FromBullet(m_body->getWorldTransform().getOrigin());
}
Quaternionf BulletRigidBody3D::GetRotation() const
{
return FromBullet(m_body->getWorldTransform().getRotation());
}
bool BulletRigidBody3D::IsSimulationEnabled() const
{
return m_body->isActive();
}
bool BulletRigidBody3D::IsSleeping() const
{
return m_body->getActivationState() == ISLAND_SLEEPING;
}
bool BulletRigidBody3D::IsSleepingEnabled() const
{
return m_body->getActivationState() != DISABLE_DEACTIVATION;
}
void BulletRigidBody3D::SetAngularDamping(float angularDamping)
{
m_body->setDamping(m_body->getLinearDamping(), angularDamping);
}
void BulletRigidBody3D::SetAngularVelocity(const Vector3f& angularVelocity)
{
m_body->setAngularVelocity(ToBullet(angularVelocity));
}
void BulletRigidBody3D::SetGeom(std::shared_ptr<BulletCollider3D> geom, bool recomputeInertia)
{
if (m_geom != geom)
{
if (geom)
m_geom = std::move(geom);
else
m_geom = std::make_shared<BulletNullCollider3D>();
m_body->setCollisionShape(m_geom->GetShape());
if (recomputeInertia)
{
float mass = GetMass();
Vector3f inertia;
m_geom->ComputeInertia(mass, &inertia);
m_body->setMassProps(mass, ToBullet(inertia));
}
}
}
void BulletRigidBody3D::SetLinearDamping(float damping)
{
m_body->setDamping(damping, m_body->getAngularDamping());
}
void BulletRigidBody3D::SetLinearVelocity(const Vector3f& velocity)
{
m_body->setLinearVelocity(ToBullet(velocity));
}
void BulletRigidBody3D::SetMass(float mass)
{
NazaraAssert(mass >= 0.f, "Mass must be positive and finite");
NazaraAssert(std::isfinite(mass), "Mass must be positive and finite");
Vector3f inertia;
m_geom->ComputeInertia(mass, &inertia);
m_body->setMassProps(mass, ToBullet(inertia));
}
void BulletRigidBody3D::SetMassCenter(const Vector3f& center)
{
btTransform centerTransform;
centerTransform.setIdentity();
centerTransform.setOrigin(ToBullet(center));
m_body->setCenterOfMassTransform(centerTransform);
}
void BulletRigidBody3D::SetPosition(const Vector3f& position)
{
btTransform worldTransform = m_body->getWorldTransform();
worldTransform.setOrigin(ToBullet(position));
m_body->setWorldTransform(worldTransform);
}
void BulletRigidBody3D::SetPositionAndRotation(const Vector3f& position, const Quaternionf& rotation)
{
btTransform worldTransform;
worldTransform.setOrigin(ToBullet(position));
worldTransform.setRotation(ToBullet(rotation));
m_body->setWorldTransform(worldTransform);
}
void BulletRigidBody3D::SetRotation(const Quaternionf& rotation)
{
btTransform worldTransform = m_body->getWorldTransform();
worldTransform.setRotation(ToBullet(rotation));
m_body->setWorldTransform(worldTransform);
}
Quaternionf BulletRigidBody3D::ToLocal(const Quaternionf& worldRotation)
{
return GetRotation().Conjugate() * worldRotation;
}
Vector3f BulletRigidBody3D::ToLocal(const Vector3f& worldPosition)
{
return GetMatrix().InverseTransform() * worldPosition;
}
Quaternionf BulletRigidBody3D::ToWorld(const Quaternionf& localRotation)
{
return GetRotation() * localRotation;
}
Vector3f BulletRigidBody3D::ToWorld(const Vector3f& localPosition)
{
return GetMatrix() * localPosition;
}
void BulletRigidBody3D::WakeUp()
{
m_body->activate();
}
BulletRigidBody3D& BulletRigidBody3D::operator=(BulletRigidBody3D&& object) noexcept
{
Destroy();
m_body = object.m_body;
m_bodyPoolIndex = object.m_bodyPoolIndex;
m_geom = std::move(object.m_geom);
m_world = object.m_world;
if (m_body)
m_body->setUserPointer(this);
object.m_body = nullptr;
return *this;
}
void BulletRigidBody3D::Destroy()
{
if (m_body)
{
m_world->RemoveRigidBody(m_body, m_bodyPoolIndex);
m_body = nullptr;
}
m_geom.reset();
}
}

View File

@ -1,145 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - BulletPhysics3D module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/BulletPhysics3D/Systems/BulletPhysics3DSystem.hpp>
#include <Nazara/Core/Components/DisabledComponent.hpp>
#include <Nazara/Utility/Components/NodeComponent.hpp>
#include <Nazara/BulletPhysics3D/Debug.hpp>
namespace Nz
{
BulletPhysics3DSystem::BulletPhysics3DSystem(entt::registry& registry) :
m_registry(registry),
m_physicsConstructObserver(m_registry, entt::collector.group<BulletRigidBody3DComponent, NodeComponent>())
{
m_constructConnection = registry.on_construct<BulletRigidBody3DComponent>().connect<&BulletPhysics3DSystem::OnConstruct>(this);
m_destructConnection = registry.on_destroy<BulletRigidBody3DComponent>().connect<&BulletPhysics3DSystem::OnDestruct>(this);
m_stepCount = 0;
m_physicsTime = Time::Zero();
m_updateTime = Time::Zero();
}
BulletPhysics3DSystem::~BulletPhysics3DSystem()
{
m_physicsConstructObserver.disconnect();
// Ensure every RigidBody3D is destroyed before world is
auto rigidBodyView = m_registry.view<BulletRigidBody3DComponent>();
for (auto [entity, rigidBodyComponent] : rigidBodyView.each())
rigidBodyComponent.Destroy();
}
void BulletPhysics3DSystem::Dump()
{
if (m_stepCount == 0)
m_stepCount = 1;
/*
std::cout << "Physics time: " << (m_physicsTime / Time::Nanoseconds(m_stepCount)) << std::endl;
std::cout << "Update time: " << (m_updateTime / Time::Nanoseconds(m_stepCount)) << std::endl;
std::cout << "Active body count: " << m_activeObjectCount << std::endl;
std::cout << "--" << std::endl;
*/
m_stepCount = 0;
m_physicsTime = Time::Zero();
m_updateTime = Time::Zero();
}
bool BulletPhysics3DSystem::RaycastQuery(const Vector3f& from, const Vector3f& to, const FunctionRef<std::optional<float>(const RaycastHit& hitInfo)>& callback)
{
return m_physWorld.RaycastQuery(from, to, [&](const BulletPhysWorld3D::RaycastHit& hitInfo)
{
RaycastHit hitWithEntity;
static_cast<BulletPhysWorld3D::RaycastHit&>(hitWithEntity) = hitInfo;
if (hitWithEntity.hitBody)
{
std::size_t uniqueIndex = hitWithEntity.hitBody->GetUniqueIndex();
if (uniqueIndex < m_physicsEntities.size())
hitWithEntity.hitEntity = entt::handle(m_registry, m_physicsEntities[uniqueIndex]);
}
return callback(hitWithEntity);
});
}
bool BulletPhysics3DSystem::RaycastQueryFirst(const Vector3f& from, const Vector3f& to, RaycastHit* hitInfo)
{
if (!m_physWorld.RaycastQueryFirst(from, to, hitInfo))
return false;
if (hitInfo->hitBody)
{
std::size_t uniqueIndex = hitInfo->hitBody->GetUniqueIndex();
if (uniqueIndex < m_physicsEntities.size())
hitInfo->hitEntity = entt::handle(m_registry, m_physicsEntities[uniqueIndex]);
}
return true;
}
void BulletPhysics3DSystem::Update(Time elapsedTime)
{
// Move newly-created physics entities to their node position/rotation
m_physicsConstructObserver.each([&](entt::entity entity)
{
BulletRigidBody3DComponent& entityPhysics = m_registry.get<BulletRigidBody3DComponent>(entity);
NodeComponent& entityNode = m_registry.get<NodeComponent>(entity);
entityPhysics.SetPositionAndRotation(entityNode.GetPosition(CoordSys::Global), entityNode.GetRotation(CoordSys::Global));
});
Time t1 = GetElapsedNanoseconds();
// Update the physics world
m_physWorld.Step(elapsedTime);
m_stepCount++;
Time t2 = GetElapsedNanoseconds();
// Replicate rigid body position to their node components
// TODO: Only replicate active entities
m_activeObjectCount = 0;
auto view = m_registry.view<NodeComponent, const BulletRigidBody3DComponent>(entt::exclude<DisabledComponent>);
for (auto entity : view)
{
auto& rigidBodyComponent = view.get<const BulletRigidBody3DComponent>(entity);
if (rigidBodyComponent.IsSleeping())
continue;
auto& nodeComponent = view.get<NodeComponent>(entity);
nodeComponent.SetTransform(rigidBodyComponent.GetPosition(), rigidBodyComponent.GetRotation());
m_activeObjectCount++;
}
Time t3 = GetElapsedNanoseconds();
m_physicsTime += (t2 - t1);
m_updateTime += (t3 - t2);
}
void BulletPhysics3DSystem::OnConstruct(entt::registry& registry, entt::entity entity)
{
// Register rigid body owning entity
BulletRigidBody3DComponent& rigidBody = registry.get<BulletRigidBody3DComponent>(entity);
std::size_t uniqueIndex = rigidBody.GetUniqueIndex();
if (uniqueIndex >= m_physicsEntities.size())
m_physicsEntities.resize(uniqueIndex + 1);
m_physicsEntities[uniqueIndex] = entity;
}
void BulletPhysics3DSystem::OnDestruct(entt::registry& registry, entt::entity entity)
{
// Unregister owning entity
BulletRigidBody3DComponent& rigidBody = registry.get<BulletRigidBody3DComponent>(entity);
std::size_t uniqueIndex = rigidBody.GetUniqueIndex();
assert(uniqueIndex <= m_physicsEntities.size());
m_physicsEntities[uniqueIndex] = entt::null;
}
}

View File

@ -3,5 +3,4 @@
#include <Nazara/Math.hpp>
#include <Nazara/Network.hpp>
#include <Nazara/ChipmunkPhysics2D.hpp>
#include <Nazara/BulletPhysics3D.hpp>
#include <Nazara/Utility.hpp>

View File

@ -71,11 +71,6 @@ local modules = {
end
end
},
BulletPhysics3D = {
Option = "bulletphysics",
Deps = {"NazaraUtility"},
Packages = { "bullet3", "entt" }
},
ChipmunkPhysics2D = {
Option = "chipmunkphysics",
Deps = {"NazaraUtility"},
@ -300,10 +295,6 @@ if has_config("audio") then
end
end
if has_config("bulletphysics") then
add_requires("bullet3", { configs = { debug = is_mode("debug") }})
end
if has_config("chipmunkphysics") then
add_requires("chipmunk2d")
end