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 44d04461..927190d5 100644 --- a/Nuake/src/Core/Physics/DynamicWorld.cpp +++ b/Nuake/src/Core/Physics/DynamicWorld.cpp @@ -275,8 +275,6 @@ namespace Nuake bodySettings.mUserData = rb->GetEntity().GetID(); // Create the actual rigid body JPH::BodyID body = _JoltBodyInterface->CreateAndAddBody(bodySettings, JPH::EActivation::Activate); // Note that if we run out of bodies this can return nullptr - - _JoltBodyInterface->AddForce(body, JPH::Vec3(10, 1, 0)); _registeredBodies.push_back((uint32_t)body.GetIndexAndSequenceNumber()); } @@ -452,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()) { @@ -466,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()) @@ -476,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 cfa25a48..d568c957 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(glm::vec3 from, glm::vec3 to); void StepSimulation(Timestep ts); diff --git a/Nuake/src/Core/Physics/Rigibody.h b/Nuake/src/Core/Physics/Rigibody.h index 14b99b76..4a9bc9e1 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 aaa93938..a8cbd7fc 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/Scene/Components/RigidbodyComponent.h b/Nuake/src/Scene/Components/RigidbodyComponent.h index 85a54a89..508b6597 100644 --- a/Nuake/src/Scene/Components/RigidbodyComponent.h +++ b/Nuake/src/Scene/Components/RigidbodyComponent.h @@ -24,6 +24,7 @@ namespace Nuake { void DrawShape(TransformComponent* tc); void DrawEditor(); + json Serialize() { BEGIN_SERIALIZE(); diff --git a/Nuake/src/Scripting/Modules/SceneModule.h b/Nuake/src/Scripting/Modules/SceneModule.h index bd2c2e4e..c0297bbc 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); @@ -126,6 +128,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(); @@ -259,6 +262,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);