diff --git a/Editor/resources/Scripts/Scene.wren b/Editor/resources/Scripts/Scene.wren index a5f0eb65..64aa3c93 100644 --- a/Editor/resources/Scripts/Scene.wren +++ b/Editor/resources/Scripts/Scene.wren @@ -24,6 +24,8 @@ class Scene { return Light.new(id) } else if (component == "CharacterController") { return CharacterController.new(id) + } else if (component == "RigidBody") { + return RigidBody.new(id) } else if (component == "Camera") { return Camera.new(id) } else if (component == "Transform") { @@ -70,6 +72,9 @@ class Scene { foreign static IsCharacterControllerOnGround_(e) //foreign static IsOnGround_(e) + // RigidBody + foreign static AddForce_(e, x, y, z) + foreign static TriggerGetOverlappingBodyCount_(e) foreign static TriggerGetOverlappingBodies_(e) @@ -159,6 +164,16 @@ class CharacterController { } } +class RigidBody { + construct new(id) { + _entityId = id + } + + AddForce(force) { + Scene.AddForce_(_entityId, force.x, force,y, force.z) + } +} + class Camera { construct new(id) { _entityId = id diff --git a/Nuake/src/Core/Physics/DynamicWorld.cpp b/Nuake/src/Core/Physics/DynamicWorld.cpp index 0ffbcf16..6b47a206 100644 --- a/Nuake/src/Core/Physics/DynamicWorld.cpp +++ b/Nuake/src/Core/Physics/DynamicWorld.cpp @@ -187,12 +187,12 @@ namespace Nuake public: virtual void OnBodyActivated(const JPH::BodyID& inBodyID, JPH::uint64 inBodyUserData) override { - std::cout << "A body got activated" << std::endl; + //std::cout << "A body got activated" << std::endl; } virtual void OnBodyDeactivated(const JPH::BodyID& inBodyID, JPH::uint64 inBodyUserData) override { - std::cout << "A body went to sleep" << std::endl; + //std::cout << "A body went to sleep" << std::endl; } }; @@ -420,7 +420,7 @@ namespace Nuake // Do 1 collision step per 1 / 60th of a second (round up). int collisionSteps = 1; constexpr float minStepDuration = 1.0f / 90.0f; - constexpr int maxStepCount = 32; + constexpr int maxStepCount = 16; if(ts > minStepDuration) { collisionSteps = static_cast(ts) / minStepDuration; @@ -450,9 +450,10 @@ namespace Nuake if (!_registeredBodies.empty()) { - _JoltBodyInterface->RemoveBodies(reinterpret_cast(_registeredBodies.data()), _registeredBodies.size()); - _registeredBodies.clear(); + _JoltBodyInterface->DestroyBodies(reinterpret_cast(_registeredBodies.data()), _registeredBodies.size()); } + + _registeredBodies.clear(); if (!_registeredCharacters.empty()) { @@ -464,7 +465,7 @@ namespace Nuake } } - void DynamicWorld::MoveAndSlideCharacterController(const Entity& entity, const Vector3 velocity) + void DynamicWorld::MoveAndSlideCharacterController(const Entity& entity, const Vector3& velocity) { const uint32_t entityHandle = entity.GetHandle(); if (_registeredCharacters.find(entityHandle) != _registeredCharacters.end()) @@ -474,6 +475,23 @@ namespace Nuake } } + void DynamicWorld::AddForceToRigidBody(const Entity& entity, const Vector3& force) + { + auto& bodyInterface = _JoltPhysicsSystem->GetBodyInterface(); + for (const auto& body : _registeredBodies) + { + auto bodyId = static_cast(body); + auto entityId = static_cast(bodyInterface.GetUserData(bodyId)); + if (entityId == entity.GetHandle()) + { + bodyInterface.AddForce(bodyId, JPH::Vec3(force.x, force.y, force.z)); + return; + } + } + + Logger::Log("[PhysicsSystem] - Failed to add force to rigidbody. Body not found with id: " + std::to_string(entity.GetHandle())); + } + JPH::Ref DynamicWorld::GetJoltShape(const Ref shape) { JPH::ShapeSettings::ShapeResult result; diff --git a/Nuake/src/Core/Physics/DynamicWorld.h b/Nuake/src/Core/Physics/DynamicWorld.h index 0bc45ecd..bbb5c05c 100644 --- a/Nuake/src/Core/Physics/DynamicWorld.h +++ b/Nuake/src/Core/Physics/DynamicWorld.h @@ -59,8 +59,8 @@ namespace Nuake void AddCharacterController(Ref cc); bool IsCharacterGrounded(const Entity& entity); // This is going to be ugly. TODO: Find a better way that passing itself as a parameter - void MoveAndSlideCharacterController(const Entity& entity, const Vector3 velocity); - + void MoveAndSlideCharacterController(const Entity& entity, const Vector3& velocity); + void AddForceToRigidBody(const Entity& entity, const Vector3& force); RaycastResult Raycast(const Vector3& from, const Vector3& to); void StepSimulation(Timestep ts); diff --git a/Nuake/src/Core/Physics/Rigibody.h b/Nuake/src/Core/Physics/Rigibody.h index c579400a..354dd84f 100644 --- a/Nuake/src/Core/Physics/Rigibody.h +++ b/Nuake/src/Core/Physics/Rigibody.h @@ -37,6 +37,7 @@ namespace Nuake void SetShape(Ref shape); Ref GetShape() const { return _collisionShape; } Entity GetEntity() const { return _entity; } + void AddForce(const Vector3& force); }; } } diff --git a/Nuake/src/Core/Physics/Rigidbody.cpp b/Nuake/src/Core/Physics/Rigidbody.cpp index 0a4da02e..464aa7b6 100644 --- a/Nuake/src/Core/Physics/Rigidbody.cpp +++ b/Nuake/src/Core/Physics/Rigidbody.cpp @@ -1,6 +1,8 @@ #include "PhysicsShapes.h" #include "Rigibody.h" -#include "../Core.h" +#include "src/Core/Core.h" +#include "src/Core/Physics/PhysicsManager.h" + #include #include @@ -42,5 +44,10 @@ namespace Nuake { _entity = ent; } + + void RigidBody::AddForce(const Vector3& force) + { + PhysicsManager::Get().GetWorld()->AddForceToRigidBody(_entity, force); + } } } diff --git a/Nuake/src/Resource/Prefab.h b/Nuake/src/Resource/Prefab.h index 593e3282..6e0241f2 100644 --- a/Nuake/src/Resource/Prefab.h +++ b/Nuake/src/Resource/Prefab.h @@ -71,11 +71,17 @@ namespace Nuake { { for (json e : j["Entities"]) { - Entity entity = Entity { Engine::GetCurrentScene()->m_Registry.create(), Engine::GetCurrentScene().get() }; + Entity entity = Engine::GetCurrentScene()->CreateEntity("-"); + auto& nameComponent = entity.GetComponent(); + + int entityId = nameComponent.ID; entity.Deserialize(e.dump()); + nameComponent.ID = entityId; + this->AddEntity(entity); } + // Set reference to the parent entity to children for (auto& e : Entities) { auto parentC = e.GetComponent(); diff --git a/Nuake/src/Scene/Components/RigidbodyComponent.cpp b/Nuake/src/Scene/Components/RigidbodyComponent.cpp index 4dd4c3e7..39862b53 100644 --- a/Nuake/src/Scene/Components/RigidbodyComponent.cpp +++ b/Nuake/src/Scene/Components/RigidbodyComponent.cpp @@ -13,18 +13,18 @@ namespace Nuake { Ref RigidBodyComponent::GetRigidBody() const { - return m_Rigidbody; + return Rigidbody; } void RigidBodyComponent::SyncTransformComponent(TransformComponent* tc) { - if (!m_Rigidbody) + if (!GetRigidBody()) return; } void RigidBodyComponent::SyncWithTransform(TransformComponent* tc) { - if (!m_Rigidbody) + if (!GetRigidBody()) return; } diff --git a/Nuake/src/Scene/Components/RigidbodyComponent.h b/Nuake/src/Scene/Components/RigidbodyComponent.h index 7fae80fb..508b6597 100644 --- a/Nuake/src/Scene/Components/RigidbodyComponent.h +++ b/Nuake/src/Scene/Components/RigidbodyComponent.h @@ -13,7 +13,7 @@ namespace Nuake { { public: float Mass; - Ref m_Rigidbody; + Ref Rigidbody; RigidBodyComponent(); Ref GetRigidBody() const; @@ -24,6 +24,7 @@ namespace Nuake { void DrawShape(TransformComponent* tc); void DrawEditor(); + json Serialize() { BEGIN_SERIALIZE(); diff --git a/Nuake/src/Scene/Entities/Entity.h b/Nuake/src/Scene/Entities/Entity.h index bbf073d3..2f197050 100644 --- a/Nuake/src/Scene/Entities/Entity.h +++ b/Nuake/src/Scene/Entities/Entity.h @@ -31,7 +31,7 @@ namespace Nuake template T& AddComponent() { - T& component = m_Scene->m_Registry.emplace(m_EntityHandle); + T& component = m_Scene->m_Registry.emplace_or_replace (m_EntityHandle); return component; } diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index 7dd2f876..11f5fd47 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -215,7 +215,7 @@ namespace Nuake { } std::string entityName; - if (GetEntity(name) != Entity()) + if (GetEntity(name) == Entity()) { entityName = name; } @@ -226,7 +226,7 @@ namespace Nuake { { const std::string& entityEnumName = name + std::to_string(i); const auto& entityId = GetEntity(entityEnumName).GetHandle(); - if (entityId != -1) + if (entityId == -1) { entityName = entityEnumName; break; diff --git a/Nuake/src/Scene/Systems/PhysicsSystem.cpp b/Nuake/src/Scene/Systems/PhysicsSystem.cpp index 3f28533d..8f484bfc 100644 --- a/Nuake/src/Scene/Systems/PhysicsSystem.cpp +++ b/Nuake/src/Scene/Systems/PhysicsSystem.cpp @@ -120,6 +120,8 @@ namespace Nuake if (!Engine::IsPlayMode()) return; + InitializeRigidbodies(); + PhysicsManager::Get().Step(ts); } @@ -227,6 +229,11 @@ namespace Nuake Entity ent = Entity({ e, m_Scene }); Ref rigidBody; + if (rigidBodyComponent.GetRigidBody()) + { + continue; + } + if (ent.HasComponent()) { float mass = rigidBodyComponent.Mass; @@ -276,6 +283,7 @@ namespace Nuake { Logger::Log("Cannot use mesh collider without model component", "physics", WARNING); } + const auto& modelComponent = ent.GetComponent(); const auto& component = ent.GetComponent(); @@ -293,6 +301,8 @@ namespace Nuake PhysicsManager::Get().RegisterBody(rigidBody); } } + + rigidBodyComponent.Rigidbody = rigidBody; } } diff --git a/Nuake/src/Scene/Systems/PhysicsSystem.h b/Nuake/src/Scene/Systems/PhysicsSystem.h index 5c14c303..7b639e65 100644 --- a/Nuake/src/Scene/Systems/PhysicsSystem.h +++ b/Nuake/src/Scene/Systems/PhysicsSystem.h @@ -14,7 +14,6 @@ namespace Nuake void Exit() override; private: - void InitializeShapes(); void InitializeQuakeMap(); void InitializeRigidbodies(); diff --git a/Nuake/src/Scripting/Modules/PhysicsModule.h b/Nuake/src/Scripting/Modules/PhysicsModule.h index ae211dd6..621750bb 100644 --- a/Nuake/src/Scripting/Modules/PhysicsModule.h +++ b/Nuake/src/Scripting/Modules/PhysicsModule.h @@ -8,8 +8,10 @@ #include #include "../Core/Physics/PhysicsManager.h" -namespace Nuake { - namespace ScriptAPI { +namespace Nuake +{ + namespace ScriptAPI + { class PhysicsModule : public ScriptModule { std::string ModuleName = "Engine"; diff --git a/Nuake/src/Scripting/Modules/SceneModule.h b/Nuake/src/Scripting/Modules/SceneModule.h index 954126bd..c15f109f 100644 --- a/Nuake/src/Scripting/Modules/SceneModule.h +++ b/Nuake/src/Scripting/Modules/SceneModule.h @@ -57,6 +57,8 @@ namespace Nuake { RegisterMethod("MoveAndSlide_(_,_,_,_)", (void*)MoveAndSlide); RegisterMethod("IsCharacterControllerOnGround_(_)", (void*)IsCharacterControllerOnGround); + RegisterMethod("AddForce_(_,_,_,_)", (void*)AddForce); + RegisterMethod("TriggerGetOverlappingBodyCount_(_)", (void*)TriggerGetOverlappingBodyCount); RegisterMethod("TriggerGetOverlappingBodies_(_)", (void*)TriggerGetOverlappingBodies); @@ -125,6 +127,7 @@ namespace Nuake { if (name == "Transform") result = ent.HasComponent(); if (name == "Light") result = ent.HasComponent(); if (name == "QuakeMap") result = ent.HasComponent(); + if (name == "RigidBody") result = ent.HasComponent(); if (name == "CharacterController") { result = ent.HasComponent(); @@ -258,6 +261,18 @@ namespace Nuake { characterController.CharacterController->MoveAndSlide(Vector3(x, y, z)); } + static void AddForce(WrenVM* vm) + { + double handle = wrenGetSlotDouble(vm, 1); + double x = wrenGetSlotDouble(vm, 2); + double y = wrenGetSlotDouble(vm, 3); + double z = wrenGetSlotDouble(vm, 4); + + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + auto& rigidBodyComponent = ent.GetComponent(); + rigidBodyComponent.Rigidbody->AddForce(Vector3(x, y, z)); + } + static void GetTranslation(WrenVM* vm) { double handle = wrenGetSlotDouble(vm, 1);