Merge pull request #45 from antopilo/NK-16-physics-scripting-module

Nk 16 physics scripting module
This commit is contained in:
Antoine Pilote
2023-07-22 11:58:47 -04:00
committed by GitHub
14 changed files with 94 additions and 20 deletions

View File

@@ -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

View File

@@ -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<float>(ts) / minStepDuration;
@@ -450,9 +450,10 @@ namespace Nuake
if (!_registeredBodies.empty())
{
_JoltBodyInterface->RemoveBodies(reinterpret_cast<JPH::BodyID*>(_registeredBodies.data()), _registeredBodies.size());
_registeredBodies.clear();
_JoltBodyInterface->DestroyBodies(reinterpret_cast<JPH::BodyID*>(_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<JPH::BodyID>(body);
auto entityId = static_cast<uint32_t>(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<JPH::Shape> DynamicWorld::GetJoltShape(const Ref<PhysicShape> shape)
{
JPH::ShapeSettings::ShapeResult result;

View File

@@ -59,8 +59,8 @@ namespace Nuake
void AddCharacterController(Ref<CharacterController> 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);

View File

@@ -37,6 +37,7 @@ namespace Nuake
void SetShape(Ref<PhysicShape> shape);
Ref<PhysicShape> GetShape() const { return _collisionShape; }
Entity GetEntity() const { return _entity; }
void AddForce(const Vector3& force);
};
}
}

View File

@@ -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 <glm/trigonometric.hpp>
#include <src/Scene/Entities/Entity.h>
@@ -42,5 +44,10 @@ namespace Nuake
{
_entity = ent;
}
void RigidBody::AddForce(const Vector3& force)
{
PhysicsManager::Get().GetWorld()->AddForceToRigidBody(_entity, force);
}
}
}

View File

@@ -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<NameComponent>();
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<ParentComponent>();

View File

@@ -13,18 +13,18 @@ namespace Nuake {
Ref<Physics::RigidBody> 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;
}

View File

@@ -13,7 +13,7 @@ namespace Nuake {
{
public:
float Mass;
Ref<Physics::RigidBody> m_Rigidbody;
Ref<Physics::RigidBody> Rigidbody;
RigidBodyComponent();
Ref<Physics::RigidBody> GetRigidBody() const;
@@ -24,6 +24,7 @@ namespace Nuake {
void DrawShape(TransformComponent* tc);
void DrawEditor();
json Serialize()
{
BEGIN_SERIALIZE();

View File

@@ -31,7 +31,7 @@ namespace Nuake
template<typename T>
T& AddComponent() {
T& component = m_Scene->m_Registry.emplace<T>(m_EntityHandle);
T& component = m_Scene->m_Registry.emplace_or_replace <T>(m_EntityHandle);
return component;
}

View File

@@ -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;

View File

@@ -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<Physics::RigidBody> rigidBody;
if (rigidBodyComponent.GetRigidBody())
{
continue;
}
if (ent.HasComponent<BoxColliderComponent>())
{
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<ModelComponent>();
const auto& component = ent.GetComponent<MeshColliderComponent>();
@@ -293,6 +301,8 @@ namespace Nuake
PhysicsManager::Get().RegisterBody(rigidBody);
}
}
rigidBodyComponent.Rigidbody = rigidBody;
}
}

View File

@@ -14,7 +14,6 @@ namespace Nuake
void Exit() override;
private:
void InitializeShapes();
void InitializeQuakeMap();
void InitializeRigidbodies();

View File

@@ -8,8 +8,10 @@
#include <wren.h>
#include "../Core/Physics/PhysicsManager.h"
namespace Nuake {
namespace ScriptAPI {
namespace Nuake
{
namespace ScriptAPI
{
class PhysicsModule : public ScriptModule
{
std::string ModuleName = "Engine";

View File

@@ -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<TransformComponent>();
if (name == "Light") result = ent.HasComponent<LightComponent>();
if (name == "QuakeMap") result = ent.HasComponent<QuakeMapComponent>();
if (name == "RigidBody") result = ent.HasComponent<RigidBodyComponent>();
if (name == "CharacterController")
{
result = ent.HasComponent<CharacterControllerComponent>();
@@ -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>();
rigidBodyComponent.Rigidbody->AddForce(Vector3(x, y, z));
}
static void GetTranslation(WrenVM* vm)
{
double handle = wrenGetSlotDouble(vm, 1);