From 3b401e77114b0b87b2f11ce9b5c5c7daf10022f0 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Fri, 4 Aug 2023 17:18:05 -0400 Subject: [PATCH 1/3] Upgraded jolt version --- Nuake/src/Core/Physics/DynamicWorld.cpp | 109 +++++++++++++++++------- Nuake/src/Rendering/SceneRenderer.cpp | 6 +- Nuake/src/Resource/Prefab.cpp | 2 +- 3 files changed, 83 insertions(+), 34 deletions(-) diff --git a/Nuake/src/Core/Physics/DynamicWorld.cpp b/Nuake/src/Core/Physics/DynamicWorld.cpp index 2db145bc..5f3936ae 100644 --- a/Nuake/src/Core/Physics/DynamicWorld.cpp +++ b/Nuake/src/Core/Physics/DynamicWorld.cpp @@ -161,7 +161,7 @@ namespace Nuake { public: // See: ContactListener - virtual JPH::ValidateResult OnContactValidate(const JPH::Body& inBody1, const JPH::Body& inBody2, const JPH::CollideShapeResult& inCollisionResult) override + virtual JPH::ValidateResult OnContactValidate(const JPH::Body& inBody1, const JPH::Body& inBody2, JPH::RVec3Arg inBaseOffset, const JPH::CollideShapeResult& inCollisionResult) override { //std::cout << "Contact validate callback" << std::endl; @@ -200,7 +200,47 @@ namespace Nuake } }; + class ObjectVsBroadPhaseLayerFilterImpl : public JPH::ObjectVsBroadPhaseLayerFilter + { + public: + virtual bool ShouldCollide(JPH::ObjectLayer inLayer1, JPH::BroadPhaseLayer inLayer2) const override + { + switch (inLayer1) + { + case Layers::NON_MOVING: + return inLayer2 == BroadPhaseLayers::MOVING; + case Layers::MOVING: + return true; + default: + + return false; + } + } + }; + + class ObjectLayerPairFilterImpl : public JPH::ObjectLayerPairFilter + { + public: + virtual bool ShouldCollide(JPH::ObjectLayer inObject1, JPH::ObjectLayer inObject2) const override + { + switch (inObject1) + { + case Layers::NON_MOVING: + return inObject2 == Layers::MOVING; // Non moving only collides with moving + case Layers::MOVING: + return true; // Moving collides with everything + default: + + return false; + } + } + }; + + BPLayerInterfaceImpl JoltBroadphaseLayerInterface = BPLayerInterfaceImpl(); + ObjectVsBroadPhaseLayerFilterImpl JoltObjectVSBroadphaseLayerFilter = ObjectVsBroadPhaseLayerFilterImpl(); + ObjectLayerPairFilterImpl JoltObjectVSObjectLayerFilter; + namespace Physics { DynamicWorld::DynamicWorld() : _stepCount(0) @@ -208,13 +248,13 @@ namespace Nuake _registeredCharacters = std::map(); // Initialize Jolt Physics - const uint32_t MaxBodies = 1024; + const uint32_t MaxBodies = 2048; const uint32_t NumBodyMutexes = 0; const uint32_t MaxBodyPairs = 1024; const uint32_t MaxContactConstraints = 1024; _JoltPhysicsSystem = CreateRef(); - _JoltPhysicsSystem->Init(MaxBodies, NumBodyMutexes, MaxBodyPairs, MaxContactConstraints, JoltBroadphaseLayerInterface, MyBroadPhaseCanCollide, MyObjectCanCollide); + _JoltPhysicsSystem->Init(MaxBodies, NumBodyMutexes, MaxBodyPairs, MaxContactConstraints, JoltBroadphaseLayerInterface, JoltObjectVSBroadphaseLayerFilter, JoltObjectVSObjectLayerFilter); // A body activation listener gets notified when bodies activate and go to sleep // Note that this is called from a job so whatever you do here needs to be thread safe. @@ -295,6 +335,7 @@ namespace Nuake settings->mFriction = cc->Friction; settings->mShape = GetJoltShape(cc->Shape); settings->mGravityFactor = 0.0f; + settings->mSupportingVolume = JPH::Plane(JPH::Vec3::sAxisY(), -0.5f); auto& joltPosition = JPH::Vec3(cc->Position.x, cc->Position.y, cc->Position.z); @@ -302,7 +343,7 @@ namespace Nuake // We need to add 180 degrees because our forward is -Z. const auto& yOffset = Vector3(0.0f, Rad(180.0), 0.0f); - bodyRotation = glm::normalize(bodyRotation * Quat(yOffset)); + //bodyRotation = glm::normalize(bodyRotation * Quat(yOffset)); const auto& joltRotation = JPH::Quat(bodyRotation.x, bodyRotation.y, bodyRotation.z, bodyRotation.w); JPH::Character* character = new JPH::Character(settings, joltPosition, joltRotation, cc->GetEntity().GetID() , _JoltPhysicsSystem.get()); @@ -320,6 +361,7 @@ namespace Nuake { auto& characterController = _registeredCharacters[entityHandle]; const auto groundState = characterController->GetGroundState(); + return groundState == JPH::CharacterBase::EGroundState::OnGround; } @@ -331,31 +373,37 @@ namespace Nuake { // Create jolt ray const auto& fromJolt = JPH::Vec3(from.x, from.y, from.z); - const auto& toJolt = JPH::Vec3(to.x, to.y, to.z); - JPH::RayCast ray { fromJolt, toJolt - fromJolt }; - JPH::AllHitCollisionCollector collector; - _JoltPhysicsSystem->GetBroadPhaseQuery().CastRay(ray, collector); + const auto& toDirectionJolt = JPH::Vec3(to.x - from.x, to.y - from.y, to.z - from.z); + JPH::RRayCast ray { fromJolt, toDirectionJolt }; + JPH::AllHitCollisionCollector collector; + + JPH::RayCastResult result; + _JoltPhysicsSystem->GetNarrowPhaseQuery().CastRay(ray, JPH::RayCastSettings(), collector); // Fetch results - int num_hits = (int)collector.mHits.size(); - JPH::BroadPhaseCastResult* results = collector.mHits.data(); - - // Format result std::vector raycastResults; - for (int i = 0; i < num_hits; ++i) + + if (collector.HadHit()) { - const float hitFraction = results[i].mFraction; - const JPH::Vec3& hitPosition = ray.GetPointOnRay(results[i].mFraction); + int num_hits = (int)collector.mHits.size(); + JPH::BroadPhaseCastResult* results = collector.mHits.data(); - RaycastResult result + // Format result + for (int i = 0; i < num_hits; ++i) { - Vector3(hitPosition.GetX(), hitPosition.GetY(), hitPosition.GetZ()), - hitFraction - }; + const float hitFraction = results[i].mFraction; + const JPH::Vec3& hitPosition = ray.GetPointOnRay(results[i].mFraction); - raycastResults.push_back(std::move(result)); + RaycastResult result + { + Vector3(hitPosition.GetX(), hitPosition.GetY(), hitPosition.GetZ()), + hitFraction + }; + + raycastResults.push_back(std::move(result)); + } } - + return raycastResults; } @@ -435,31 +483,34 @@ namespace Nuake // Next step ++_stepCount; - // If you take larger steps than 1 / 60th of a second you need to do multiple collision steps in order to keep the simulation stable. // Do 1 collision step per 1 / 60th of a second (round up). int collisionSteps = 1; - constexpr float minStepDuration = 1.0f / 90.0f; + constexpr float minStepDuration = 1.0f / 30.0f; constexpr int maxStepCount = 32; + if(ts > minStepDuration) { + Logger::Log("Large step detected: " + std::to_string(ts), "physics", WARNING); collisionSteps = static_cast(ts) / minStepDuration; } + if (collisionSteps >= maxStepCount) + { + Logger::Log("Very large step detected: " + std::to_string(ts), "physics", WARNING); + } + // Prevents having too many steps and running out of jobs collisionSteps = std::min(collisionSteps, maxStepCount); - // If you want more accurate step results you can do multiple sub steps within a collision step. Usually you would set this to 1. - constexpr int subSteps = 1; - // Step the world try { - _JoltPhysicsSystem->Update(ts, collisionSteps, subSteps, new JPH::TempAllocatorMalloc(), _JoltJobSystem); + _JoltPhysicsSystem->Update(ts, collisionSteps, new JPH::TempAllocatorMalloc(), _JoltJobSystem); for (auto& c : _registeredCharacters) { - c.second->PostSimulation(0.001); + c.second->PostSimulation(0.05f); } } catch (...) @@ -483,8 +534,6 @@ namespace Nuake _registeredBodies.clear(); } - _registeredBodies.clear(); - if (!_registeredCharacters.empty()) { for (auto& character : _registeredCharacters) diff --git a/Nuake/src/Rendering/SceneRenderer.cpp b/Nuake/src/Rendering/SceneRenderer.cpp index d73bba18..22f50d16 100644 --- a/Nuake/src/Rendering/SceneRenderer.cpp +++ b/Nuake/src/Rendering/SceneRenderer.cpp @@ -131,8 +131,8 @@ namespace Nuake } mToneMapBuffer->Unbind(); - mSSR->Resize(framebuffer.GetSize()); - mSSR->Draw(mGBuffer.get(), framebuffer.GetTexture(), mView, mProjection, scene.GetCurrentCamera()); + //mSSR->Resize(framebuffer.GetSize()); + //mSSR->Draw(mGBuffer.get(), framebuffer.GetTexture(), mView, mProjection, scene.GetCurrentCamera()); framebuffer.Bind(); { @@ -141,7 +141,7 @@ namespace Nuake shader->Bind(); shader->SetUniformTex("u_Source", mToneMapBuffer->GetTexture().get(), 0); - shader->SetUniformTex("u_Source2", mSSR->OutputFramebuffer->GetTexture().get(), 1); + shader->SetUniformTex("u_Source2", mToneMapBuffer->GetTexture().get(), 1); Renderer::DrawQuad(); } framebuffer.Unbind(); diff --git a/Nuake/src/Resource/Prefab.cpp b/Nuake/src/Resource/Prefab.cpp index 66e89aef..4740028d 100644 --- a/Nuake/src/Resource/Prefab.cpp +++ b/Nuake/src/Resource/Prefab.cpp @@ -19,7 +19,7 @@ namespace Nuake { if (FileSystem::FileExists(path, false)) { std::string prefabTextContent = FileSystem::ReadFile(path); - newPrefab->Deserialize(prefabTextContent); + newPrefab->Deserialize(json::parse(prefabTextContent)); } return newPrefab; From 476cddd549808a6a7c14a1ed65b449a098a867d7 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Fri, 4 Aug 2023 17:22:49 -0400 Subject: [PATCH 2/3] Bumped jolt --- Nuake/dependencies/JoltPhysics | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Nuake/dependencies/JoltPhysics b/Nuake/dependencies/JoltPhysics index 0e4865a3..b767673c 160000 --- a/Nuake/dependencies/JoltPhysics +++ b/Nuake/dependencies/JoltPhysics @@ -1 +1 @@ -Subproject commit 0e4865a3456731bb27cbe58461c36656882aac11 +Subproject commit b767673cd51e19ace1025affb098290b4d46e59e From cd3e54292288e8380a5f2831946d5afa7f26aaf2 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Fri, 4 Aug 2023 17:33:25 -0400 Subject: [PATCH 3/3] Fixed rendering ghosting effect --- Nuake/src/Rendering/SceneRenderer.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Nuake/src/Rendering/SceneRenderer.cpp b/Nuake/src/Rendering/SceneRenderer.cpp index 22f50d16..a1569429 100644 --- a/Nuake/src/Rendering/SceneRenderer.cpp +++ b/Nuake/src/Rendering/SceneRenderer.cpp @@ -53,10 +53,14 @@ namespace Nuake mGBuffer->QueueResize(framebuffer.GetSize()); GBufferPass(scene); + // SSAO + const auto& sceneEnv = scene.GetEnvironment(); + sceneEnv->mSSAO->Resize(framebuffer.GetSize()); + sceneEnv->mSSAO->Draw(mGBuffer.get(), mProjection, mView); + mShadingBuffer->QueueResize(framebuffer.GetSize()); ShadingPass(scene); - const auto& sceneEnv = scene.GetEnvironment(); Ref finalOutput = mShadingBuffer->GetTexture(); if (scene.GetEnvironment()->BloomEnabled) { @@ -112,9 +116,7 @@ namespace Nuake finalOutput = framebuffer.GetTexture(); - // SSAO - sceneEnv->mSSAO->Resize(framebuffer.GetSize()); - sceneEnv->mSSAO->Draw(mGBuffer.get(), mProjection, mView); + // Copy final output to target framebuffer mToneMapBuffer->QueueResize(framebuffer.GetSize()); @@ -131,8 +133,8 @@ namespace Nuake } mToneMapBuffer->Unbind(); - //mSSR->Resize(framebuffer.GetSize()); - //mSSR->Draw(mGBuffer.get(), framebuffer.GetTexture(), mView, mProjection, scene.GetCurrentCamera()); + mSSR->Resize(framebuffer.GetSize()); + mSSR->Draw(mGBuffer.get(), framebuffer.GetTexture(), mView, mProjection, scene.GetCurrentCamera()); framebuffer.Bind(); { @@ -141,7 +143,7 @@ namespace Nuake shader->Bind(); shader->SetUniformTex("u_Source", mToneMapBuffer->GetTexture().get(), 0); - shader->SetUniformTex("u_Source2", mToneMapBuffer->GetTexture().get(), 1); + shader->SetUniformTex("u_Source2", mSSR->OutputFramebuffer->GetTexture().get(), 1); Renderer::DrawQuad(); } framebuffer.Unbind();