Merge branch 'main' of https://github.com/antopilo/Nuake
This commit is contained in:
@@ -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;
|
||||
|
||||
16
Nuake/src/Physics/CollisionData.h
Normal file
16
Nuake/src/Physics/CollisionData.h
Normal 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;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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)";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,5 +13,8 @@ namespace Nuake {
|
||||
void Draw() override {}
|
||||
void FixedUpdate(Timestep ts) override;
|
||||
void Exit() override;
|
||||
|
||||
private:
|
||||
void DispatchPhysicCallbacks();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Core/Logger.h"
|
||||
|
||||
#include <Coral/NativeString.hpp>
|
||||
#include <Coral/String.hpp>
|
||||
|
||||
namespace Nuake {
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
25
Nuake/src/Threading/Job.cpp
Normal file
25
Nuake/src/Threading/Job.cpp
Normal 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
25
Nuake/src/Threading/Job.h
Normal 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;
|
||||
};
|
||||
}
|
||||
43
Nuake/src/Threading/JobSystem.h
Normal file
43
Nuake/src/Threading/JobSystem.h
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user