mirror of
https://github.com/antopilo/Nuake.git
synced 2026-09-15 20:08:54 +03:00
Partial Jolt implementation and some model loader fixes.
This commit is contained in:
@@ -8,22 +8,7 @@ namespace Nuake
|
||||
{
|
||||
CharacterController::CharacterController(float height, float radius, float mass, Vector3 position)
|
||||
{
|
||||
m_surfaceHitNormals = std::vector<glm::vec3>();
|
||||
|
||||
m_bottomRoundedRegionYOffset = (height + radius) / 2.0f;
|
||||
m_bottomYOffset = height / 2.0f + radius;
|
||||
|
||||
|
||||
|
||||
//m_CollisionShape->calculateLocalInertia(mass, inertia);
|
||||
|
||||
|
||||
//rigidBodyCI.m_additionalDamping = true;
|
||||
//rigidBodyCI.m_additionalLinearDampingThresholdSqr= 1.0f;
|
||||
//rigidBodyCI.m_additionalLinearDampingThresholdSqr = 0.5f;
|
||||
|
||||
// Specify filters manually, otherwise ghost doesn't collide with statics for some reason
|
||||
//m_pPhysicsWorld->m_pDynamicsWorld->addCollisionObject(m_pGhostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
|
||||
}
|
||||
|
||||
void CharacterController::SetEntity(Entity& ent)
|
||||
@@ -31,12 +16,8 @@ namespace Nuake
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CharacterController::MoveAndSlide(glm::vec3 velocity)
|
||||
{
|
||||
|
||||
|
||||
IsOnGround = false;
|
||||
ParseGhostContacts();
|
||||
UpdatePosition();
|
||||
|
||||
@@ -5,33 +5,258 @@
|
||||
#include <src/Core/Logger.h>
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#include <Jolt/RegisterTypes.h>
|
||||
#include <Jolt/Core/Factory.h>
|
||||
#include <Jolt/Core/TempAllocator.h>
|
||||
#include <Jolt/Core/JobSystemThreadPool.h>
|
||||
#include <Jolt/Physics/PhysicsSettings.h>
|
||||
#include <Jolt/Physics/PhysicsSystem.h>
|
||||
#include <Jolt/Physics/Collision/Shape/BoxShape.h>
|
||||
#include <Jolt/Physics/Collision/Shape/SphereShape.h>
|
||||
#include <Jolt/Physics/Body/BodyCreationSettings.h>
|
||||
#include <Jolt/Physics/Body/BodyActivationListener.h>
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
namespace Physics
|
||||
// Callback for traces, connect this to your own trace function if you have one
|
||||
static void TraceImpl(const char* inFMT, ...)
|
||||
{
|
||||
DynamicWorld::DynamicWorld()
|
||||
// Format the message
|
||||
va_list list;
|
||||
va_start(list, inFMT);
|
||||
char buffer[1024];
|
||||
vsnprintf(buffer, sizeof(buffer), inFMT, list);
|
||||
|
||||
// Print to the TTY
|
||||
std::cout << buffer << std::endl;
|
||||
}
|
||||
|
||||
#ifdef JPH_ENABLE_ASSERTS
|
||||
|
||||
// Callback for asserts, connect this to your own assert handler if you have one
|
||||
static bool AssertFailedImpl(const char* inExpression, const char* inMessage, const char* inFile, uint32_t inLine)
|
||||
{
|
||||
// Print to the TTY
|
||||
std::cout << inFile << ":" << inLine << ": (" << inExpression << ") " << (inMessage != nullptr ? inMessage : "") << std::endl;
|
||||
|
||||
// Breakpoint
|
||||
return true;
|
||||
};
|
||||
|
||||
#endif // JPH_ENABLE_ASSERTS
|
||||
|
||||
// Layer that objects can be in, determines which other objects it can collide with
|
||||
// Typically you at least want to have 1 layer for moving bodies and 1 layer for static bodies, but you can have more
|
||||
// layers if you want. E.g. you could have a layer for high detail collision (which is not used by the physics simulation
|
||||
// but only if you do collision testing).
|
||||
namespace Layers
|
||||
{
|
||||
static constexpr uint8_t NON_MOVING = 0;
|
||||
static constexpr uint8_t MOVING = 1;
|
||||
static constexpr uint8_t NUM_LAYERS = 2;
|
||||
};
|
||||
|
||||
// Function that determines if two object layers can collide
|
||||
static bool MyObjectCanCollide(JPH::ObjectLayer inObject1, JPH::ObjectLayer inObject2)
|
||||
{
|
||||
switch (inObject1)
|
||||
{
|
||||
///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration.
|
||||
|
||||
SetGravity(Vector3(0, -10000, 0));
|
||||
case Layers::NON_MOVING:
|
||||
return inObject2 == Layers::MOVING; // Non moving only collides with moving
|
||||
case Layers::MOVING:
|
||||
return true; // Moving collides with everything
|
||||
default:
|
||||
//JPH_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Each broadphase layer results in a separate bounding volume tree in the broad phase. You at least want to have
|
||||
// a layer for non-moving and moving objects to avoid having to update a tree full of static objects every frame.
|
||||
// You can have a 1-on-1 mapping between object layers and broadphase layers (like in this case) but if you have
|
||||
// many object layers you'll be creating many broad phase trees, which is not efficient. If you want to fine tune
|
||||
// your broadphase layers define JPH_TRACK_BROADPHASE_STATS and look at the stats reported on the TTY.
|
||||
namespace BroadPhaseLayers
|
||||
{
|
||||
static constexpr JPH::BroadPhaseLayer NON_MOVING(0);
|
||||
static constexpr JPH::BroadPhaseLayer MOVING(1);
|
||||
static constexpr uint32_t NUM_LAYERS(2);
|
||||
};
|
||||
|
||||
// BroadPhaseLayerInterface implementation
|
||||
// This defines a mapping between object and broadphase layers.
|
||||
class BPLayerInterfaceImpl final : public JPH::BroadPhaseLayerInterface
|
||||
{
|
||||
public:
|
||||
BPLayerInterfaceImpl()
|
||||
{
|
||||
// Create a mapping table from object to broad phase layer
|
||||
mObjectToBroadPhase[Layers::NON_MOVING] = BroadPhaseLayers::NON_MOVING;
|
||||
mObjectToBroadPhase[Layers::MOVING] = BroadPhaseLayers::MOVING;
|
||||
}
|
||||
|
||||
virtual JPH::uint GetNumBroadPhaseLayers() const override
|
||||
{
|
||||
return BroadPhaseLayers::NUM_LAYERS;
|
||||
}
|
||||
|
||||
virtual JPH::BroadPhaseLayer GetBroadPhaseLayer(JPH::ObjectLayer inLayer) const override
|
||||
{
|
||||
using namespace JPH;
|
||||
JPH_ASSERT(inLayer < Layers::NUM_LAYERS);
|
||||
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
|
||||
{
|
||||
public:
|
||||
// See: ContactListener
|
||||
virtual JPH::ValidateResult OnContactValidate(const JPH::Body& inBody1, const JPH::Body& inBody2, 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
virtual void OnContactPersisted(const JPH::Body& inBody1, const JPH::Body& inBody2, const JPH::ContactManifold& inManifold, JPH::ContactSettings& ioSettings) override
|
||||
{
|
||||
std::cout << "A contact was persisted" << std::endl;
|
||||
}
|
||||
|
||||
virtual void OnContactRemoved(const JPH::SubShapeIDPair& inSubShapePair) override
|
||||
{
|
||||
std::cout << "A contact was removed" << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
// An example activation listener
|
||||
class MyBodyActivationListener : public JPH::BodyActivationListener
|
||||
{
|
||||
public:
|
||||
virtual void OnBodyActivated(const JPH::BodyID& inBodyID, JPH::uint64 inBodyUserData) override
|
||||
{
|
||||
std::cout << "A body got activated" << std::endl;
|
||||
}
|
||||
|
||||
virtual void OnBodyDeactivated(const JPH::BodyID& inBodyID, JPH::uint64 inBodyUserData) override
|
||||
{
|
||||
std::cout << "A body went to sleep" << std::endl;
|
||||
}
|
||||
};
|
||||
JPH::BodyID sphere_id;
|
||||
namespace Physics
|
||||
{
|
||||
DynamicWorld::DynamicWorld() : _stepCount(0)
|
||||
{
|
||||
const uint32_t MaxBodies = 1024;
|
||||
const uint32_t NumBodyMutexes = 0;
|
||||
const uint32_t MaxBodyPairs = 1024;
|
||||
const uint32_t MaxContactConstraints = 1024;
|
||||
|
||||
BPLayerInterfaceImpl broad_phase_layer_interface;
|
||||
|
||||
_JoltPhysicsSystem = CreateRef<JPH::PhysicsSystem>();
|
||||
_JoltPhysicsSystem->Init(MaxBodies, NumBodyMutexes, MaxBodyPairs, MaxContactConstraints, broad_phase_layer_interface, MyBroadPhaseCanCollide, MyObjectCanCollide);
|
||||
|
||||
// A body activation listener gets notified when bodies activate and go to sleep
|
||||
// Note that this is called from a job so whatever you do here needs to be thread safe.
|
||||
// Registering one is entirely optional.
|
||||
_bodyActivationListener = CreateScope<MyBodyActivationListener>();
|
||||
_JoltPhysicsSystem->SetBodyActivationListener(_bodyActivationListener.get());
|
||||
|
||||
// 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>();
|
||||
_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
|
||||
// variant of this. We're going to use the locking version (even though we're not planning to access bodies from multiple threads)
|
||||
JPH::BodyInterface& bodyInterface = _JoltPhysicsSystem->GetBodyInterface();
|
||||
|
||||
// Next we can create a rigid body to serve as the floor, we make a large box
|
||||
// Create the settings for the collision volume (the shape).
|
||||
// Note that for simple shapes (like boxes) you can also directly construct a BoxShape.
|
||||
JPH::BoxShapeSettings floor_shape_settings(JPH::Vec3(100.0f, 1.0f, 100.0f));
|
||||
|
||||
// Create the shape
|
||||
JPH::ShapeSettings::ShapeResult floor_shape_result = floor_shape_settings.Create();
|
||||
JPH::ShapeRefC floor_shape = floor_shape_result.Get(); // We don't expect an error here, but you can check floor_shape_result for HasError() / GetError()
|
||||
|
||||
// Create the settings for the body itself. Note that here you can also set other properties like the restitution / friction.
|
||||
JPH::BodyCreationSettings floor_settings(floor_shape, JPH::Vec3(0.0f, -1.0f, 0.0f), JPH::Quat::sIdentity(), JPH::EMotionType::Static, Layers::NON_MOVING);
|
||||
|
||||
// Create the actual rigid body
|
||||
JPH::Body* floor = bodyInterface.CreateBody(floor_settings); // Note that if we run out of bodies this can return nullptr
|
||||
|
||||
bodyInterface.AddBody(floor->GetID(), JPH::EActivation::DontActivate);
|
||||
|
||||
JPH::BodyCreationSettings sphere_settings(new JPH::SphereShape(0.5f), JPH::Vec3(0.0, 2.0, 0.0), JPH::Quat::sIdentity(), JPH::EMotionType::Dynamic, Layers::MOVING);
|
||||
sphere_id = bodyInterface.CreateAndAddBody(sphere_settings, JPH::EActivation::Activate);
|
||||
|
||||
// Now you can interact with the dynamic body, in this case we're going to give it a velocity.
|
||||
// (note that if we had used CreateBody then we could have set the velocity straight on the body before adding it to the physics system)
|
||||
bodyInterface.SetLinearVelocity(sphere_id, JPH::Vec3(0.0f, -5.0f, 0.0f));
|
||||
|
||||
// We simulate the physics world in discrete time steps. 60 Hz is a good rate to update the physics system.
|
||||
const float cDeltaTime = 1.0f / 60.0f;
|
||||
|
||||
// Optional step: Before starting the physics simulation you can optimize the broad phase. This improves collision detection performance (it's pointless here because we only have 2 bodies).
|
||||
// You should definitely not call this every frame or when e.g. streaming in a new level section as it is an expensive operation.
|
||||
// Instead insert all new objects in batches instead of 1 at a time to keep the broad phase efficient.
|
||||
_JoltPhysicsSystem->OptimizeBroadPhase();
|
||||
_JoltJobSystem = new JPH::JobSystemThreadPool(JPH::cMaxPhysicsJobs, JPH::cMaxPhysicsBarriers, std::thread::hardware_concurrency() - 1);
|
||||
}
|
||||
|
||||
void DynamicWorld::DrawDebug()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DynamicWorld::SetGravity(glm::vec3 g)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DynamicWorld::AddRigidbody(Ref<RigidBody> rb)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DynamicWorld::AddGhostbody(Ref<GhostObject> gb)
|
||||
@@ -40,11 +265,8 @@ namespace Nuake
|
||||
|
||||
void DynamicWorld::AddCharacterController(Ref<CharacterController> cc)
|
||||
{
|
||||
|
||||
// Specify filters manually, otherwise ghost doesn't collide with statics for some reason
|
||||
}
|
||||
|
||||
|
||||
RaycastResult DynamicWorld::Raycast(glm::vec3 from, glm::vec3 to)
|
||||
{
|
||||
Vector3 localNorm = glm::vec3(0,0,0);
|
||||
@@ -61,17 +283,31 @@ namespace Nuake
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void DynamicWorld::StepSimulation(Timestep ts)
|
||||
{
|
||||
// Next step
|
||||
++_stepCount;
|
||||
const auto& bodyInterface = _JoltPhysicsSystem->GetBodyInterface();
|
||||
|
||||
// Output current position and velocity of the sphere
|
||||
JPH::Vec3 position = bodyInterface.GetCenterOfMassPosition(sphere_id);
|
||||
JPH::Vec3 velocity = bodyInterface.GetLinearVelocity(sphere_id);
|
||||
|
||||
std::cout << "Step " << _stepCount << ": Position = (" << position.GetX() << ", " << position.GetY() << ", " << position.GetZ() << "), Velocity = (" << velocity.GetX() << ", " << velocity.GetY() << ", " << velocity.GetZ() << ")" << std::endl;
|
||||
|
||||
// If you take larger steps than 1 / 60th of a second you need to do multiple collision steps in order to keep the simulation stable. Do 1 collision step per 1 / 60th of a second (round up).
|
||||
const int cCollisionSteps = 1;
|
||||
|
||||
// If you want more accurate step results you can do multiple sub steps within a collision step. Usually you would set this to 1.
|
||||
const int cIntegrationSubSteps = 1;
|
||||
|
||||
// Step the world
|
||||
_JoltPhysicsSystem->Update(ts, cCollisionSteps, cIntegrationSubSteps, new JPH::TempAllocatorMalloc(), _JoltJobSystem);
|
||||
}
|
||||
|
||||
|
||||
void DynamicWorld::Clear()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,11 +9,28 @@
|
||||
#include <src/Core/Physics/GhostObject.h>
|
||||
#include "CharacterController.h"
|
||||
|
||||
namespace JPH
|
||||
{
|
||||
class PhysicsSystem;
|
||||
class JobSystemThreadPool;
|
||||
class ContactListener;
|
||||
class BodyActivationListener;
|
||||
}
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
class MyContactListener;
|
||||
class MyBodyActivationListener;
|
||||
|
||||
namespace Physics {
|
||||
class DynamicWorld {
|
||||
private:
|
||||
uint32_t _stepCount;
|
||||
Ref<JPH::PhysicsSystem> _JoltPhysicsSystem;
|
||||
JPH::JobSystemThreadPool* _JoltJobSystem;
|
||||
Scope<MyContactListener> _contactListener;
|
||||
Scope<MyBodyActivationListener> _bodyActivationListener;
|
||||
|
||||
public:
|
||||
DynamicWorld();
|
||||
|
||||
@@ -23,13 +40,11 @@ namespace Nuake
|
||||
void AddRigidbody(Ref<RigidBody> rb);
|
||||
|
||||
void AddGhostbody(Ref<GhostObject> gb);
|
||||
|
||||
void AddCharacterController(Ref < CharacterController> cc);
|
||||
void AddCharacterController(Ref<CharacterController> cc);
|
||||
|
||||
RaycastResult Raycast(glm::vec3 from, glm::vec3 to);
|
||||
void StepSimulation(Timestep ts);
|
||||
void Clear();
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,9 +40,7 @@ namespace Nuake
|
||||
|
||||
RaycastResult PhysicsManager::Raycast(glm::vec3 from, glm::vec3 to)
|
||||
{
|
||||
|
||||
return m_World->Raycast(from, to);
|
||||
|
||||
}
|
||||
|
||||
void PhysicsManager::DrawDebug()
|
||||
@@ -53,31 +51,15 @@ namespace Nuake
|
||||
|
||||
void PhysicsManager::Init()
|
||||
{
|
||||
Logger::Log("Initializing Jolt physics.");
|
||||
JPH::RegisterDefaultAllocator();
|
||||
|
||||
Logger::Log("Creating factory & registering types.");
|
||||
JPH::Factory::sInstance = new JPH::Factory();
|
||||
|
||||
JPH::RegisterTypes();
|
||||
|
||||
// This is the max amount of rigid bodies that you can add to the physics system. If you try to add more you'll get an error.
|
||||
// Note: This value is low because this is a simple test. For a real project use something in the order of 65536.
|
||||
const uint32_t cMaxBodies = 1024;
|
||||
|
||||
// This determines how many mutexes to allocate to protect rigid bodies from concurrent access. Set it to 0 for the default settings.
|
||||
const uint32_t cNumBodyMutexes = 0;
|
||||
|
||||
// This is the max amount of body pairs that can be queued at any time (the broad phase will detect overlapping
|
||||
// body pairs based on their bounding boxes and will insert them into a queue for the narrowphase). If you make this buffer
|
||||
// too small the queue will fill up and the broad phase jobs will start to do narrow phase work. This is slightly less efficient.
|
||||
// Note: This value is low because this is a simple test. For a real project use something in the order of 65536.
|
||||
const uint32_t cMaxBodyPairs = 1024;
|
||||
|
||||
// This is the maximum size of the contact constraint buffer. If more contacts (collisions between bodies) are detected than this
|
||||
// number then these contacts will be ignored and bodies will start interpenetrating / fall through the world.
|
||||
// Note: This value is low because this is a simple test. For a real project use something in the order of 10240.
|
||||
const uint32_t cMaxContactConstraints = 1024;
|
||||
|
||||
|
||||
m_World = new Physics::DynamicWorld();
|
||||
m_World->SetGravity(glm::vec3(0, -3, 0));
|
||||
|
||||
|
||||
@@ -21,10 +21,7 @@ namespace Nuake
|
||||
m_Type = BOX;
|
||||
}
|
||||
|
||||
btCollisionShape* Box::GetBulletShape()
|
||||
{
|
||||
return bShape;
|
||||
}
|
||||
|
||||
|
||||
// Sphere
|
||||
Sphere::Sphere(float radius) {
|
||||
@@ -37,11 +34,6 @@ namespace Nuake
|
||||
Radius = radius;
|
||||
}
|
||||
|
||||
btCollisionShape* Sphere::GetBulletShape()
|
||||
{
|
||||
return bShape;
|
||||
}
|
||||
|
||||
MeshShape::MeshShape(Ref<Mesh> mesh)
|
||||
{
|
||||
m_Mesh = mesh;
|
||||
@@ -59,9 +51,5 @@ namespace Nuake
|
||||
|
||||
}
|
||||
|
||||
btCollisionShape* MeshShape::GetBulletShape()
|
||||
{
|
||||
return bShape;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
#include "src/Core/Maths.h"
|
||||
#include "src/Rendering/Mesh/Mesh.h"
|
||||
|
||||
class btCollisionShape;
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
namespace Physics
|
||||
@@ -16,10 +14,8 @@ namespace Nuake
|
||||
class PhysicShape
|
||||
{
|
||||
protected:
|
||||
btCollisionShape* bShape;
|
||||
RigidbodyShapes m_Type;
|
||||
public:
|
||||
virtual btCollisionShape* GetBulletShape() = 0;
|
||||
RigidbodyShapes GetType() const { return m_Type; }
|
||||
|
||||
};
|
||||
@@ -28,42 +24,36 @@ namespace Nuake
|
||||
{
|
||||
private:
|
||||
glm::vec3 Size;
|
||||
btCollisionShape* bShape;
|
||||
public:
|
||||
Box();
|
||||
Box(glm::vec3 size);
|
||||
Box(float x, float y, float z);
|
||||
|
||||
glm::vec3 GetSize() const { return Size; }
|
||||
btCollisionShape* GetBulletShape() override;
|
||||
};
|
||||
|
||||
class Sphere : public PhysicShape
|
||||
{
|
||||
private:
|
||||
float Radius;
|
||||
btCollisionShape* bShape;
|
||||
public:
|
||||
Sphere(float radius);
|
||||
|
||||
float GetRadius() const { return Radius; }
|
||||
void SetRadius(float radius);
|
||||
|
||||
btCollisionShape* GetBulletShape() override;
|
||||
};
|
||||
|
||||
class MeshShape : public PhysicShape
|
||||
{
|
||||
private:
|
||||
Ref<Mesh> m_Mesh;
|
||||
btCollisionShape* bShape;
|
||||
public:
|
||||
MeshShape(Ref<Mesh> mesh);
|
||||
|
||||
void SetMesh(Mesh* mesh);
|
||||
Mesh* GetMesh();
|
||||
|
||||
btCollisionShape* GetBulletShape() override;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "../Core/Core.h"
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
class Entity;
|
||||
@@ -11,8 +12,7 @@ namespace Nuake
|
||||
private:
|
||||
bool m_IsDynamic = false;
|
||||
bool m_IsKinematic = false;
|
||||
glm::vec3 m_InitialVel;
|
||||
|
||||
Vector3 m_InitialVel;
|
||||
|
||||
Ref<PhysicShape> m_CollisionShape;
|
||||
public:
|
||||
@@ -22,10 +22,9 @@ namespace Nuake
|
||||
RigidBody(glm::vec3 position, Entity handle);
|
||||
RigidBody(float mass, glm::vec3 position, Ref<PhysicShape> shape, glm::vec3 initialVel = glm::vec3(0, 0, 0));
|
||||
|
||||
|
||||
void UpdateTransform();
|
||||
glm::vec3 GetPosition() const;
|
||||
glm::vec3 GetRotation() const;
|
||||
Vector3 GetPosition() const;
|
||||
Vector3 GetRotation() const;
|
||||
|
||||
void SetEntityID(Entity ent);
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ namespace Nuake
|
||||
return texture;
|
||||
}
|
||||
|
||||
std::string texturePath = FileSystem::Root + modelDir + path;
|
||||
std::string texturePath = modelDir + path;
|
||||
if (!FileSystem::FileExists(texturePath, true))
|
||||
{
|
||||
std::string textureNotFoundmsg = "Texture file couldn't be found: " + texturePath;
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Nuake {
|
||||
void ModelComponent::LoadModel()
|
||||
{
|
||||
auto loader = ModelLoader();
|
||||
this->ModelResource = loader.LoadModel(FileSystem::Root + "../" + ModelPath);
|
||||
this->ModelResource = loader.LoadModel(FileSystem::Root + ModelPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,6 +89,8 @@ namespace Nuake
|
||||
void TransformComponent::SetGlobalTransform(const Matrix4& transform)
|
||||
{
|
||||
GlobalTransform = transform;
|
||||
|
||||
GlobalTranslation = Vector3(transform[3]);
|
||||
}
|
||||
|
||||
Matrix4 TransformComponent::GetLocalTransform() const
|
||||
@@ -99,5 +101,6 @@ namespace Nuake
|
||||
void TransformComponent::SetLocalTransform(const Matrix4& transform)
|
||||
{
|
||||
LocalTransform = transform;
|
||||
Translation = Vector3(transform[3]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +136,7 @@ namespace Nuake {
|
||||
auto [transform, camera, parent] = view.get<TransformComponent, CameraComponent, ParentComponent>(e);
|
||||
cam = camera.CameraInstance;
|
||||
cam->Translation = transform.GetGlobalPosition();
|
||||
cam->SetDirection(Vector3(Vector4(0, 0, 1, 0) * transform.GetGlobalTransform()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user