Make Jolt work on web + update demo

This commit is contained in:
SirLynix 2023-03-19 11:47:35 +01:00 committed by Jérôme Leclercq
parent c5ac142888
commit 648273573d
4 changed files with 131 additions and 57 deletions

View File

@ -19,6 +19,7 @@ constexpr float BoxDims = 16.f;
int main()
{
try {
// Mise en place de l'application, de la fenêtre et du monde
Nz::Renderer::Config renderConfig;
//renderConfig.preferredAPI = Nz::RenderAPI::OpenGL;
@ -50,8 +51,9 @@ int main()
auto& physSystem = world.AddSystem<Nz::BulletPhysics3DSystem>();
#endif
physSystem.GetPhysWorld().SetMaxStepCount(1);
//physSystem.GetPhysWorld().SetGravity(Nz::Vector3f::Down() * 9.81f);
physSystem.GetPhysWorld().SetGravity(Nz::Vector3f::Zero());
physSystem.GetPhysWorld().SetStepSize(Nz::Time::TickDuration(30));
physSystem.GetPhysWorld().SetGravity(Nz::Vector3f::Down() * 9.81f);
//physSystem.GetPhysWorld().SetGravity(Nz::Vector3f::Zero());
auto& renderSystem = world.AddSystem<Nz::RenderSystem>();
Nz::WindowSwapchain& windowSwapchain = renderSystem.CreateSwapchain(mainWindow);
@ -146,9 +148,9 @@ int main()
//std::mt19937 rd(std::random_device{}());
std::mt19937 rd(42);
std::uniform_real_distribution<float> colorDis(0.f, 360.f);
std::uniform_real_distribution<float> radiusDis(0.05f, 0.5f);
std::uniform_real_distribution<float> radiusDis(0.1f, 0.5f);
constexpr std::size_t SphereCount = 3000;
constexpr std::size_t SphereCount = 2000;
for (std::size_t i = 0; i < SphereCount; ++i)
{
float radius = radiusDis(rd);
@ -180,11 +182,11 @@ int main()
#else
auto& ballPhysics = ballEntity.emplace<Nz::BulletRigidBody3DComponent>(physSystem.CreateRigidBody(sphereCollider));
#endif
//ballPhysics.SetMass(4.f / 3.f * Nz::Pi<float> * Nz::IntegralPow(radius, 3));
ballPhysics.DisableSleeping();
ballPhysics.SetMass(4.f / 3.f * Nz::Pi<float> * Nz::IntegralPow(radius, 3));
//ballPhysics.DisableSleeping();
}
std::uniform_real_distribution<float> lengthDis(0.1f, 1.f);
std::uniform_real_distribution<float> lengthDis(0.2f, 1.5f);
std::shared_ptr<Nz::GraphicalMesh> boxMesh = Nz::GraphicalMesh::Build(Nz::Primitive::Box(Nz::Vector3f(1.f)));
constexpr std::size_t BoxCount = 100;
@ -224,8 +226,8 @@ int main()
#else
auto& ballPhysics = ballEntity.emplace<Nz::BulletRigidBody3DComponent>(physSystem.CreateRigidBody(boxCollider));
#endif
//ballPhysics.SetMass(width * height * depth);
ballPhysics.DisableSleeping();
ballPhysics.SetMass(width * height * depth);
//ballPhysics.DisableSleeping();
}
// Lumière
@ -270,14 +272,9 @@ int main()
NazaraSlot(Nz::WindowEventHandler, OnMouseMoved, cameraMove);
NazaraSlot(Nz::WindowEventHandler, OnMouseMoved, grabbedObjectMove);
//std::optional<Nz::JoltPivotConstraint3D> grabConstraint;
//std::optional<Nz::PivotConstraint3D> grabConstraint;
Nz::WindowEventHandler& eventHandler = mainWindow.GetEventHandler();
eventHandler.OnMouseButtonPressed.Connect([&](const Nz::WindowEventHandler*, const Nz::WindowEvent::MouseButtonEvent& event)
{
if (event.button == Nz::Mouse::Middle)
{
cameraMove.Connect(eventHandler.OnMouseMoved, [&](const Nz::WindowEventHandler*, const Nz::WindowEvent::MouseMoveEvent& event)
auto mouseMoveCallback = [&](const Nz::WindowEventHandler*, const Nz::WindowEvent::MouseMoveEvent& event)
{
constexpr float sensitivity = 0.3f;
@ -286,24 +283,47 @@ int main()
camAngles.pitch = Nz::Clamp(camAngles.pitch - event.deltaY * sensitivity, -89.f, 89.f);
UpdateCamera();
});
};
Nz::WindowEventHandler& eventHandler = mainWindow.GetEventHandler();
eventHandler.OnMouseButtonPressed.Connect([&](const Nz::WindowEventHandler*, const Nz::WindowEvent::MouseButtonEvent& event)
{
if (event.button == Nz::Mouse::Middle)
{
cameraMove.Connect(eventHandler.OnMouseMoved, mouseMoveCallback);
}
else if (event.button == Nz::Mouse::Left)
{
auto& cameraNode = cameraEntity.get<Nz::NodeComponent>();
auto& cameraComponent = cameraEntity.get<Nz::CameraComponent>();
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 });
/*Nz::JoltPhysics3DSystem::RaycastHit hitInfo;
if (physSystem.RaycastQueryFirst(from, to, &hitInfo))
/*/Nz::Physics3DSystem::RaycastHit lastHitInfo;
auto callback = [&](const Nz::Physics3DSystem::RaycastHit& hitInfo) -> std::optional<float>
{
if (hitInfo.hitBody)
if (hitInfo.hitEntity == boxEntity)
{
grabConstraint.emplace(*hitInfo.hitBody, hitInfo.hitPosition);
Nz::Vector3f dirToCenter = Nz::Vector3f::Zero() - hitInfo.hitPosition;
dirToCenter.Normalize();
grabbedObjectMove.Connect(eventHandler.OnMouseMoved, [&, body = hitInfo.hitBody, distance = Nz::Vector3f::Distance(from, hitInfo.hitPosition)](const Nz::WindowEventHandler*, const Nz::WindowEvent::MouseMoveEvent& event)
if (Nz::Vector3f::DotProduct(dirToCenter, hitInfo.hitNormal) < 0.f)
return std::nullopt;
}
lastHitInfo = hitInfo;
return hitInfo.fraction;
};
if (physSystem.RaycastQuery(from, to, callback))
{
if (lastHitInfo.hitBody && lastHitInfo.hitEntity != boxEntity)
{
grabConstraint.emplace(*lastHitInfo.hitBody, lastHitInfo.hitPosition);
grabConstraint->SetImpulseClamp(30.f);
grabbedObjectMove.Connect(eventHandler.OnMouseMoved, [&, body = lastHitInfo.hitBody, distance = Nz::Vector3f::Distance(from, lastHitInfo.hitPosition)](const Nz::WindowEventHandler*, const Nz::WindowEvent::MouseMoveEvent& event)
{
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 });
@ -312,7 +332,11 @@ int main()
grabConstraint->SetSecondAnchor(newPosition);
});
}
}*/
else
cameraMove.Connect(eventHandler.OnMouseMoved, mouseMoveCallback);
}
else
cameraMove.Connect(eventHandler.OnMouseMoved, mouseMoveCallback);*/
}
});
@ -321,6 +345,7 @@ int main()
if (event.button == Nz::Mouse::Left)
{
//grabConstraint.reset();
cameraMove.Disconnect();
grabbedObjectMove.Disconnect();
}
else if (event.button == Nz::Mouse::Middle)
@ -339,10 +364,17 @@ int main()
{
auto& cameraNode = cameraEntity.get<Nz::NodeComponent>();
physSystem.GetPhysWorld().SetGravity(cameraNode.GetBackward() * 9.81f);
//physSystem.GetPhysWorld().SetGravity(cameraNode.GetBackward() * 9.81f);
}
});
Nz::DegreeAnglef rotation = 0.f;
app.AddUpdater([&](Nz::Time elapsedTime)
{
rotation += elapsedTime.AsSeconds() * 30.f;
physSystem.GetPhysWorld().SetGravity(Nz::Quaternionf(Nz::EulerAnglesf(0.f, rotation, 0.f)) * Nz::Vector3f::Forward());
});
Nz::MillisecondClock fpsClock;
unsigned int fps = 0;
app.AddUpdater([&](Nz::Time /*elapsedTime*/)
@ -357,4 +389,9 @@ int main()
});
return app.Run();
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}

View File

@ -179,6 +179,8 @@ namespace Nz
DitchMeAsap::BPLayerInterfaceImpl layerInterface;
DitchMeAsap::ObjectLayerPairFilterImpl objectLayerFilter;
DitchMeAsap::ObjectVsBroadPhaseLayerFilterImpl objectBroadphaseLayerFilter;
DitchMeAsap::MyBodyActivationListener bodyActivationListener;
DitchMeAsap::MyContactListener contactListener;
JoltWorld() = default;
JoltWorld(const JoltWorld&) = delete;
@ -196,6 +198,8 @@ namespace Nz
{
m_world = std::make_unique<JoltWorld>();
m_world->physicsSystem.Init(0xFFFF, 0, 0xFFFF, 0xFFFF, m_world->layerInterface, m_world->objectBroadphaseLayerFilter, m_world->objectLayerFilter);
m_world->physicsSystem.SetBodyActivationListener(&m_world->bodyActivationListener);
//m_world->physicsSystem.SetContactListener(&m_world->contactListener);
}
JoltPhysWorld3D::~JoltPhysWorld3D() = default;

View File

@ -40,7 +40,7 @@ namespace Nz
JPH::Factory::sInstance = new JPH::Factory;
JPH::RegisterTypes();
m_threadPool = std::make_unique<JPH::JobSystemThreadPool>(JPH::cMaxPhysicsJobs, JPH::cMaxPhysicsBarriers, Core::Instance()->GetHardwareInfo().GetCpuThreadCount());
m_threadPool = std::make_unique<JPH::JobSystemThreadPool>(JPH::cMaxPhysicsJobs, JPH::cMaxPhysicsBarriers, /* Core::Instance()->GetHardwareInfo().GetCpuThreadCount()*/0);
}
JoltPhysics3D::~JoltPhysics3D()

View File

@ -37,7 +37,6 @@ namespace Nz
JPH::Quat rotation = ToJolt(mat.GetRotation().Normalize());
JPH::BodyCreationSettings settings(m_geom->GetShapeSettings(), position, rotation, JPH::EMotionType::Dynamic, 1);
settings.mAllowSleeping = false;
JPH::Body* body = body_interface.CreateBody(settings);
body->SetUserData(SafeCast<UInt64>(reinterpret_cast<std::uintptr_t>(this)));
@ -59,23 +58,27 @@ namespace Nz
Destroy();
}
#if 0
void JoltRigidBody3D::AddForce(const Vector3f& force, CoordSys coordSys)
{
switch (coordSys)
{
case CoordSys::Global:
WakeUp();
m_body->applyCentralForce(ToJolt(force));
{
JPH::BodyInterface& body_interface = m_world->GetPhysicsSystem()->GetBodyInterface();
body_interface.AddForce(JPH::BodyID(m_bodyIndex), ToJolt(force));
//WakeUp();
//m_body->applyCentralForce(ToJolt(force));
break;
}
case CoordSys::Local:
WakeUp();
m_body->applyCentralForce(ToJolt(GetRotation() * force));
//WakeUp();
//m_body->applyCentralForce(ToJolt(GetRotation() * force));
break;
}
}
#if 0
void JoltRigidBody3D::AddForce(const Vector3f& force, const Vector3f& point, CoordSys coordSys)
{
switch (coordSys)
@ -112,6 +115,13 @@ namespace Nz
#endif
void JoltRigidBody3D::EnableSleeping(bool enable)
{
auto& body_interface = m_world->GetPhysicsSystem()->GetBodyLockInterface();
JPH::BodyLockWrite lock(body_interface, JPH::BodyID(m_bodyIndex));
if (lock.Succeeded())
{
JPH::Body& body = lock.GetBody();
body.SetAllowSleeping(enable);
}
}
#if 0
@ -148,12 +158,19 @@ namespace Nz
{
return FromJolt(m_body->getLinearVelocity());
}
#endif
float JoltRigidBody3D::GetMass() const
{
return m_body->getMass();
}
auto& body_interface = m_world->GetPhysicsSystem()->GetBodyLockInterface();
JPH::BodyLockRead lock(body_interface, JPH::BodyID(m_bodyIndex));
if (!lock.Succeeded())
return 0.f;
const JPH::Body& body = lock.GetBody();
return 1.f / body.GetMotionProperties()->GetInverseMass();
}
#if 0
Vector3f JoltRigidBody3D::GetMassCenter(CoordSys coordSys) const
{
return FromJolt(m_body->getCenterOfMassPosition());
@ -190,12 +207,18 @@ namespace Nz
return !body_interface.IsActive(JPH::BodyID(m_bodyIndex));
}
#if 0
bool JoltRigidBody3D::IsSleepingEnabled() const
{
return m_body->getActivationState() != DISABLE_DEACTIVATION;
auto& body_interface = m_world->GetPhysicsSystem()->GetBodyLockInterface();
JPH::BodyLockRead lock(body_interface, JPH::BodyID(m_bodyIndex));
if (!lock.Succeeded())
return true;
const JPH::Body& body = lock.GetBody();
return body.GetAllowSleeping();
}
#if 0
void JoltRigidBody3D::SetAngularDamping(float angularDamping)
{
m_body->setDamping(m_body->getLinearDamping(), angularDamping);
@ -205,7 +228,7 @@ namespace Nz
{
m_body->setAngularVelocity(ToJolt(angularVelocity));
}
#endif
void JoltRigidBody3D::SetGeom(std::shared_ptr<JoltCollider3D> geom, bool recomputeInertia)
{
if (m_geom != geom)
@ -213,21 +236,13 @@ namespace Nz
if (geom)
m_geom = std::move(geom);
else
m_geom = std::make_shared<NullCollider3D>();
m_geom = std::make_shared<JoltSphereCollider3D>(1.f);
m_body->setCollisionShape(m_geom->GetShape());
if (recomputeInertia)
{
float mass = GetMass();
Vector3f inertia;
m_geom->ComputeInertia(mass, &inertia);
m_body->setMassProps(mass, ToJolt(inertia));
JPH::BodyInterface& body_interface = m_world->GetPhysicsSystem()->GetBodyInterface();
body_interface.SetShape(JPH::BodyID(m_bodyIndex), m_geom->GetShapeSettings()->Create().Get(), true, JPH::EActivation::Activate);
}
}
}
#if 0
void JoltRigidBody3D::SetLinearDamping(float damping)
{
m_body->setDamping(damping, m_body->getAngularDamping());
@ -243,8 +258,25 @@ namespace Nz
NazaraAssert(mass >= 0.f, "Mass must be positive and finite");
NazaraAssert(std::isfinite(mass), "Mass must be positive and finite");
JPH::BodyInterface& body_interface = m_world->GetPhysicsSystem()->GetBodyInterface();
body_interface.SetMotionType(JPH::BodyID(m_bodyIndex), (mass > 0.f) ? JPH::EMotionType::Dynamic : JPH::EMotionType::Static, JPH::EActivation::Activate);
auto& bodyLock = m_world->GetPhysicsSystem()->GetBodyLockInterface();
JPH::BodyLockWrite lock(bodyLock, JPH::BodyID(m_bodyIndex));
if (!lock.Succeeded())
return;
JPH::Body& body = lock.GetBody();
if (mass > 0.f)
{
body.SetMotionType(JPH::EMotionType::Dynamic);
body.GetMotionProperties()->SetInverseMass(1.f / mass);
}
else
{
JPH::BodyInterface& body_interface = m_world->GetPhysicsSystem()->GetBodyInterfaceNoLock();
body_interface.DeactivateBody(body.GetID());
body.SetMotionType(JPH::EMotionType::Static);
}
}
#if 0
@ -290,12 +322,13 @@ namespace Nz
{
return GetMatrix() * localPosition;
}
#endif
void JoltRigidBody3D::WakeUp()
{
m_body->activate();
JPH::BodyInterface& body_interface = m_world->GetPhysicsSystem()->GetBodyInterface();
body_interface.ActivateBody(JPH::BodyID(m_bodyIndex));
}
#endif
JoltRigidBody3D& JoltRigidBody3D::operator=(JoltRigidBody3D&& object) noexcept
{