This commit is contained in:
Antoine Pilote
2024-04-02 09:29:07 -04:00
33 changed files with 751 additions and 312 deletions

View File

@@ -41,7 +41,7 @@ namespace Nuake
bool result = state == GLFW_PRESS;
// First time pressed?
if (m_Keys.find(keycode) == m_Keys.end() || m_Keys[keycode] == true)
if (m_Keys.find(keycode) == m_Keys.end() || m_Keys[keycode] == false)
{
if (result)
m_Keys[keycode] = true;

View File

@@ -0,0 +1,16 @@
#pragma once
#include <src/Core/Maths.h>
namespace Nuake {
namespace Physics {
struct CollisionData
{
uint32_t Entity1;
uint32_t Entity2;
Vector3 Normal;
Vector3 Position;
};
}
}

View File

@@ -72,24 +72,10 @@ namespace Nuake
static constexpr uint8_t NON_MOVING = 0;
static constexpr uint8_t MOVING = 1;
static constexpr uint8_t KINEMATIC = 2;
static constexpr uint8_t NUM_LAYERS = 3;
};
// Function that determines if two object layers can collide
static bool MyObjectCanCollide(JPH::ObjectLayer inObject1, JPH::ObjectLayer inObject2)
{
switch (inObject1)
{
case Layers::NON_MOVING:
return inObject2 == Layers::MOVING || inObject2 == Layers::KINEMATIC; // Non moving only collides with moving
case Layers::MOVING:
return true; // Moving collides with everything
case Layers::KINEMATIC:
return inObject2 == Layers::NON_MOVING || inObject2 == Layers::MOVING; // Only collides with non moving
default:
//JPH_ASSERT(false);
return false;
}
static constexpr uint8_t CHARACTER_GHOST = 3;
static constexpr uint8_t CHARACTER = 4;
static constexpr uint8_t SENSORS = 5;
static constexpr uint8_t NUM_LAYERS = 6;
};
// Each broadphase layer results in a separate bounding volume tree in the broad phase. You at least want to have
@@ -114,6 +100,9 @@ namespace Nuake
// Create a mapping table from object to broad phase layer
mObjectToBroadPhase[Layers::NON_MOVING] = BroadPhaseLayers::NON_MOVING;
mObjectToBroadPhase[Layers::MOVING] = BroadPhaseLayers::MOVING;
mObjectToBroadPhase[Layers::CHARACTER] = BroadPhaseLayers::MOVING;
mObjectToBroadPhase[Layers::CHARACTER_GHOST] = BroadPhaseLayers::MOVING;
mObjectToBroadPhase[Layers::SENSORS] = BroadPhaseLayers::MOVING;
}
virtual JPH::uint GetNumBroadPhaseLayers() const override
@@ -128,54 +117,51 @@ namespace Nuake
return mObjectToBroadPhase[inLayer];
}
#if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED)
virtual const char* GetBroadPhaseLayerName(BroadPhaseLayer inLayer) const override
{
switch ((BroadPhaseLayer::Type)inLayer)
{
case (BroadPhaseLayer::Type)BroadPhaseLayers::NON_MOVING: return "NON_MOVING";
case (BroadPhaseLayer::Type)BroadPhaseLayers::MOVING: return "MOVING";
default: JPH_ASSERT(false); return "INVALID";
}
}
#endif // JPH_EXTERNAL_PROFILE || JPH_PROFILE_ENABLED
private:
JPH::BroadPhaseLayer mObjectToBroadPhase[Layers::NUM_LAYERS];
};
// Function that determines if two broadphase layers can collide
static bool MyBroadPhaseCanCollide(JPH::ObjectLayer inLayer1, JPH::BroadPhaseLayer inLayer2)
{
using namespace JPH;
switch (inLayer1)
{
case Layers::NON_MOVING:
return inLayer2 == BroadPhaseLayers::MOVING;
case Layers::MOVING:
return true;
default:
JPH_ASSERT(false);
return false;
}
}
// An example contact listener
class MyContactListener : public JPH::ContactListener
{
private:
Physics::DynamicWorld* _World;
public:
MyContactListener(Physics::DynamicWorld* world)
: _World(world)
{
}
// See: ContactListener
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;
// Allows you to ignore a contact before it is created (using layers to not make objects collide is cheaper!)
return JPH::ValidateResult::AcceptAllContactsForThisBodyPair;
return JPH::ValidateResult::AcceptAllContactsForThisBodyPair;
}
virtual void OnContactAdded(const JPH::Body& inBody1, const JPH::Body& inBody2, const JPH::ContactManifold& inManifold, JPH::ContactSettings& ioSettings) override
{
//std::cout << "A contact was added" << std::endl;
int entity1 = static_cast<int>(inBody1.GetUserData());
int entity2 = static_cast<int>(inBody2.GetUserData());
JPH::Vec3 joltNormal = inManifold.mWorldSpaceNormal;
Vector3 normal = Vector3(joltNormal.GetX(), joltNormal.GetY(), joltNormal.GetZ());
JPH::Vec3 joltPos = inManifold.GetWorldSpaceContactPointOn1(0);
Vector3 position = Vector3(joltPos.GetX(), joltPos.GetY(), joltPos.GetZ());
Physics::CollisionData data
{
entity1,
entity2,
normal,
position
};
_World->RegisterCollisionCallback(std::move(data));
}
virtual void OnContactPersisted(const JPH::Body& inBody1, const JPH::Body& inBody2, const JPH::ContactManifold& inManifold, JPH::ContactSettings& ioSettings) override
@@ -215,8 +201,9 @@ namespace Nuake
return inLayer2 == BroadPhaseLayers::MOVING;
case Layers::MOVING:
return true;
case Layers::SENSORS:
return inLayer2 == BroadPhaseLayers::MOVING;;
default:
return false;
}
}
@@ -230,9 +217,15 @@ namespace Nuake
switch (inObject1)
{
case Layers::NON_MOVING:
return inObject2 == Layers::MOVING; // Non moving only collides with moving
return inObject2 == Layers::MOVING || inObject2 == Layers::CHARACTER_GHOST || inObject2 == Layers::CHARACTER; // Non moving only collides with moving
case Layers::MOVING:
return true; // Moving collides with everything
case Layers::CHARACTER_GHOST:
return inObject2 != Layers::CHARACTER;
case Layers::CHARACTER:
return inObject2 != Layers::CHARACTER_GHOST;
case Layers::SENSORS:
return inObject2 == Layers::MOVING || inObject2 == Layers::CHARACTER_GHOST;
default:
return false;
@@ -240,7 +233,6 @@ namespace Nuake
}
};
BPLayerInterfaceImpl JoltBroadphaseLayerInterface = BPLayerInterfaceImpl();
ObjectVsBroadPhaseLayerFilterImpl JoltObjectVSBroadphaseLayerFilter = ObjectVsBroadPhaseLayerFilterImpl();
ObjectLayerPairFilterImpl JoltObjectVSObjectLayerFilter;
@@ -249,7 +241,7 @@ namespace Nuake
{
DynamicWorld::DynamicWorld() : _stepCount(0)
{
_registeredCharacters = std::map<uint32_t, Ref<JPH::CharacterVirtual>>();
_registeredCharacters = std::map<uint32_t, CharacterGhostPair>();
// Initialize Jolt Physics
const uint32_t MaxBodies = 4096;
@@ -269,7 +261,7 @@ namespace Nuake
// A contact listener gets notified when bodies (are about to) collide, and when they separate again.
// Note that this is called from a job so whatever you do here needs to be thread safe.
// Registering one is entirely optional.
_contactListener = CreateScope<MyContactListener>();
_contactListener = CreateScope<MyContactListener>(this);
_JoltPhysicsSystem->SetContactListener(_contactListener.get());
// The main way to interact with the bodies in the physics system is through the body interface. There is a locking and a non-locking
@@ -309,12 +301,29 @@ namespace Nuake
layer = Layers::MOVING;
}
if (rb->IsTrigger())
{
layer = Layers::SENSORS;
motionType = JPH::EMotionType::Kinematic;
}
const auto& startPos = rb->GetPosition();
const Quat& bodyRotation = rb->GetRotation();
const auto& joltRotation = JPH::Quat(bodyRotation.x, bodyRotation.y, bodyRotation.z, bodyRotation.w);
const auto& joltPos = JPH::Vec3(startPos.x, startPos.y, startPos.z);
auto joltShape = GetJoltShape(rb->GetShape());
JPH::Ref<JPH::Shape> joltShape = GetJoltShape(rb->GetShape());
if (!joltShape)
{
return;
}
JPH::BodyCreationSettings bodySettings(joltShape, joltPos, joltRotation, motionType, layer);
bodySettings.mIsSensor = rb->IsTrigger();
if (bodySettings.mIsSensor)
{
bodySettings.mCollideKinematicVsNonDynamic = true;
}
bodySettings.mAllowedDOFs = (JPH::EAllowedDOFs::All);
@@ -354,7 +363,7 @@ namespace Nuake
bodySettings.mUserData = entityId;
// 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
uint32_t bodyIndex = (uint32_t)body.GetIndex();
uint32_t bodyIndex = (uint32_t)body.GetIndexAndSequenceNumber();
_registeredBodies.push_back(bodyIndex);
}
@@ -372,15 +381,38 @@ namespace Nuake
settings->mPenetrationRecoverySpeed = 1.0f;
settings->mPredictiveContactDistance = 0.01f;
settings->mShape = GetJoltShape(cc->Shape);
auto joltPosition = JPH::Vec3(cc->Position.x, cc->Position.y, cc->Position.z);
const Quat& bodyRotation = cc->Rotation;
const auto& joltRotation = JPH::Quat(bodyRotation.x, bodyRotation.y, bodyRotation.z, bodyRotation.w);
auto character = CreateRef<JPH::CharacterVirtual>(settings, std::move(joltPosition), std::move(joltRotation), _JoltPhysicsSystem.get());
auto character = CreateRef<JPH::CharacterVirtual>(settings, std::move(joltPosition), joltRotation, _JoltPhysicsSystem.get());
// add ghost kinematic body to respond to hit test as the virtual char are not present in the world.
JPH::BodyInterface& bodyInterface = _JoltPhysicsSystem->GetBodyInterface();
const float mass = 0.0f;
JPH::EMotionType motionType = JPH::EMotionType::Dynamic;
JPH::ObjectLayer layer = Layers::CHARACTER_GHOST;
const auto& startPos = joltPosition;
auto joltShape = GetJoltShape(cc->Shape);
JPH::BodyCreationSettings bodySettings(joltShape, startPos, joltRotation, motionType, layer);
int entityId = cc->GetEntity().GetID();
if (entityId == 0)
{
Logger::Log("ERROR");
}
bodySettings.mUserData = cc->Owner.GetHandle();
// 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
uint32_t bodyIndex = body.GetIndexAndSequenceNumber();
//_registeredBodies.push_back(bodyIndex);
// To get the jolt character control from a scene entity.
_registeredCharacters[cc->Owner.GetHandle()] = character;
_registeredCharacters[cc->Owner.GetHandle()] = CharacterGhostPair{ character, bodyIndex };
}
bool DynamicWorld::IsCharacterGrounded(const Entity& entity)
@@ -388,7 +420,7 @@ namespace Nuake
const uint32_t entityHandle = entity.GetHandle();
if (_registeredCharacters.find(entityHandle) != _registeredCharacters.end())
{
auto& characterController = _registeredCharacters[entityHandle];
auto& characterController = _registeredCharacters[entityHandle].Character;
const auto groundState = characterController->GetGroundState();
return groundState == JPH::CharacterBase::EGroundState::OnGround;
@@ -398,6 +430,16 @@ namespace Nuake
return false;
}
void DynamicWorld::SetCharacterControllerPosition(const Entity & entity, const Vector3 & position)
{
const uint32_t entityHandle = entity.GetHandle();
if (_registeredCharacters.find(entityHandle) != _registeredCharacters.end())
{
auto& characterController = _registeredCharacters[entityHandle].Character;
characterController->SetPosition({ position.x, position.y, position.z });
}
}
std::vector<RaycastResult> DynamicWorld::Raycast(const Vector3& from, const Vector3& to)
{
// Create jolt ray
@@ -442,28 +484,27 @@ namespace Nuake
for (const auto& body : _registeredBodies)
{
auto bodyId = static_cast<JPH::BodyID>(body);
JPH::Vec3 position = bodyInterface.GetCenterOfMassPosition(bodyId);
JPH::Vec3 velocity = bodyInterface.GetLinearVelocity(bodyId);
JPH::Mat44 joltTransform = bodyInterface.GetWorldTransform(bodyId);
const auto bodyRotation = bodyInterface.GetRotation(bodyId);
Matrix4 transform = glm::mat4(
joltTransform(0, 0), joltTransform(1, 0), joltTransform(2, 0), joltTransform(3, 0),
joltTransform(0, 1), joltTransform(1, 1), joltTransform(2, 1), joltTransform(3, 1),
joltTransform(0, 2), joltTransform(1, 2), joltTransform(2, 2), joltTransform(3, 2),
joltTransform(0, 3), joltTransform(1, 3), joltTransform(2, 3), joltTransform(3, 3)
);
Vector3 scale = Vector3();
Quat rotation = Quat();
Vector3 pos = Vector3();
Vector3 skew = Vector3();
Vector4 pesp = Vector4();
glm::decompose(transform, scale, rotation, pos, skew, pesp);
auto entId = static_cast<int>(bodyInterface.GetUserData(bodyId));
if (entId != 0)
if (auto entId = static_cast<int>(bodyInterface.GetUserData(bodyId)); entId != 0)
{
JPH::Vec3 position = bodyInterface.GetCenterOfMassPosition(bodyId);
JPH::Vec3 velocity = bodyInterface.GetLinearVelocity(bodyId);
JPH::Mat44 joltTransform = bodyInterface.GetWorldTransform(bodyId);
const auto bodyRotation = bodyInterface.GetRotation(bodyId);
Matrix4 transform = glm::mat4(
joltTransform(0, 0), joltTransform(1, 0), joltTransform(2, 0), joltTransform(3, 0),
joltTransform(0, 1), joltTransform(1, 1), joltTransform(2, 1), joltTransform(3, 1),
joltTransform(0, 2), joltTransform(1, 2), joltTransform(2, 2), joltTransform(3, 2),
joltTransform(0, 3), joltTransform(1, 3), joltTransform(2, 3), joltTransform(3, 3)
);
Vector3 scale = Vector3();
Quat rotation = Quat();
Vector3 pos = Vector3();
Vector3 skew = Vector3();
Vector4 pesp = Vector4();
glm::decompose(transform, scale, rotation, pos, skew, pesp);
Entity entity = Engine::GetCurrentScene()->GetEntityByID(entId);
auto& transformComponent = entity.GetComponent<TransformComponent>();
transformComponent.SetLocalPosition(pos);
@@ -476,15 +517,11 @@ namespace Nuake
void DynamicWorld::SyncCharactersTransforms()
{
// TODO(ANTO): Finish this to connect updated jolt transforms back to the entity.
// The problem was that I dont know yet how to go from jolt body ptr to the entity
// Combinations of find and iterators etc. I do not have the brain power rn zzz.
// const auto& bodyInterface = _JoltPhysicsSystem->GetBodyInterface();
for (const auto& e : _registeredCharacters)
{
Entity entity { (entt::entity)e.first, Engine::GetCurrentScene().get()};
Ref<JPH::CharacterVirtual> characterController = e.second;
Ref<JPH::CharacterVirtual> characterController = e.second.Character;
JPH::Mat44 joltTransform = characterController->GetWorldTransform();
const auto bodyRotation = characterController->GetRotation();
@@ -512,6 +549,12 @@ namespace Nuake
void DynamicWorld::StepSimulation(Timestep ts)
{
// Clear collisions, before very step
{
std::scoped_lock<std::mutex> lock(_CollisionCallbackMutex);
_CollisionCallbacks.clear();
}
if (ts > 0.1f)
{
ts = 0.08f;
@@ -529,7 +572,7 @@ namespace Nuake
if(ts > minStepDuration)
{
#ifdef NK_DEBUG
Logger::Log("Large step detected: " + std::to_string(ts), "physics", WARNING);
//Logger::Log("Large step detected: " + std::to_string(ts), "physics", WARNING);
#endif
collisionSteps = static_cast<float>(ts) / minStepDuration;
}
@@ -562,7 +605,7 @@ namespace Nuake
auto characterController = characterControllerComponent.GetCharacterController();
const auto& broadPhaseLayerFilter = _JoltPhysicsSystem->GetDefaultBroadPhaseLayerFilter(Layers::NON_MOVING);
const auto& LayerFilter = _JoltPhysicsSystem->GetDefaultLayerFilter(Layers::MOVING);
const auto& LayerFilter = _JoltPhysicsSystem->GetDefaultLayerFilter(Layers::CHARACTER);
const auto& joltGravity = _JoltPhysicsSystem->GetGravity();
auto& tempAllocatorPtr = *(joltTempAllocator);
if (characterController->AutoStepping)
@@ -574,12 +617,33 @@ namespace Nuake
joltUpdateSettings.mWalkStairsStepForwardTest = characterController->StepDistance;
joltUpdateSettings.mWalkStairsMinStepForward = characterController->StepMinDistance;
c.second->ExtendedUpdate(ts, joltGravity, joltUpdateSettings, broadPhaseLayerFilter, LayerFilter, { }, { }, tempAllocatorPtr);
c.second.Character->ExtendedUpdate(ts, joltGravity, joltUpdateSettings, broadPhaseLayerFilter, LayerFilter, { }, { }, tempAllocatorPtr);
}
else
{
c.second->Update(ts, joltGravity, broadPhaseLayerFilter, LayerFilter, {}, {}, tempAllocatorPtr);
c.second.Character->Update(ts, joltGravity, broadPhaseLayerFilter, LayerFilter, {}, {}, tempAllocatorPtr);
}
uint32_t ghostId = c.second.Ghost;
JPH::Mat44 joltTransform = c.second.Character->GetWorldTransform();
const auto bodyRotation = c.second.Character->GetRotation();
Matrix4 transform = glm::mat4(
joltTransform(0, 0), joltTransform(1, 0), joltTransform(2, 0), joltTransform(3, 0),
joltTransform(0, 1), joltTransform(1, 1), joltTransform(2, 1), joltTransform(3, 1),
joltTransform(0, 2), joltTransform(1, 2), joltTransform(2, 2), joltTransform(3, 2),
joltTransform(0, 3), joltTransform(1, 3), joltTransform(2, 3), joltTransform(3, 3)
);
Vector3 scale = Vector3();
Quat rotation = Quat();
Vector3 pos = Vector3();
Vector3 skew = Vector3();
Vector4 pesp = Vector4();
glm::decompose(transform, scale, rotation, pos, skew, pesp);
//auto& bodyInterface = _JoltPhysicsSystem->GetBodyInterfaceNoLock();
_JoltBodyInterface->MoveKinematic(static_cast<JPH::BodyID>(ghostId), JPH::Vec3{ pos.x, pos.y, pos.z }, { rotation.x, rotation.y, rotation.z, rotation.w }, ts);
}
}
@@ -590,6 +654,11 @@ namespace Nuake
Logger::Log("Failed to run simulation update", "physics", CRITICAL);
}
for (auto& c : _registeredCharacters)
{
}
SyncEntitiesTranforms();
SyncCharactersTransforms();
}
@@ -615,13 +684,36 @@ namespace Nuake
}
}
void DynamicWorld::RegisterCollisionCallback(const CollisionData& data)
{
// This will be called from multiple threads
std::scoped_lock<std::mutex> lock(_CollisionCallbackMutex);
_CollisionCallbacks.push_back(std::move(data));
}
const std::vector<CollisionData>& DynamicWorld::GetCollisionsData()
{
std::scoped_lock<std::mutex> lock(_CollisionCallbackMutex);
return _CollisionCallbacks;
}
void DynamicWorld::MoveAndSlideCharacterController(const Entity& entity, const Vector3& velocity)
{
const uint32_t entityHandle = entity.GetHandle();
if (_registeredCharacters.find(entityHandle) != _registeredCharacters.end())
{
auto& characterController = _registeredCharacters[entityHandle];
characterController->SetLinearVelocity(JPH::Vec3(velocity.x, velocity.y, velocity.z));
auto& characterController = _registeredCharacters[entityHandle].Character;
const auto& joltVelocity = JPH::Vec3(velocity.x, velocity.y, velocity.z);
characterController->SetLinearVelocity(joltVelocity);
auto& ghost = _registeredCharacters[entityHandle].Ghost;
auto ghostPos = _JoltBodyInterface->GetPosition(static_cast<JPH::BodyID>(ghost));
//std::cout << "Ghost pos: " << ghostPos.GetX() << ", " << ghostPos.GetY() << ", " << ghostPos.GetZ() << std::endl;
auto charPos = characterController->GetPosition();
//std::cout << "Char pos: " << charPos.GetX() << ", " << charPos.GetY() << ", " << charPos.GetZ() << std::endl;
//_JoltBodyInterface->SetLinearVelocity(static_cast<JPH::BodyID>(ghost), joltVelocity);
}
}
@@ -631,7 +723,7 @@ namespace Nuake
for (const auto& body : _registeredBodies)
{
auto bodyId = static_cast<JPH::BodyID>(body);
auto entityId = static_cast<uint32_t>(bodyInterface.GetUserData(bodyId));
auto entityId = bodyInterface.GetUserData(bodyId);
if (entityId == entity.GetID())
{
bodyInterface.AddForce(bodyId, JPH::Vec3(force.x, force.y, force.z));
@@ -728,6 +820,14 @@ namespace Nuake
break;
}
if (!result.IsValid())
{
const std::string errorMessage = std::string("Failed to create physics shape: ") + result.GetError().c_str();
Logger::Log(errorMessage, "physics", WARNING);
return nullptr;
}
return result.Get();
}
}

View File

@@ -9,9 +9,11 @@
#include <src/Physics/GhostObject.h>
#include "CharacterController.h"
#include "CollisionData.h"
#include "Jolt/Jolt.h"
#include <mutex>
namespace JPH
{
@@ -35,6 +37,14 @@ namespace Nuake
namespace Physics
{
struct CharacterGhostPair
{
Ref<JPH::CharacterVirtual> Character;
uint32_t Ghost;
};
class DynamicWorld
{
private:
@@ -48,8 +58,10 @@ namespace Nuake
BPLayerInterfaceImpl* _JoltBroadphaseLayerInterface;
std::vector<uint32_t> _registeredBodies;
std::map<uint32_t, Ref<JPH::CharacterVirtual>> _registeredCharacters;
std::map<uint32_t, CharacterGhostPair> _registeredCharacters;
std::mutex _CollisionCallbackMutex;
std::vector<CollisionData> _CollisionCallbacks;
public:
DynamicWorld();
@@ -61,6 +73,8 @@ namespace Nuake
void AddGhostbody(Ref<GhostObject> gb);
void AddCharacterController(Ref<CharacterController> cc);
bool IsCharacterGrounded(const Entity& entity);
void SetCharacterControllerPosition(const Entity& entity, const Vector3& position);
// 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 AddForceToRigidBody(Entity& entity, const Vector3& force);
@@ -69,6 +83,8 @@ namespace Nuake
void StepSimulation(Timestep ts);
void Clear();
void RegisterCollisionCallback(const CollisionData& data);
const std::vector<CollisionData>& GetCollisionsData();
private:
JPH::Ref<JPH::Shape> GetJoltShape(const Ref<PhysicShape> shape);
void SyncEntitiesTranforms();

View File

@@ -27,6 +27,11 @@ namespace Nuake
m_World->AddCharacterController(cc);
}
void PhysicsManager::SetCharacterControllerPosition(const Entity& entity, const Vector3& position)
{
m_World->SetCharacterControllerPosition(entity, position);
}
void PhysicsManager::Step(Timestep ts)
{
m_World->StepSimulation(ts);
@@ -42,6 +47,11 @@ namespace Nuake
return m_World->Raycast(from, to);
}
const std::vector<Physics::CollisionData>& PhysicsManager::GetCollisions()
{
return m_World->GetCollisionsData();
}
void PhysicsManager::DrawDebug()
{
if (m_DrawDebug)

View File

@@ -3,6 +3,7 @@
#include "../Scene/Entities/Entity.h"
#include "DynamicWorld.h"
#include "Rigibody.h"
#include "CollisionData.h"
#include "RaycastResult.h"
@@ -49,8 +50,12 @@ namespace Nuake
std::vector<RaycastResult> Raycast(const Vector3& from, const Vector3& to);
const std::vector<Physics::CollisionData>& GetCollisions();
void RegisterBody(Ref<Physics::RigidBody> rb);
void RegisterGhostBody(Ref<GhostObject> rb);
void RegisterCharacterController(Ref<Physics::CharacterController> c);
void SetCharacterControllerPosition(const Entity& entity, const Vector3& position);
};
}

View File

@@ -20,6 +20,7 @@ namespace Nuake
Quat _rotation;
Entity _entity;
bool _isTrigger = false;
bool m_LockXAxis = false;
bool m_LockYAxis = false;
bool m_LockZAxis = false;
@@ -33,13 +34,16 @@ namespace Nuake
void UpdateTransform();
void SetIsTrigger(bool isTrigger) { _isTrigger = isTrigger; }
bool IsTrigger() const { return _isTrigger; }
bool GetLockXAxis() const { return m_LockXAxis; }
bool GetLockYAxis() const { return m_LockYAxis; }
bool GetLockZAxis() const { return m_LockZAxis; }
void setLockXAxis(bool lock) { m_LockXAxis = lock; }
void setLockYAxis(bool lock) { m_LockYAxis = lock; }
void setLockZAxis(bool lock) { m_LockZAxis = lock; }
void SetLockXAxis(bool lock) { m_LockXAxis = lock; }
void SetLockYAxis(bool lock) { m_LockYAxis = lock; }
void SetLockZAxis(bool lock) { m_LockZAxis = lock; }
void SetEntityID(Entity ent);
Vector3 GetPosition() const { return _position; }

View File

@@ -235206,13 +235206,17 @@ const std::string Resources_Shaders_gizmo_shader_path = R"(Resources/Shaders/giz
0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63,
0x34, 0x28, 0x31, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x75,
0x5f, 0x4f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x29, 0x3b, 0x0d, 0x0a,
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x45, 0x6e, 0x74, 0x69, 0x74,
0x79, 0x49, 0x44, 0x20, 0x3d, 0x20, 0x75, 0x5f, 0x45, 0x6e, 0x74, 0x69,
0x74, 0x79, 0x49, 0x44, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d,
0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0d, 0x0a, 0x7d
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x28, 0x75, 0x5f, 0x4f,
0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x20, 0x3e, 0x3d, 0x20, 0x30, 0x2e,
0x35, 0x66, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0d, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x45, 0x6e, 0x74,
0x69, 0x74, 0x79, 0x49, 0x44, 0x20, 0x3d, 0x20, 0x75, 0x5f, 0x45, 0x6e,
0x74, 0x69, 0x74, 0x79, 0x49, 0x44, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x46, 0x72,
0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x63, 0x6f,
0x6c, 0x6f, 0x72, 0x3b, 0x0d, 0x0a, 0x7d
};
unsigned int Resources_Shaders_gizmo_shader_len = 994;
unsigned int Resources_Shaders_gizmo_shader_len = 1039;
// Data for file: Resources_Shaders_line_shader_path
const std::string Resources_Shaders_line_shader_path = R"(Resources/Shaders/line.shader)";
@@ -235325,66 +235329,80 @@ const std::string Resources_Shaders_outline_shader_path = R"(Resources/Shaders/o
0x61, 0x74, 0x20, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x20, 0x3d, 0x20,
0x34, 0x2e, 0x66, 0x3b, 0x0d, 0x0a, 0x09, 0x76, 0x65, 0x63, 0x32, 0x20,
0x75, 0x76, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x55, 0x56, 0x3b, 0x0d, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f,
0x20, 0x43, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x61, 0x73, 0x70,
0x65, 0x63, 0x74, 0x20, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x0d, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x61, 0x73, 0x70, 0x65,
0x63, 0x74, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x2f, 0x20, 0x76,
0x65, 0x63, 0x32, 0x28, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53,
0x69, 0x7a, 0x65, 0x28, 0x75, 0x5f, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79,
0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x30, 0x29, 0x29,
0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0d, 0x0a, 0x09, 0x76, 0x65,
0x63, 0x34, 0x20, 0x66, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72,
0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x30, 0x2e, 0x30, 0x2c,
0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30,
0x2e, 0x30, 0x66, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20,
0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30,
0x2e, 0x30, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x54, 0x41, 0x55, 0x3b,
0x20, 0x69, 0x20, 0x2b, 0x3d, 0x20, 0x54, 0x41, 0x55, 0x20, 0x2f, 0x20,
0x73, 0x74, 0x65, 0x70, 0x73, 0x29, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x53, 0x61, 0x6d,
0x70, 0x6c, 0x65, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x69, 0x6e,
0x20, 0x61, 0x20, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x20,
0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x0d, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x6f, 0x66,
0x66, 0x73, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28,
0x73, 0x69, 0x6e, 0x28, 0x69, 0x29, 0x2c, 0x20, 0x63, 0x6f, 0x73, 0x28,
0x69, 0x29, 0x29, 0x20, 0x2a, 0x20, 0x61, 0x73, 0x70, 0x65, 0x63, 0x74,
0x20, 0x2a, 0x20, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3b, 0x0d, 0x0a,
0x09, 0x09, 0x75, 0x69, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6c, 0x20, 0x3d,
0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x75, 0x5f, 0x45,
0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65,
0x2c, 0x20, 0x75, 0x76, 0x20, 0x2b, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65,
0x74, 0x29, 0x2e, 0x72, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x0d, 0x0a, 0x09,
0x09, 0x2f, 0x2f, 0x20, 0x4d, 0x69, 0x78, 0x20, 0x6f, 0x75, 0x74, 0x6c,
0x69, 0x6e, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x62, 0x61, 0x63,
0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x0d, 0x0a, 0x09, 0x09, 0x66,
0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x20, 0x3d,
0x20, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x73, 0x74, 0x65, 0x70, 0x28,
0x30, 0x2e, 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x37, 0x2c, 0x20, 0x69, 0x6e,
0x74, 0x28, 0x63, 0x6f, 0x6c, 0x20, 0x21, 0x3d, 0x20, 0x74, 0x61, 0x72,
0x67, 0x65, 0x74, 0x29, 0x20, 0x2a, 0x20, 0x31, 0x30, 0x2e, 0x30, 0x66,
0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x72, 0x61, 0x67, 0x43, 0x6f,
0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x6d, 0x69, 0x78, 0x28, 0x66, 0x72,
0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x75, 0x5f, 0x4f,
0x75, 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c,
0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x7d,
0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x28,
0x66, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x61, 0x20,
0x3e, 0x20, 0x30, 0x2e, 0x31, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66,
0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x61, 0x20, 0x3d,
0x20, 0x31, 0x2e, 0x30, 0x66, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d,
0x20, 0x6d, 0x69, 0x78, 0x28, 0x76, 0x65, 0x63, 0x34, 0x28, 0x30, 0x29,
0x2c, 0x20, 0x66, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c,
0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x75, 0x5f, 0x45,
0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65,
0x2c, 0x20, 0x75, 0x76, 0x29, 0x2e, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x74,
0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a
0x20, 0x20, 0x20, 0x20, 0x0d, 0x0a, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x61,
0x6d, 0x70, 0x6c, 0x65, 0x20, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x0d,
0x0a, 0x09, 0x75, 0x69, 0x6e, 0x74, 0x20, 0x6d, 0x69, 0x64, 0x64, 0x6c,
0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x65,
0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x75, 0x5f, 0x45, 0x6e, 0x74, 0x69,
0x74, 0x79, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x75,
0x76, 0x29, 0x2e, 0x72, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x2f, 0x2f, 0x20, 0x43, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20,
0x61, 0x73, 0x70, 0x65, 0x63, 0x74, 0x20, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x61,
0x73, 0x70, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x20,
0x2f, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x74, 0x65, 0x78, 0x74, 0x75,
0x72, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x28, 0x75, 0x5f, 0x45, 0x6e, 0x74,
0x69, 0x74, 0x79, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20,
0x30, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0d, 0x0a,
0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x68, 0x61, 0x73, 0x48, 0x69,
0x74, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x66, 0x3b, 0x0d, 0x0a, 0x09,
0x76, 0x65, 0x63, 0x34, 0x20, 0x66, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c,
0x6f, 0x72, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x30, 0x2e,
0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c,
0x20, 0x30, 0x2e, 0x30, 0x66, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x66, 0x6f,
0x72, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x69, 0x20, 0x3d,
0x20, 0x30, 0x2e, 0x30, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x54, 0x41,
0x55, 0x3b, 0x20, 0x69, 0x20, 0x2b, 0x3d, 0x20, 0x54, 0x41, 0x55, 0x20,
0x2f, 0x20, 0x73, 0x74, 0x65, 0x70, 0x73, 0x29, 0x20, 0x0d, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x53,
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20,
0x69, 0x6e, 0x20, 0x61, 0x20, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6c, 0x61,
0x72, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x0d, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20,
0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63,
0x32, 0x28, 0x73, 0x69, 0x6e, 0x28, 0x69, 0x29, 0x2c, 0x20, 0x63, 0x6f,
0x73, 0x28, 0x69, 0x29, 0x29, 0x20, 0x2a, 0x20, 0x61, 0x73, 0x70, 0x65,
0x63, 0x74, 0x20, 0x2a, 0x20, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3b,
0x0d, 0x0a, 0x09, 0x09, 0x75, 0x69, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6c,
0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x75,
0x5f, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x65, 0x78, 0x74, 0x75,
0x72, 0x65, 0x2c, 0x20, 0x75, 0x76, 0x20, 0x2b, 0x20, 0x6f, 0x66, 0x66,
0x73, 0x65, 0x74, 0x29, 0x2e, 0x72, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x0d,
0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x63, 0x6f, 0x6c, 0x20, 0x3d, 0x3d,
0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x0d, 0x0a, 0x09, 0x09,
0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x68, 0x61, 0x73, 0x48, 0x69, 0x74,
0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x66, 0x3b, 0x0d, 0x0a, 0x09, 0x09,
0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x4d, 0x69,
0x78, 0x20, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x69,
0x74, 0x68, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e,
0x64, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x20, 0x3d, 0x20, 0x73, 0x6d, 0x6f, 0x6f, 0x74,
0x68, 0x73, 0x74, 0x65, 0x70, 0x28, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x30,
0x2e, 0x39, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x28, 0x63, 0x6f, 0x6c, 0x20,
0x21, 0x3d, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x20, 0x2a,
0x20, 0x68, 0x61, 0x73, 0x48, 0x69, 0x74, 0x20, 0x2a, 0x20, 0x31, 0x30,
0x2e, 0x30, 0x66, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x72, 0x61,
0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x6d, 0x69, 0x78,
0x28, 0x66, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20,
0x75, 0x5f, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6c,
0x6f, 0x72, 0x2c, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x29, 0x3b, 0x0d,
0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x69, 0x66, 0x28, 0x66, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72,
0x2e, 0x61, 0x20, 0x3e, 0x20, 0x30, 0x2e, 0x31, 0x29, 0x0d, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x66, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e,
0x61, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x66, 0x3b, 0x0d, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0d, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f,
0x72, 0x20, 0x3d, 0x20, 0x6d, 0x69, 0x78, 0x28, 0x76, 0x65, 0x63, 0x34,
0x28, 0x30, 0x29, 0x2c, 0x20, 0x66, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c,
0x6f, 0x72, 0x2c, 0x20, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x53, 0x61,
0x6d, 0x70, 0x6c, 0x65, 0x20, 0x21, 0x3d, 0x20, 0x74, 0x61, 0x72, 0x67,
0x65, 0x74, 0x20, 0x26, 0x26, 0x20, 0x68, 0x61, 0x73, 0x48, 0x69, 0x74,
0x20, 0x3e, 0x20, 0x30, 0x2e, 0x30, 0x66, 0x29, 0x3b, 0x0d, 0x0a, 0x7d,
0x0d, 0x0a
};
unsigned int Resources_Shaders_outline_shader_len = 1260;
unsigned int Resources_Shaders_outline_shader_len = 1418;
// Data for file: Resources_Shaders_pbr_shader_path
const std::string Resources_Shaders_pbr_shader_path = R"(Resources/Shaders/pbr.shader)";

View File

@@ -52,12 +52,6 @@ namespace Nuake
{
auto [transform, brush] = brushes.get<TransformComponent, BSPBrushComponent>(e);
for (auto& r : brush.Rigidbody)
{
//r->m_Transform->setOrigin(btVector3(transform.GlobalTranslation.x, transform.GlobalTranslation.y, transform.GlobalTranslation.z));
//r->UpdateTransform(*r->m_Transform);
}
if (!brush.IsFunc)
continue;
@@ -73,37 +67,6 @@ namespace Nuake
}
}
}
//auto bspTriggerView = m_Scene->m_Registry.view<TransformComponent, BSPBrushComponent, TriggerZone>();
//for (auto e : bspTriggerView)
//{
// auto [transform, brush, trigger] = bspTriggerView.get<TransformComponent, BSPBrushComponent, TriggerZone>(e);
// trigger.GhostObject->ScanOverlap();
// brush.Targets.clear();
// auto targetnameView = m_Scene->m_Registry.view<TransformComponent, NameComponent>();
// for (auto e2 : targetnameView)
// {
// auto [ttransform, name] = targetnameView.get<TransformComponent, NameComponent>(e2);
// if (name.Name == brush.target) {
// brush.Targets.push_back(Entity{ e2, m_Scene });
// }
// }
//}
/*auto physicGroup = m_Scene->m_Registry.view<TransformComponent, RigidBodyComponent>();
for (auto e : physicGroup) {
auto [transform, rb] = physicGroup.get<TransformComponent, RigidBodyComponent>(e);
rb.SyncTransformComponent(&m_Scene->m_Registry.get<TransformComponent>(e));
}*/
//auto ccGroup = m_Scene->m_Registry.view<TransformComponent, CharacterControllerComponent>();
//for (auto e : ccGroup) {
// auto [transform, rb] = ccGroup.get<TransformComponent, CharacterControllerComponent>(e);
// rb.SyncWithTransform(m_Scene->m_Registry.get<TransformComponent>(e));
//}
}
void PhysicsSystem::FixedUpdate(Timestep ts)
@@ -219,6 +182,8 @@ namespace Nuake
Entity ent = Entity({ e, m_Scene });
Ref<Physics::RigidBody> rigidBody;
Ref<Physics::PhysicShape> shape;
bool isTrigger = false;
if (rigidBodyComponent.GetRigidBody())
{
continue;
@@ -227,6 +192,7 @@ namespace Nuake
if (ent.HasComponent<BoxColliderComponent>())
{
BoxColliderComponent& boxComponent = ent.GetComponent<BoxColliderComponent>();
isTrigger = boxComponent.IsTrigger;
shape = CreateRef<Physics::Box>(boxComponent.Size);
}
@@ -235,6 +201,7 @@ namespace Nuake
auto& capsuleComponent = ent.GetComponent<CapsuleColliderComponent>();
float radius = capsuleComponent.Radius;
float height = capsuleComponent.Height;
isTrigger = capsuleComponent.IsTrigger;
shape = CreateRef<Physics::Capsule>(radius, height);
}
@@ -243,12 +210,14 @@ namespace Nuake
auto& cylinderComponent = ent.GetComponent<CylinderColliderComponent>();
float radius = cylinderComponent.Radius;
float height = cylinderComponent.Height;
isTrigger = cylinderComponent.IsTrigger;
shape = CreateRef<Physics::Cylinder>(radius, height);
}
if (ent.HasComponent<SphereColliderComponent>())
{
const auto& component = ent.GetComponent<SphereColliderComponent>();
isTrigger = component.IsTrigger;
shape = CreateRef<Physics::Sphere>(component.Radius);
}
@@ -262,6 +231,8 @@ namespace Nuake
const auto& modelComponent = ent.GetComponent<ModelComponent>();
const auto& component = ent.GetComponent<MeshColliderComponent>();
isTrigger = component.IsTrigger;
if (modelComponent.ModelResource)
{
uint32_t subMeshId = component.SubMesh;
@@ -282,10 +253,14 @@ namespace Nuake
}
rigidBody = CreateRef<Physics::RigidBody>(rigidBodyComponent.Mass, transform.GetGlobalPosition(), transform.GetGlobalRotation(), transform.GetGlobalTransform(), shape, ent);
rigidBody->setLockXAxis(rigidBodyComponent.LockX);
rigidBody->setLockYAxis(rigidBodyComponent.LockY);
rigidBody->setLockZAxis(rigidBodyComponent.LockZ);
rigidBody->SetLockXAxis(rigidBodyComponent.LockX);
rigidBody->SetLockYAxis(rigidBodyComponent.LockY);
rigidBody->SetLockZAxis(rigidBodyComponent.LockZ);
rigidBody->SetIsTrigger(isTrigger);
PhysicsManager::Get().RegisterBody(rigidBody);
rigidBodyComponent.Rigidbody = rigidBody;
}
}

View File

@@ -5,7 +5,7 @@
#include "Engine.h"
#include "src/Scripting/ScriptingEngineNet.h"
#include "src/Physics/PhysicsManager.h"
namespace Nuake
{
@@ -52,13 +52,22 @@ namespace Nuake
if (netScriptComponent.ScriptPath.empty())
continue;
// Creates an instance of the entity script in C#
auto entity = Entity{ e, m_Scene };
scriptingEngineNet.RegisterEntityScript(entity);
// We can now call on init on it.
auto scriptInstance = scriptingEngineNet.GetEntityScript(entity);
scriptInstance.InvokeMethod("OnInit");
// Creates an instance of the entity script in C#
scriptingEngineNet.RegisterEntityScript(entity);
}
for (auto& e : netEntities)
{
auto entity = Entity{ e, m_Scene };
if (entity.IsValid() && scriptingEngineNet.HasEntityScriptInstance(entity))
{
// We can now call on init on it.
auto scriptInstance = scriptingEngineNet.GetEntityScript(entity);
scriptInstance.InvokeMethod("OnInit");
}
}
return true;
@@ -91,6 +100,8 @@ namespace Nuake
auto scriptInstance = scriptingEngineNet.GetEntityScript(entity);
scriptInstance.InvokeMethod("OnUpdate", ts.GetSeconds());
}
DispatchPhysicCallbacks();
}
void ScriptingSystem::FixedUpdate(Timestep ts)
@@ -157,4 +168,23 @@ namespace Nuake
ScriptingEngine::Close();
ScriptingEngineNet::Get().Uninitialize();
}
void ScriptingSystem::DispatchPhysicCallbacks()
{
auto& scriptingEngineNet = ScriptingEngineNet::Get();
auto& physicsManager = PhysicsManager::Get();
const auto& collisions = physicsManager.GetCollisions();
for (const auto& col : collisions)
{
Entity entity1 = m_Scene->GetEntityByID(col.Entity1);
Entity entity2 = m_Scene->GetEntityByID(col.Entity2);
if (entity1.IsValid() && scriptingEngineNet.HasEntityScriptInstance(entity1))
{
auto scriptInstance = scriptingEngineNet.GetEntityScript(entity1);
scriptInstance.InvokeMethod("OnCollisionInternal", (int)col.Entity1, (int)col.Entity2);
}
}
}
}

View File

@@ -13,5 +13,8 @@ namespace Nuake {
void Draw() override {}
void FixedUpdate(Timestep ts) override;
void Exit() override;
private:
void DispatchPhysicCallbacks();
};
}

View File

@@ -2,9 +2,9 @@
namespace Nuake {
void Log(Coral::NativeString string)
void Log(Coral::String string)
{
Logger::Log(string.ToString(), ".net", VERBOSE);
Logger::Log(string, ".net", VERBOSE);
}
void EngineNetAPI::RegisterMethods()

View File

@@ -2,25 +2,45 @@
#include "src/Core/Input.h"
#include <Coral/NativeArray.hpp>
#include <Coral/Array.hpp>
namespace Nuake {
void ShowMouse(bool visible)
{
if (visible)
{
Input::ShowMouse();
}
else
{
Input::HideMouse();
}
}
bool IsKeyDown(int keyCode)
{
return Input::IsKeyDown(keyCode);
}
Coral::NativeArray<float> GetMousePosition()
bool IsKeyPressed(int keyCode)
{
return Input::IsKeyPressed(keyCode);
}
Coral::Array<float> GetMousePosition()
{
Vector2 mousePosition = Input::GetMousePosition();
return { mousePosition.x, mousePosition.y};
return Coral::Array<float>::New({ mousePosition.x, mousePosition.y });
}
void InputNetAPI::RegisterMethods()
{
RegisterMethod("Input.ShowMouseIcall", &ShowMouse);
RegisterMethod("Input.IsKeyDownIcall", &IsKeyDown);
RegisterMethod("Input.IsKeyPressedIcall", &IsKeyPressed);
RegisterMethod("Input.GetMousePositionIcall", &GetMousePosition);
}

View File

@@ -2,7 +2,7 @@
#include "src/Core/Core.h"
#include "src/Core/Logger.h"
#include <Coral/NativeString.hpp>
#include <Coral/String.hpp>
namespace Nuake {

View File

@@ -21,23 +21,40 @@
#include "src/Scene/Components/QuakeMap.h"
#include "src/Physics/PhysicsManager.h"
#include "src/Scripting/ScriptingEngineNet.h"
#include <Coral/NativeArray.hpp>
#include <Coral/Array.hpp>
namespace Nuake {
uint32_t GetEntity(Coral::NativeString entityName)
uint32_t GetEntity(Coral::String entityName)
{
auto scene = Engine::GetCurrentScene();
std::string entityNameString = entityName.ToString();
if (!scene->EntityExists(entityNameString))
if (!scene->EntityExists(entityName))
{
return UINT32_MAX; // Error code: entity not found.
}
return scene->GetEntity(entityNameString).GetHandle();
return scene->GetEntity(entityName).GetHandle();
}
Coral::ManagedObject GetEntityScript(Coral::String entityName)
{
auto scene = Engine::GetCurrentScene();
if (!scene->EntityExists(entityName))
{
return Coral::ManagedObject(); // Error code: entity not found.
}
Entity entity = scene->GetEntity(entityName);
auto& scriptingEngine = ScriptingEngineNet::Get();
if (scriptingEngine.HasEntityScriptInstance(entity))
{
auto instance = scriptingEngine.GetEntityScript(entity);
return instance;
}
}
static enum ComponentTypes
@@ -112,6 +129,24 @@ namespace Nuake {
{
auto& component = entity.GetComponent<TransformComponent>();
component.SetLocalPosition({ x, y, z });
if (entity.HasComponent<CharacterControllerComponent>())
{
PhysicsManager::Get().SetCharacterControllerPosition(entity, { x, y, z });
}
}
}
Coral::Array<float> TransformGetGlobalPosition(int entityId)
{
Entity entity = { (entt::entity)(entityId), Engine::GetCurrentScene().get() };
if (entity.IsValid() && entity.HasComponent<TransformComponent>())
{
auto& component = entity.GetComponent<TransformComponent>();
const auto& globalPosition = component.GetGlobalPosition();
Coral::Array<float> result = Coral::Array<float>::New({ globalPosition.x, globalPosition.y, globalPosition.z });
return result;
}
}
@@ -127,7 +162,7 @@ namespace Nuake {
}
}
Coral::NativeArray<float> CameraGetDirection(int entityId)
Coral::Array<float> CameraGetDirection(int entityId)
{
Entity entity = { (entt::entity)(entityId), Engine::GetCurrentScene().get() };
@@ -135,7 +170,7 @@ namespace Nuake {
{
auto& component = entity.GetComponent<CameraComponent>();
const Vector3 camDirection = component.CameraInstance->GetDirection();
return { camDirection.x, camDirection.y, camDirection.z };
return Coral::Array<float>::New({ camDirection.x, camDirection.y, camDirection.z });
}
}
@@ -169,19 +204,50 @@ namespace Nuake {
return false;
}
void Play(int entityId, Coral::String animation)
{
Entity entity = Entity((entt::entity)(entityId), Engine::GetCurrentScene().get());
if (entity.IsValid() && entity.HasComponent<SkinnedModelComponent>())
{
auto& skinnedModel = entity.GetComponent<SkinnedModelComponent>();
if (skinnedModel.ModelResource)
{
auto& model = skinnedModel.ModelResource;
// Find animation from name
int animIndex = 0;
for (const auto& anim : model->GetAnimations())
{
if (anim->GetName() == animation)
{
model->PlayAnimation(animIndex);
}
animIndex++;
}
}
}
}
void Nuake::SceneNetAPI::RegisterMethods()
{
RegisterMethod("Entity.EntityHasComponentIcall", &EntityHasComponent);
RegisterMethod("Scene.GetEntityIcall", &GetEntity);
RegisterMethod("Scene.GetEntityScriptIcall", &GetEntityScript);
// Components
RegisterMethod("TransformComponent.SetPositionIcall", &TransformSetPosition);
RegisterMethod("TransformComponent.GetGlobalPositionIcall", &TransformGetGlobalPosition);
RegisterMethod("TransformComponent.RotateIcall", &TransformRotate);
RegisterMethod("CameraComponent.GetDirectionIcall", &CameraGetDirection);
RegisterMethod("CharacterControllerComponent.MoveAndSlideIcall", &MoveAndSlide);
RegisterMethod("CharacterControllerComponent.IsOnGroundIcall", &IsOnGround);
RegisterMethod("SkinnedModelComponent.PlayIcall", &Play);
}
}

View File

@@ -3,6 +3,7 @@
#include "src/Core/Logger.h"
#include "src/Core/FileSystem.h"
#include "src/Core/OS.h"
#include "src/Threading/JobSystem.h"
#include "src/Resource/Project.h"
#include "src/Scene/Components/NetScriptComponent.h"
@@ -12,7 +13,7 @@
#include <Coral/HostInstance.hpp>
#include <Coral/GC.hpp>
#include <Coral/NativeArray.hpp>
#include <Coral/Array.hpp>
#include <Coral/Attribute.hpp>
@@ -136,7 +137,7 @@ namespace Nuake
}
const std::string sanitizedProjectName = String::Sanitize(project->Name);
const std::string assemblyPath = "/bin/Debug/net7.0/" + sanitizedProjectName + ".dll";
const std::string assemblyPath = "/bin/Debug/net8.0/" + sanitizedProjectName + ".dll";
if (!FileSystem::FileExists(assemblyPath))
{
@@ -149,13 +150,15 @@ namespace Nuake
for (auto& type : m_GameAssembly.GetTypes())
{
Logger::Log(std::string("Detected type: ") + std::string(type->GetName()), ".net");
Logger::Log(std::string("Detected base type: ") + std::string(type->GetBaseType().GetName()), ".net");
Logger::Log(std::string("Detected type: ") + std::string(type->GetFullName()), ".net");
Logger::Log(std::string("Detected base type: ") + std::string(type->GetBaseType().GetFullName()), ".net");
const std::string baseTypeName = std::string(type->GetBaseType().GetName());
if (baseTypeName == "Entity")
const std::string baseTypeName = std::string(type->GetBaseType().GetFullName());
if (baseTypeName == "Nuake.Net.Entity")
{
m_GameEntityTypes[std::string(type->GetName())] = type; // We have found an entity script.
auto typeSplits = String::Split(type->GetFullName(), '.');
std::string shortenedTypeName = typeSplits[typeSplits.size() - 1];
m_GameEntityTypes[shortenedTypeName] = type; // We have found an entity script.
}
}
}
@@ -222,7 +225,6 @@ namespace Nuake
size_t classNameLength = semiColonPos - classNameStartIndex;
const std::string className = fileContent.substr(classNameStartIndex, classNameLength);
if(m_GameEntityTypes.find(className) == m_GameEntityTypes.end())
{
// The class name parsed in the file was not found in the game's DLL.
@@ -246,8 +248,10 @@ namespace Nuake
{
if (!HasEntityScriptInstance(entity))
{
std::string name = entity.GetComponent<NameComponent>().Name;
Logger::Log(name);
Logger::Log("Failed to get entity .Net script instance, doesn't exist", ".net", CRITICAL);
throw std::exception("Failed to get entity .Net script instance, doesn't exist");
return Coral::ManagedObject();
}
return m_EntityToManagedObjects[entity.GetID()];
@@ -294,10 +298,10 @@ namespace Nuake
const std::string cleanProjectName = String::Sanitize(projectName);
const std::string premakeScript = R"(
workspace ")" + cleanProjectName + R"("
configurations { "Debug", "Release" }
project ")" + cleanProjectName + R"("
language "C#"
dotnetframework "net7.0"
dotnetframework "net8.0"
kind "SharedLib"
clr "Unsafe"

View File

@@ -0,0 +1,25 @@
#include "Job.h"
namespace Nuake {
Job::Job(std::function<void()> job, std::function<void()> end)
: m_Job(job)
, m_End(end)
{
m_End = end;
m_Thread = std::thread([this, job]()
{
job();
m_IsDone = true;
});
}
void Job::End()
{
if (m_End)
{
m_End();
}
}
}

25
Nuake/src/Threading/Job.h Normal file
View File

@@ -0,0 +1,25 @@
#pragma once
#include <atomic>
#include <functional>
#include <thread>
namespace Nuake {
class Job
{
public:
Job(std::function<void()> job, std::function<void()> end);
Job(const Job&) = delete;
Job& operator=(const Job&) = delete;
~Job() { m_Thread.join(); }
bool IsDone() { return m_IsDone; }
void End();
private:
std::thread m_Thread;
std::atomic<bool> m_IsDone;
std::function<void()> m_Job;
std::function<void()> m_End;
};
}

View File

@@ -0,0 +1,43 @@
#pragma once
#include "Job.h"
namespace Nuake {
class JobSystem
{
private:
std::vector<std::unique_ptr<Job>> m_Jobs;
public:
JobSystem() = default;
~JobSystem() = default;
static JobSystem& Get()
{
static JobSystem instance;
return instance;
}
void Dispatch(std::function<void()> job, std::function<void()> end)
{
m_Jobs.push_back(std::make_unique<Job>(job, end));
}
void Update()
{
for (auto it = m_Jobs.begin(); it != m_Jobs.end();)
{
if (it->get()->IsDone())
{
it->get()->End();
it = m_Jobs.erase(it);
}
else
{
++it;
}
}
}
};
}