mirror of
https://github.com/antopilo/Nuake.git
synced 2026-09-09 20:08:57 +03:00
Merge branch 'main' of https://github.com/antopilo/Nuake
This commit is contained in:
@@ -17,30 +17,21 @@ public:
|
||||
BeginComponentTable(CHARACTER CONTROLLER, Nuake::CharacterControllerComponent);
|
||||
{
|
||||
{
|
||||
ImGui::Text("Height");
|
||||
ImGui::Text("Friction");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::DragFloat("##Height", &component.Height, 0.01f, 0.1f, 100.0f);
|
||||
ImGui::DragFloat("##Friction", &component.Friction, 0.01f, 0.1f, 100.0f);
|
||||
ImGui::TableNextColumn();
|
||||
ComponentTableReset(component.Height, 1.0f)
|
||||
ComponentTableReset(component.Friction, 0.5f)
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
{
|
||||
ImGui::Text("Radius");
|
||||
ImGui::Text("Max Slope Angle");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::DragFloat("##Radius", &component.Radius, 0.01f, 0.1f, 10.0f);
|
||||
ImGui::DragFloat("##MaxSlopeAngle", &component.MaxSlopeAngle, 0.01f, 0.1f, 90.0f);
|
||||
ImGui::TableNextColumn();
|
||||
ComponentTableReset(component.Radius, 0.25f)
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
{
|
||||
ImGui::Text("Mass");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::DragFloat("##Mass", &component.Mass, 0.001f, 0.00001f, 10.0f);
|
||||
ImGui::TableNextColumn();
|
||||
ComponentTableReset(component.Mass, 0.001f)
|
||||
ComponentTableReset(component.MaxSlopeAngle, 0.45f)
|
||||
}
|
||||
}
|
||||
EndComponentTable()
|
||||
|
||||
@@ -6,14 +6,21 @@ namespace Nuake
|
||||
{
|
||||
namespace Physics
|
||||
{
|
||||
CharacterController::CharacterController(float height, float radius, float mass, Vector3 position)
|
||||
CharacterController::CharacterController(const Ref<PhysicShape>& shape, float friction, float maxSlopeAngle)
|
||||
{
|
||||
|
||||
Shape = shape;
|
||||
Friction = friction;
|
||||
MaxSlopeAngle = maxSlopeAngle;
|
||||
}
|
||||
|
||||
void CharacterController::SetEntity(Entity& ent)
|
||||
{
|
||||
|
||||
Owner = ent;
|
||||
}
|
||||
|
||||
Entity CharacterController::GetEntity() const
|
||||
{
|
||||
return Owner;
|
||||
}
|
||||
|
||||
void CharacterController::MoveAndSlide(glm::vec3 velocity)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Core/Maths.h"
|
||||
#include "src/Core/Physics/PhysicsShapes.h"
|
||||
#include "src/Scene/Entities/Entity.h"
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
@@ -11,26 +13,30 @@ namespace Nuake
|
||||
class CharacterController
|
||||
{
|
||||
public:
|
||||
|
||||
Vector3 Position = Vector3(0, 0, 0);
|
||||
Entity Owner;
|
||||
|
||||
bool IsOnGround = false;
|
||||
bool m_hittingWall;
|
||||
float m_stepHeight = 0.35f;
|
||||
float m_MaxSlopeAngle = 45.0f;
|
||||
|
||||
float m_stepHeight = 0.35f;
|
||||
float MaxSlopeAngle = 45.0f;
|
||||
float Friction = 0.5f;
|
||||
Ref<PhysicShape> Shape;
|
||||
|
||||
//bool m_onJumpableGround; // A bit lower contact than just onGround
|
||||
|
||||
float m_bottomYOffset;
|
||||
float m_bottomRoundedRegionYOffset;
|
||||
|
||||
|
||||
glm::vec3 m_manualVelocity;
|
||||
std::vector<glm::vec3> m_surfaceHitNormals;
|
||||
|
||||
|
||||
float m_jumpRechargeTimer;
|
||||
CharacterController(float height, float radius, float mass, Vector3 position);
|
||||
CharacterController(const Ref<PhysicShape>& shape, float friction, float maxSlopeAngle);
|
||||
|
||||
void SetEntity(Entity& ent);
|
||||
Entity GetEntity() const;
|
||||
void MoveAndSlide(glm::vec3 velocity);
|
||||
|
||||
bool IsOnFloor()
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "DynamicWorld.h"
|
||||
#include "Rigibody.h"
|
||||
#include "../Core/Core.h"
|
||||
#include <src/Vendors/glm/ext/quaternion_common.hpp>
|
||||
#include <src/Core/Logger.h>
|
||||
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Core/Logger.h"
|
||||
#include <src/Core/Physics/PhysicsShapes.h>
|
||||
|
||||
#include <src/Vendors/glm/ext/quaternion_common.hpp>
|
||||
#include "src/Vendors/glm/gtx/matrix_decompose.hpp"
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
@@ -241,103 +241,21 @@ namespace Nuake
|
||||
void DynamicWorld::AddRigidbody(Ref<RigidBody> rb)
|
||||
{
|
||||
JPH::BodyInterface& bodyInterface = _JoltPhysicsSystem->GetBodyInterface();
|
||||
|
||||
JPH::ShapeSettings::ShapeResult shapeResult;
|
||||
auto rbShape = rb->GetShape();
|
||||
switch (rbShape->GetType())
|
||||
{
|
||||
case RigidbodyShapes::BOX:
|
||||
{
|
||||
Box* box = (Box*)rbShape.get();
|
||||
const Vector3& boxSize = box->GetSize();
|
||||
JPH::BoxShapeSettings shapeSettings(JPH::Vec3(boxSize.x, boxSize.y, boxSize.z));
|
||||
shapeResult = shapeSettings.Create();
|
||||
}
|
||||
break;
|
||||
case RigidbodyShapes::SPHERE:
|
||||
{
|
||||
Sphere* sphere = (Sphere*)rbShape.get();
|
||||
const float sphereRadius = sphere->GetRadius();
|
||||
JPH::SphereShapeSettings shapeSettings(sphereRadius);
|
||||
shapeResult = shapeSettings.Create();
|
||||
}
|
||||
break;
|
||||
case RigidbodyShapes::CAPSULE:
|
||||
{
|
||||
Capsule* capsule = (Capsule*)rbShape.get();
|
||||
const float radius = capsule->GetRadius();
|
||||
const float height = capsule->GetHeight();
|
||||
JPH::CapsuleShapeSettings shapeSettings(height / 2.0f, radius);
|
||||
shapeResult = shapeSettings.Create();
|
||||
}
|
||||
break;
|
||||
case RigidbodyShapes::CYLINDER:
|
||||
{
|
||||
Cylinder* capsule = (Cylinder*)rbShape.get();
|
||||
const float radius = capsule->GetRadius();
|
||||
const float height = capsule->GetHeight();
|
||||
JPH::CylinderShapeSettings shapeSettings(height / 2.0f, radius);
|
||||
shapeResult = shapeSettings.Create();
|
||||
}
|
||||
break;
|
||||
case RigidbodyShapes::MESH:
|
||||
{
|
||||
MeshShape* meshShape = (MeshShape*)rbShape.get();
|
||||
const auto& mesh = meshShape->GetMesh();
|
||||
const auto& vertices = mesh->GetVertices();
|
||||
const auto& indices = mesh->GetIndices();
|
||||
|
||||
JPH::TriangleList triangles;
|
||||
triangles.reserve(indices.size());
|
||||
Matrix4 transform = rb->_transform;
|
||||
transform[3] = Vector4(0, 0, 0, 1.0f);
|
||||
for (int i = 0; i < indices.size() - 3; i += 3)
|
||||
{
|
||||
const Vector3& p1 = vertices[indices[i]].position;
|
||||
const Vector3& p2 = vertices[indices[i + 1]].position;
|
||||
const Vector3& p3 = vertices[indices[i + 2]].position;
|
||||
|
||||
const Vector4& tp1 = transform * Vector4(p1, 1.0f);
|
||||
const Vector4& tp2 = transform * Vector4(p2, 1.0f);
|
||||
const Vector4& tp3 = transform * Vector4(p3, 1.0f);
|
||||
triangles.push_back(JPH::Triangle(JPH::Float3(tp1.x, tp1.y, tp1.z), JPH::Float3(tp2.x, tp2.y, tp2.z), JPH::Float3(tp3.x, tp3.y, tp3.z)));
|
||||
}
|
||||
|
||||
JPH::MeshShapeSettings shapeSettings(std::move(triangles));
|
||||
|
||||
shapeResult = shapeSettings.Create();
|
||||
}
|
||||
break;
|
||||
case CONVEX_HULL:
|
||||
{
|
||||
ConvexHullShape* shape = (ConvexHullShape*)rbShape.get();
|
||||
|
||||
const auto& hullPoints = shape->GetPoints();
|
||||
JPH::Array<JPH::Vec3> points;
|
||||
points.reserve(std::size(hullPoints));
|
||||
for (const auto& p : hullPoints)
|
||||
{
|
||||
points.push_back(JPH::Vec3(p.x, p.y, p.z));
|
||||
}
|
||||
|
||||
JPH::ConvexHullShapeSettings shapeSettings(points);
|
||||
shapeResult = shapeSettings.Create();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
const float mass = rb->_mass;
|
||||
JPH::EMotionType motionType = JPH::EMotionType::Static;
|
||||
|
||||
float mass = rb->_mass;
|
||||
|
||||
// According to jolt documentation, Mesh shapes should only be static.
|
||||
if (mass > 0.0f && rb->GetShape()->GetType() != MESH)
|
||||
const bool isMeshShape = rb->GetShape()->GetType() == MESH;
|
||||
if (mass > 0.0f && !isMeshShape)
|
||||
{
|
||||
motionType = JPH::EMotionType::Dynamic;
|
||||
}
|
||||
|
||||
const auto& startPos = rb->GetPosition();
|
||||
const auto& joltPos = JPH::Vec3(startPos.x, startPos.y, startPos.z);
|
||||
JPH::BodyCreationSettings bodySettings(shapeResult.Get(), joltPos, JPH::Quat::sIdentity(), motionType, Layers::MOVING);
|
||||
auto joltShape = GetJoltShape(rb->GetShape());
|
||||
JPH::BodyCreationSettings bodySettings(joltShape, joltPos, JPH::Quat::sIdentity(), motionType, Layers::MOVING);
|
||||
|
||||
if (mass > 0.0f)
|
||||
{
|
||||
@@ -358,12 +276,16 @@ namespace Nuake
|
||||
|
||||
void DynamicWorld::AddCharacterController(Ref<CharacterController> cc)
|
||||
{
|
||||
auto settings = new JPH::CharacterSettings();
|
||||
JPH::Ref<JPH::CharacterSettings> settings = new JPH::CharacterSettings();
|
||||
settings->mMaxSlopeAngle = JPH::DegreesToRadians(45.0f);
|
||||
settings->mLayer = Layers::MOVING;
|
||||
settings->mFriction = 0.5f;
|
||||
settings->mShape = GetJoltShape(cc->Shape);
|
||||
|
||||
// Shape here
|
||||
auto& joltPos = JPH::Vec3(cc->Position.x, cc->Position.y, cc->Position.z);
|
||||
JPH::Character* character = new JPH::Character(settings, joltPos, JPH::Quat::sIdentity(), cc->GetEntity().GetID() , _JoltPhysicsSystem.get());
|
||||
|
||||
character->AddToPhysicsSystem(JPH::EActivation::Activate);
|
||||
}
|
||||
|
||||
RaycastResult DynamicWorld::Raycast(glm::vec3 from, glm::vec3 to)
|
||||
@@ -454,5 +376,94 @@ namespace Nuake
|
||||
_JoltBodyInterface->RemoveBodies(reinterpret_cast<JPH::BodyID*>(_registeredBodies.data()), _registeredBodies.size());
|
||||
_registeredBodies.clear();
|
||||
}
|
||||
|
||||
JPH::Ref<JPH::Shape> DynamicWorld::GetJoltShape(const Ref<PhysicShape> shape)
|
||||
{
|
||||
JPH::ShapeSettings::ShapeResult result;
|
||||
|
||||
switch (shape->GetType())
|
||||
{
|
||||
case RigidbodyShapes::BOX:
|
||||
{
|
||||
Box* box = (Box*)shape.get();
|
||||
const Vector3& boxSize = box->GetSize();
|
||||
JPH::BoxShapeSettings shapeSettings(JPH::Vec3(boxSize.x, boxSize.y, boxSize.z));
|
||||
result = shapeSettings.Create();
|
||||
}
|
||||
break;
|
||||
case RigidbodyShapes::SPHERE:
|
||||
{
|
||||
Sphere* sphere = (Sphere*)shape.get();
|
||||
const float sphereRadius = sphere->GetRadius();
|
||||
JPH::SphereShapeSettings shapeSettings(sphereRadius);
|
||||
result = shapeSettings.Create();
|
||||
}
|
||||
break;
|
||||
case RigidbodyShapes::CAPSULE:
|
||||
{
|
||||
Capsule* capsule = (Capsule*)shape.get();
|
||||
const float radius = capsule->GetRadius();
|
||||
const float height = capsule->GetHeight();
|
||||
JPH::CapsuleShapeSettings shapeSettings(height / 2.0f, radius);
|
||||
result = shapeSettings.Create();
|
||||
}
|
||||
break;
|
||||
case RigidbodyShapes::CYLINDER:
|
||||
{
|
||||
Cylinder* capsule = (Cylinder*)shape.get();
|
||||
const float radius = capsule->GetRadius();
|
||||
const float height = capsule->GetHeight();
|
||||
JPH::CylinderShapeSettings shapeSettings(height / 2.0f, radius);
|
||||
result = shapeSettings.Create();
|
||||
}
|
||||
break;
|
||||
case RigidbodyShapes::MESH:
|
||||
{
|
||||
MeshShape* meshShape = (MeshShape*)shape.get();
|
||||
const auto& mesh = meshShape->GetMesh();
|
||||
const auto& vertices = mesh->GetVertices();
|
||||
const auto& indices = mesh->GetIndices();
|
||||
|
||||
JPH::TriangleList triangles;
|
||||
triangles.reserve(indices.size());
|
||||
Matrix4 transform; //rb->_transform;
|
||||
transform[3] = Vector4(0, 0, 0, 1.0f);
|
||||
for (int i = 0; i < indices.size() - 3; i += 3)
|
||||
{
|
||||
const Vector3& p1 = vertices[indices[i]].position;
|
||||
const Vector3& p2 = vertices[indices[i + 1]].position;
|
||||
const Vector3& p3 = vertices[indices[i + 2]].position;
|
||||
|
||||
const Vector4& tp1 = transform * Vector4(p1, 1.0f);
|
||||
const Vector4& tp2 = transform * Vector4(p2, 1.0f);
|
||||
const Vector4& tp3 = transform * Vector4(p3, 1.0f);
|
||||
triangles.push_back(JPH::Triangle(JPH::Float3(tp1.x, tp1.y, tp1.z), JPH::Float3(tp2.x, tp2.y, tp2.z), JPH::Float3(tp3.x, tp3.y, tp3.z)));
|
||||
}
|
||||
|
||||
JPH::MeshShapeSettings shapeSettings(std::move(triangles));
|
||||
|
||||
result = shapeSettings.Create();
|
||||
}
|
||||
break;
|
||||
case CONVEX_HULL:
|
||||
{
|
||||
auto* convexHullShape = (Physics::ConvexHullShape*)shape.get();
|
||||
|
||||
const auto& hullPoints = convexHullShape->GetPoints();
|
||||
JPH::Array<JPH::Vec3> points;
|
||||
points.reserve(std::size(hullPoints));
|
||||
for (const auto& p : hullPoints)
|
||||
{
|
||||
points.push_back(JPH::Vec3(p.x, p.y, p.z));
|
||||
}
|
||||
|
||||
JPH::ConvexHullShapeSettings shapeSettings(points);
|
||||
result = shapeSettings.Create();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return result.Get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "CharacterController.h"
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
#include "src/Core/Core.h"
|
||||
namespace JPH
|
||||
{
|
||||
class PhysicsSystem;
|
||||
@@ -17,8 +18,13 @@ namespace JPH
|
||||
class ContactListener;
|
||||
class BodyActivationListener;
|
||||
class BodyInterface;
|
||||
class Shape;
|
||||
|
||||
template<class T>
|
||||
class Ref;
|
||||
}
|
||||
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
class BPLayerInterfaceImpl;
|
||||
@@ -26,7 +32,8 @@ namespace Nuake
|
||||
class MyBodyActivationListener;
|
||||
|
||||
namespace Physics {
|
||||
class DynamicWorld {
|
||||
class DynamicWorld
|
||||
{
|
||||
private:
|
||||
uint32_t _stepCount;
|
||||
|
||||
@@ -38,6 +45,7 @@ namespace Nuake
|
||||
BPLayerInterfaceImpl* _JoltBroadphaseLayerInterface;
|
||||
|
||||
std::vector<uint32_t> _registeredBodies;
|
||||
std::vector<uint32_t> _registeredCharacters;
|
||||
public:
|
||||
DynamicWorld();
|
||||
|
||||
@@ -54,7 +62,7 @@ namespace Nuake
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
|
||||
JPH::Ref<JPH::Shape> GetJoltShape(const Ref<PhysicShape> shape);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,8 +58,6 @@ namespace Nuake
|
||||
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.
|
||||
m_World = new Physics::DynamicWorld();
|
||||
m_World->SetGravity(glm::vec3(0, -3, 0));
|
||||
|
||||
|
||||
@@ -12,24 +12,27 @@ namespace Nuake
|
||||
}
|
||||
|
||||
// Sphere
|
||||
Box::Box(glm::vec3 size) {
|
||||
Box::Box(glm::vec3 size)
|
||||
{
|
||||
Size = size;
|
||||
m_Type = BOX;
|
||||
}
|
||||
|
||||
Box::Box(float x, float y, float z) {
|
||||
Box::Box(float x, float y, float z)
|
||||
{
|
||||
Size = glm::vec3(x, y, z);
|
||||
m_Type = BOX;
|
||||
}
|
||||
|
||||
// Sphere
|
||||
Sphere::Sphere(float radius) {
|
||||
Sphere::Sphere(float radius)
|
||||
{
|
||||
Radius = radius;
|
||||
|
||||
m_Type = SPHERE;
|
||||
}
|
||||
|
||||
void Sphere::SetRadius(float radius) {
|
||||
void Sphere::SetRadius(float radius)
|
||||
{
|
||||
Radius = radius;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Nuake
|
||||
|
||||
RigidBody();
|
||||
RigidBody(glm::vec3 position, Entity handle);
|
||||
RigidBody(float mass, glm::vec3 position, Matrix4 _transform, Ref<PhysicShape> shape, Entity entity, glm::vec3 initialVel = glm::vec3(0, 0, 0));
|
||||
RigidBody(float mass, glm::vec3 position, Matrix4 transform, Ref<PhysicShape> shape, Entity entity, glm::vec3 initialVel = glm::vec3(0, 0, 0));
|
||||
|
||||
void UpdateTransform();
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Nuake
|
||||
|
||||
void RigidBody::SetEntityID(Entity ent)
|
||||
{
|
||||
|
||||
_entity = ent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,25 +29,26 @@ namespace Nuake {
|
||||
Meshes = std::vector<Ref<Mesh>>();
|
||||
Materials = std::vector<Ref<Material>>();
|
||||
Rigidbody = std::vector<Ref<Physics::RigidBody>>();
|
||||
Hulls = std::vector<std::vector<Vector3>>();
|
||||
}
|
||||
|
||||
json Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
|
||||
//for (uint32_t i = 0; i < Hulls.size() - 1; i++)
|
||||
//{
|
||||
// json hullPointsJson;
|
||||
for (uint32_t i = 0; i < Hulls.size(); i++)
|
||||
{
|
||||
json hullPointsJson;
|
||||
|
||||
// size_t hullSize = Hulls[i].size();
|
||||
// for (uint32_t j = 0; j < hullSize; j++)
|
||||
// {
|
||||
// hullPointsJson[j]["x"] = Hulls[i][j].x;
|
||||
// hullPointsJson[j]["y"] = Hulls[i][j].y;
|
||||
// hullPointsJson[j]["z"] = Hulls[i][j].z;
|
||||
// }
|
||||
// j["Hulls"][i] = hullPointsJson;
|
||||
//}
|
||||
size_t hullSize = Hulls[i].size();
|
||||
for (uint32_t j = 0; j < hullSize; j++)
|
||||
{
|
||||
hullPointsJson[j]["x"] = Hulls[i][j].x;
|
||||
hullPointsJson[j]["y"] = Hulls[i][j].y;
|
||||
hullPointsJson[j]["z"] = Hulls[i][j].z;
|
||||
}
|
||||
j["Hulls"][i] = hullPointsJson;
|
||||
}
|
||||
|
||||
j["IsSolid"] = IsSolid;
|
||||
END_SERIALIZE();
|
||||
|
||||
@@ -7,28 +7,36 @@ namespace Nuake {
|
||||
public:
|
||||
Ref<Physics::CharacterController> CharacterController;
|
||||
|
||||
float Height = 1.0f;
|
||||
float Radius = 0.2f;
|
||||
float Mass = 25.0f;
|
||||
float Friction = 0.5f;
|
||||
float MaxSlopeAngle = 0.45f;
|
||||
|
||||
CharacterControllerComponent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
json Serialize() {
|
||||
json Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(Height);
|
||||
SERIALIZE_VAL(Radius);
|
||||
SERIALIZE_VAL(Mass);
|
||||
SERIALIZE_VAL(Friction);
|
||||
SERIALIZE_VAL(MaxSlopeAngle);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool Deserialize(const std::string str) {
|
||||
bool Deserialize(const std::string str)
|
||||
{
|
||||
BEGIN_DESERIALIZE();
|
||||
Height = j["Height"];
|
||||
Radius = j["Radius"];
|
||||
Mass = j["Mass"];
|
||||
|
||||
if (j.contains("Friction"))
|
||||
{
|
||||
Friction = j["Friction"];
|
||||
}
|
||||
|
||||
if (j.contains("MaxSlopeAngle"))
|
||||
{
|
||||
MaxSlopeAngle = j["MaxSlopeAngle"];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Nuake {
|
||||
public:
|
||||
int SubMesh = 0;
|
||||
bool IsTrigger;
|
||||
Ref<Physics::MeshShape> Shape;
|
||||
|
||||
json Serialize()
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Nuake
|
||||
float AtmosphereRadius = 6380e3f;
|
||||
Vector3 RayleighScattering = Vector3(58e-7f, 135e-7f, 331e-7f);
|
||||
Vector3 MieScattering = Vector3(2e-5f);
|
||||
float SunIntensity = 10.0;
|
||||
float SunIntensity = 2.0;
|
||||
|
||||
Vector3 CenterPoint = Vector3(0.f, -SurfaceRadius, 0.f);
|
||||
Vector3 SunDirection = Vector3(0.20000f, 0.95917f, 0.20000f);
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace Nuake {
|
||||
}
|
||||
}
|
||||
|
||||
assert("Not found");
|
||||
assert("Entity not found");
|
||||
}
|
||||
|
||||
bool Scene::OnInit()
|
||||
|
||||
@@ -22,113 +22,15 @@ namespace Nuake
|
||||
|
||||
bool PhysicsSystem::Init()
|
||||
{
|
||||
// Create physic world.
|
||||
auto view = m_Scene->m_Registry.view<TransformComponent, RigidBodyComponent>();
|
||||
for (auto e : view)
|
||||
{
|
||||
auto [transform, rigidBodyComponent] = view.get<TransformComponent, RigidBodyComponent>(e);
|
||||
Entity ent = Entity({ e, m_Scene });
|
||||
Ref<Physics::RigidBody> rigidBody;
|
||||
if (ent.HasComponent<BoxColliderComponent>())
|
||||
{
|
||||
float mass = rigidBodyComponent.Mass;
|
||||
// We need to initialize shapes first, then bodies...
|
||||
InitializeShapes();
|
||||
|
||||
BoxColliderComponent& boxComponent = ent.GetComponent<BoxColliderComponent>();
|
||||
Ref<Physics::Box> boxShape = CreateRef<Physics::Box>(boxComponent.Size);
|
||||
|
||||
rigidBody = CreateRef<Physics::RigidBody>(rigidBodyComponent.Mass, transform.GetGlobalPosition(), transform.GetGlobalTransform(), boxShape, ent);
|
||||
PhysicsManager::Get().RegisterBody(rigidBody);
|
||||
}
|
||||
|
||||
if (ent.HasComponent<CapsuleColliderComponent>())
|
||||
{
|
||||
auto& capsuleComponent = ent.GetComponent<CapsuleColliderComponent>();
|
||||
float radius = capsuleComponent.Radius;
|
||||
float height = capsuleComponent.Height;
|
||||
auto capsuleShape = CreateRef<Physics::Capsule>(radius, height);
|
||||
|
||||
rigidBody = CreateRef<Physics::RigidBody>(rigidBodyComponent.Mass, transform.GetGlobalPosition(), transform.GetGlobalTransform(), capsuleShape, ent);
|
||||
PhysicsManager::Get().RegisterBody(rigidBody);
|
||||
}
|
||||
|
||||
if (ent.HasComponent<SphereColliderComponent>())
|
||||
{
|
||||
float mass = rigidBodyComponent.Mass;
|
||||
|
||||
const auto& component = ent.GetComponent<SphereColliderComponent>();
|
||||
auto shape = CreateRef<Physics::Sphere>(component.Radius);
|
||||
|
||||
rigidBody = CreateRef<Physics::RigidBody>(rigidBodyComponent.Mass, transform.GetGlobalPosition(), transform.GetGlobalTransform(), shape, ent);
|
||||
PhysicsManager::Get().RegisterBody(rigidBody);
|
||||
}
|
||||
|
||||
if (ent.HasComponent<MeshColliderComponent>())
|
||||
{
|
||||
if (!ent.HasComponent<ModelComponent>())
|
||||
{
|
||||
Logger::Log("Cannot use mesh collider without model component", WARNING);
|
||||
}
|
||||
const auto& modelComponent = ent.GetComponent<ModelComponent>();
|
||||
const auto& component = ent.GetComponent<MeshColliderComponent>();
|
||||
|
||||
if (modelComponent.ModelResource)
|
||||
{
|
||||
uint32_t subMeshId = component.SubMesh;
|
||||
const std::vector<Ref<Mesh>>& submeshes = modelComponent.ModelResource->GetMeshes();
|
||||
if (subMeshId >= submeshes.size())
|
||||
{
|
||||
Logger::Log("Cannot create mesh collider, invalid submesh ID", WARNING);
|
||||
}
|
||||
Ref<Mesh> mesh = submeshes[subMeshId];
|
||||
auto shape = CreateRef<Physics::MeshShape>(mesh);
|
||||
rigidBody = CreateRef<Physics::RigidBody>(rigidBodyComponent.Mass, transform.GetGlobalPosition(), transform.GetGlobalTransform(), shape, ent);
|
||||
PhysicsManager::Get().RegisterBody(rigidBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//const auto characterControllerView = m_Scene->m_Registry.view<TransformComponent, CharacterControllerComponent>();
|
||||
//for (auto e : characterControllerView)
|
||||
//{
|
||||
// Entity ent = Entity({ e, m_Scene });
|
||||
// auto [transformComponent, ccc] = view.get<TransformComponent, CharacterControllerComponent>(e);
|
||||
|
||||
//auto& physicsObject = CreateRef<Physics::CharacterController>(ccc.);
|
||||
//}
|
||||
|
||||
//// character controllers
|
||||
//auto ccview = m_Scene->m_Registry.view<TransformComponent, CharacterControllerComponent>();
|
||||
//for (auto e : ccview)
|
||||
//{
|
||||
// auto [transform, cc] = ccview.get<TransformComponent, CharacterControllerComponent>(e);
|
||||
|
||||
// cc.CharacterController = CreateRef<Physics::CharacterController>(cc.Height, cc.Radius, cc.Mass, transform.GetLocalPosition());
|
||||
// Entity ent = Entity({ e, m_Scene });
|
||||
// cc.CharacterController->SetEntity(ent);
|
||||
|
||||
// PhysicsManager::Get()->RegisterCharacterController(cc.CharacterController);
|
||||
//}
|
||||
|
||||
auto bspView = m_Scene->m_Registry.view<TransformComponent, BSPBrushComponent, ModelComponent>();
|
||||
for (auto e : bspView)
|
||||
{
|
||||
Entity ent = Entity({ e, m_Scene });
|
||||
auto [transform, brush, model] = bspView.get<TransformComponent, BSPBrushComponent, ModelComponent>(e);
|
||||
|
||||
if (!brush.IsSolid)
|
||||
continue;
|
||||
|
||||
for (const auto& h : brush.Hulls)
|
||||
{
|
||||
Ref<Physics::ConvexHullShape> meshShape = CreateRef<Physics::ConvexHullShape>(h);
|
||||
Ref<Physics::RigidBody> btRigidbody = CreateRef<Physics::RigidBody>(0.0f, transform.GetGlobalPosition(), transform.GetGlobalTransform(), meshShape, ent);
|
||||
|
||||
btRigidbody->SetEntityID(Entity{ e, m_Scene });
|
||||
brush.Rigidbody.push_back(btRigidbody);
|
||||
PhysicsManager::Get().RegisterBody(btRigidbody);
|
||||
}
|
||||
}
|
||||
InitializeRigidbodies();
|
||||
InitializeCharacterControllers();
|
||||
InitializeQuakeMap();
|
||||
|
||||
// TODO: Triggers
|
||||
|
||||
//auto bspTriggerView = m_Scene->m_Registry.view<TransformComponent, BSPBrushComponent, TriggerZone>();
|
||||
//for (auto e : bspTriggerView)
|
||||
//{
|
||||
@@ -140,6 +42,7 @@ namespace Nuake
|
||||
|
||||
// PhysicsManager::Get()->RegisterGhostBody(ghostBody);
|
||||
//}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -219,4 +122,177 @@ namespace Nuake
|
||||
{
|
||||
PhysicsManager::Get().Reset();
|
||||
}
|
||||
|
||||
void PhysicsSystem::InitializeQuakeMap()
|
||||
{
|
||||
auto quakeBrushesView = m_Scene->m_Registry.view<TransformComponent, BSPBrushComponent, ModelComponent>();
|
||||
for (auto e : quakeBrushesView)
|
||||
{
|
||||
const auto [transformComponent, brushComponent, modelComponent] = quakeBrushesView.get<TransformComponent, BSPBrushComponent, ModelComponent>(e);
|
||||
|
||||
// Doesn't apply to non-solid brushes
|
||||
if (!brushComponent.IsSolid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const auto& hull : brushComponent.Hulls)
|
||||
{
|
||||
const auto entity = Entity({ e, m_Scene });
|
||||
const Vector3 startPosition = transformComponent.GetGlobalPosition();
|
||||
const Matrix4 startTransform = transformComponent.GetGlobalTransform();
|
||||
const auto collisionShape = CreateRef<Physics::ConvexHullShape>(hull);
|
||||
|
||||
auto rigidBody = CreateRef<Physics::RigidBody>(0.0f, startPosition, startTransform, collisionShape, entity);
|
||||
brushComponent.Rigidbody.push_back(rigidBody);
|
||||
|
||||
PhysicsManager::Get().RegisterBody(rigidBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsSystem::InitializeShapes()
|
||||
{
|
||||
const auto boxView = m_Scene->m_Registry.view<BoxColliderComponent>();
|
||||
for (auto entity : boxView)
|
||||
{
|
||||
auto& boxComponent = boxView.get<BoxColliderComponent>(entity);
|
||||
boxComponent.Box = CreateRef<Physics::Box>(boxComponent.Size);
|
||||
}
|
||||
|
||||
const auto capsuleView = m_Scene->m_Registry.view<CapsuleColliderComponent>();
|
||||
for (auto entity : capsuleView)
|
||||
{
|
||||
auto& capsuleComponent = capsuleView.get<CapsuleColliderComponent>(entity);
|
||||
float radius = capsuleComponent.Radius;
|
||||
float height = capsuleComponent.Height;
|
||||
capsuleComponent.Capsule = CreateRef<Physics::Capsule>(radius, height);
|
||||
}
|
||||
|
||||
const auto sphereView = m_Scene->m_Registry.view<SphereColliderComponent>();
|
||||
for (auto entity : sphereView)
|
||||
{
|
||||
auto& sphereComponent = sphereView.get<SphereColliderComponent>(entity);
|
||||
sphereComponent.Sphere = CreateRef<Physics::Sphere>(sphereComponent.Radius);
|
||||
}
|
||||
|
||||
const auto meshColliderView = m_Scene->m_Registry.view<MeshColliderComponent>();
|
||||
for (auto e : meshColliderView)
|
||||
{
|
||||
Entity entity { e, m_Scene };
|
||||
if (!entity.HasComponent<ModelComponent>())
|
||||
{
|
||||
Logger::Log("Cannot use mesh collider without model component", WARNING);
|
||||
}
|
||||
|
||||
auto meshColliderComponent = meshColliderView.get<MeshColliderComponent>(e);
|
||||
const auto& modelComponent = entity.GetComponent<ModelComponent>();
|
||||
|
||||
if (modelComponent.ModelResource)
|
||||
{
|
||||
uint32_t subMeshId = meshColliderComponent.SubMesh;
|
||||
const std::vector<Ref<Mesh>>& submeshes = modelComponent.ModelResource->GetMeshes();
|
||||
if (subMeshId >= submeshes.size())
|
||||
{
|
||||
Logger::Log("Cannot create mesh collider, invalid submesh ID", WARNING);
|
||||
}
|
||||
|
||||
Ref<Mesh> mesh = submeshes[subMeshId];
|
||||
meshColliderComponent.Shape = CreateRef<Physics::MeshShape>(mesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsSystem::InitializeRigidbodies()
|
||||
{
|
||||
auto view = m_Scene->m_Registry.view<TransformComponent, RigidBodyComponent>();
|
||||
for (auto e : view)
|
||||
{
|
||||
auto [transform, rigidBodyComponent] = view.get<TransformComponent, RigidBodyComponent>(e);
|
||||
Entity ent = Entity({ e, m_Scene });
|
||||
Ref<Physics::RigidBody> rigidBody;
|
||||
if (ent.HasComponent<BoxColliderComponent>())
|
||||
{
|
||||
float mass = rigidBodyComponent.Mass;
|
||||
|
||||
BoxColliderComponent& boxComponent = ent.GetComponent<BoxColliderComponent>();
|
||||
Ref<Physics::Box> boxShape = CreateRef<Physics::Box>(boxComponent.Size);
|
||||
|
||||
rigidBody = CreateRef<Physics::RigidBody>(rigidBodyComponent.Mass, transform.GetGlobalPosition(), transform.GetGlobalTransform(), boxShape, ent);
|
||||
PhysicsManager::Get().RegisterBody(rigidBody);
|
||||
}
|
||||
|
||||
if (ent.HasComponent<CapsuleColliderComponent>())
|
||||
{
|
||||
auto& capsuleComponent = ent.GetComponent<CapsuleColliderComponent>();
|
||||
float radius = capsuleComponent.Radius;
|
||||
float height = capsuleComponent.Height;
|
||||
auto capsuleShape = CreateRef<Physics::Capsule>(radius, height);
|
||||
|
||||
rigidBody = CreateRef<Physics::RigidBody>(rigidBodyComponent.Mass, transform.GetGlobalPosition(), transform.GetGlobalTransform(), capsuleShape, ent);
|
||||
PhysicsManager::Get().RegisterBody(rigidBody);
|
||||
}
|
||||
|
||||
if (ent.HasComponent<SphereColliderComponent>())
|
||||
{
|
||||
float mass = rigidBodyComponent.Mass;
|
||||
|
||||
const auto& component = ent.GetComponent<SphereColliderComponent>();
|
||||
auto shape = CreateRef<Physics::Sphere>(component.Radius);
|
||||
|
||||
rigidBody = CreateRef<Physics::RigidBody>(rigidBodyComponent.Mass, transform.GetGlobalPosition(), transform.GetGlobalTransform(), shape, ent);
|
||||
PhysicsManager::Get().RegisterBody(rigidBody);
|
||||
}
|
||||
|
||||
if (ent.HasComponent<MeshColliderComponent>())
|
||||
{
|
||||
if (!ent.HasComponent<ModelComponent>())
|
||||
{
|
||||
Logger::Log("Cannot use mesh collider without model component", WARNING);
|
||||
}
|
||||
const auto& modelComponent = ent.GetComponent<ModelComponent>();
|
||||
const auto& component = ent.GetComponent<MeshColliderComponent>();
|
||||
|
||||
if (modelComponent.ModelResource)
|
||||
{
|
||||
uint32_t subMeshId = component.SubMesh;
|
||||
const std::vector<Ref<Mesh>>& submeshes = modelComponent.ModelResource->GetMeshes();
|
||||
if (subMeshId >= submeshes.size())
|
||||
{
|
||||
Logger::Log("Cannot create mesh collider, invalid submesh ID", WARNING);
|
||||
}
|
||||
Ref<Mesh> mesh = submeshes[subMeshId];
|
||||
auto shape = CreateRef<Physics::MeshShape>(mesh);
|
||||
rigidBody = CreateRef<Physics::RigidBody>(rigidBodyComponent.Mass, transform.GetGlobalPosition(), transform.GetGlobalTransform(), shape, ent);
|
||||
PhysicsManager::Get().RegisterBody(rigidBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsSystem::InitializeCharacterControllers()
|
||||
{
|
||||
auto characterControllerView = m_Scene->m_Registry.view<TransformComponent, CharacterControllerComponent>();
|
||||
for (const auto& e : characterControllerView)
|
||||
{
|
||||
Entity entity = Entity({ e, m_Scene });
|
||||
auto [transformComponent, characterControllerComponent] = characterControllerView.get<TransformComponent, CharacterControllerComponent>(e);
|
||||
|
||||
if (entity.HasComponent<CapsuleColliderComponent>())
|
||||
{
|
||||
const auto& capsuleColliderComponent = entity.GetComponent<CapsuleColliderComponent>();
|
||||
auto& capsule = capsuleColliderComponent.Capsule;
|
||||
|
||||
float friction = characterControllerComponent.Friction;
|
||||
float maxSlopeAngle = characterControllerComponent.MaxSlopeAngle;
|
||||
auto characterController = CreateRef<Physics::CharacterController>(capsule, friction, maxSlopeAngle);
|
||||
characterController->SetEntity(entity); // Used to link back to the entity
|
||||
|
||||
characterControllerComponent.CharacterController = characterController;
|
||||
PhysicsManager::Get().RegisterCharacterController(characterControllerComponent.CharacterController);
|
||||
}
|
||||
|
||||
// TODO: Other types of collider supported for character controller?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,5 +12,12 @@ namespace Nuake
|
||||
void Draw() override {}
|
||||
void FixedUpdate(Timestep ts) override;
|
||||
void Exit() override;
|
||||
|
||||
private:
|
||||
|
||||
void InitializeShapes();
|
||||
void InitializeQuakeMap();
|
||||
void InitializeRigidbodies();
|
||||
void InitializeCharacterControllers();
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user