Added ability to lock rotation axis of a rigidbody

This commit is contained in:
Antoine Pilote
2023-09-24 00:40:37 -04:00
parent 557c5e281c
commit a09fc40469
6 changed files with 106 additions and 33 deletions

View File

@@ -25,6 +25,37 @@ public:
ImGui::TableNextColumn();
ComponentTableReset(component.Mass, 0.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Lock X axis");
ImGui::TableNextColumn();
ImGui::Checkbox("##lockx", &component.LockX);
ImGui::TableNextColumn();
ComponentTableReset(component.LockX, false);
}
ImGui::TableNextColumn();
{
ImGui::Text("Lock Y axis");
ImGui::TableNextColumn();
ImGui::Checkbox("##locky", &component.LockY);
ImGui::TableNextColumn();
ComponentTableReset(component.LockY, false);
}
ImGui::TableNextColumn();
{
ImGui::Text("Lock Z axis");
ImGui::TableNextColumn();
ImGui::Checkbox("##lockz", &component.LockZ);
ImGui::TableNextColumn();
ComponentTableReset(component.LockZ, false);
}
ImGui::TableNextColumn();
}
EndComponentTable();
}

View File

@@ -85,7 +85,7 @@ namespace Nuake
case Layers::MOVING:
return true; // Moving collides with everything
case Layers::KINEMATIC:
return inObject2 == Layers::NON_MOVING; // Only collides with static
return inObject2 == Layers::NON_MOVING || inObject2 == Layers::MOVING; // Only collides with non moving
default:
//JPH_ASSERT(false);
return false;
@@ -306,7 +306,7 @@ namespace Nuake
if (mass > 0.0f && !isMeshShape)
{
motionType = JPH::EMotionType::Dynamic;
layer = Layers::NON_MOVING;
layer = Layers::MOVING;
}
const auto& startPos = rb->GetPosition();
@@ -316,6 +316,23 @@ namespace Nuake
auto joltShape = GetJoltShape(rb->GetShape());
JPH::BodyCreationSettings bodySettings(joltShape, joltPos, joltRotation, motionType, layer);
bodySettings.mAllowedDOFs = (JPH::EAllowedDOFs::All);
if (rb->GetLockXAxis())
{
bodySettings.mAllowedDOFs ^= JPH::EAllowedDOFs::RotationX;
}
if (rb->GetLockYAxis())
{
bodySettings.mAllowedDOFs ^= JPH::EAllowedDOFs::RotationY;
}
if (rb->GetLockZAxis())
{
bodySettings.mAllowedDOFs ^= JPH::EAllowedDOFs::RotationZ;
}
if (mass > 0.0f)
{
bodySettings.mOverrideMassProperties = JPH::EOverrideMassProperties::CalculateInertia;
@@ -349,8 +366,6 @@ namespace Nuake
const auto& joltRotation = JPH::Quat(bodyRotation.x, bodyRotation.y, bodyRotation.z, bodyRotation.w);
auto character = new JPH::CharacterVirtual(settings, std::move(joltPosition), std::move(joltRotation), _JoltPhysicsSystem.get());
//character->AddToPhysicsSystem(JPH::EActivation::Activate);
// To get the jolt character control from a scene entity.
_registeredCharacters[cc->Owner.GetHandle()] = character;
}

View File

@@ -20,6 +20,9 @@ namespace Nuake
Quat _rotation;
Entity _entity;
bool m_LockXAxis = false;
bool m_LockYAxis = false;
bool m_LockZAxis = false;
public:
float _mass;
Matrix4 _transform;
@@ -30,6 +33,14 @@ namespace Nuake
void UpdateTransform();
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 SetEntityID(Entity ent);
Vector3 GetPosition() const { return _position; }
Quat GetRotation() const { return _rotation; }

View File

@@ -67,12 +67,12 @@ namespace Nuake
std::vector<Vertex> QuadVertices
{
{ Vector3(-1.0f, 1.0f, 0.0f), Vector2(0.0f, 1.0f), Vector3(0, 0, -1) },
{ Vector3(1.0f, 1.0f, 0.0f), Vector2(1.0f, 1.0f), Vector3(0, 0, -1) },
{ Vector3(-1.0f, -1.0f, 0.0f), Vector2(0, 0), Vector3(0, 0, -1) },
{ Vector3(1.0f, -1.0f, 0.0f), Vector2(1.0f, 0.0f), Vector3(0, 0, -1) },
{ Vector3(-1.0f, -1.0f, 0.0f), Vector2(0.0f, 0.0f), Vector3(0, 0, -1) },
{ Vector3(1.0f, 1.0f, 0.0f), Vector2(1.0f, 1.0f), Vector3(0, 0, -1) }
{ Vector3(-1.0f, 1.0f, 0.0f), Vector2(0.0f, 1.0f), Vector3(0, 0, -1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(1.0f, 1.0f, 0.0f), Vector2(1.0f, 1.0f), Vector3(0, 0, -1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(-1.0f, -1.0f, 0.0f), Vector2(0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(1.0f, -1.0f, 0.0f), Vector2(1.0f, 0.0f), Vector3(0, 0, -1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(-1.0f, -1.0f, 0.0f), Vector2(0.0f, 0.0f), Vector3(0, 0, -1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(1.0f, 1.0f, 0.0f), Vector2(1.0f, 1.0f), Vector3(0, 0, -1), Vector3(1, 0, 0), Vector3(0, 1, 0) }
};

View File

@@ -13,6 +13,9 @@ namespace Nuake {
{
public:
float Mass;
bool LockX = false;
bool LockY = false;
bool LockZ = false;
Ref<Physics::RigidBody> Rigidbody;
Vector3 QueuedForce = Vector3();
@@ -31,12 +34,31 @@ namespace Nuake {
{
BEGIN_SERIALIZE();
SERIALIZE_VAL_LBL("Mass", Mass);
SERIALIZE_VAL(LockX);
SERIALIZE_VAL(LockY);
SERIALIZE_VAL(LockZ);
END_SERIALIZE();
}
bool Deserialize(const json& j)
{
Mass = j["Mass"];
if (j.contains("LockX"))
{
LockX = j["LockX"];
}
if (j.contains("LockY"))
{
LockY = j["LockY"];
}
if (j.contains("LockZ"))
{
LockZ = j["LockZ"];
}
return true;
}
};

View File

@@ -218,7 +218,7 @@ namespace Nuake
auto [transform, rigidBodyComponent] = view.get<TransformComponent, RigidBodyComponent>(e);
Entity ent = Entity({ e, m_Scene });
Ref<Physics::RigidBody> rigidBody;
Ref<Physics::PhysicShape> shape;
if (rigidBodyComponent.GetRigidBody())
{
continue;
@@ -226,12 +226,8 @@ namespace Nuake
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.GetGlobalRotation(), transform.GetGlobalTransform(), boxShape, ent);
PhysicsManager::Get().RegisterBody(rigidBody);
shape = CreateRef<Physics::Box>(boxComponent.Size);
}
if (ent.HasComponent<CapsuleColliderComponent>())
@@ -239,10 +235,7 @@ namespace Nuake
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.GetGlobalRotation(), transform.GetGlobalTransform(), capsuleShape, ent);
PhysicsManager::Get().RegisterBody(rigidBody);
shape = CreateRef<Physics::Capsule>(radius, height);
}
if (ent.HasComponent<CylinderColliderComponent>())
@@ -250,21 +243,13 @@ namespace Nuake
auto& cylinderComponent = ent.GetComponent<CylinderColliderComponent>();
float radius = cylinderComponent.Radius;
float height = cylinderComponent.Height;
auto cylinderShape = CreateRef<Physics::Cylinder>(radius, height);
rigidBody = CreateRef<Physics::RigidBody>(rigidBodyComponent.Mass, transform.GetGlobalPosition(), transform.GetGlobalRotation(), transform.GetGlobalTransform(), cylinderShape, ent);
PhysicsManager::Get().RegisterBody(rigidBody);
shape = CreateRef<Physics::Cylinder>(radius, height);
}
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.GetGlobalRotation(), transform.GetGlobalTransform(), shape, ent);
PhysicsManager::Get().RegisterBody(rigidBody);
shape = CreateRef<Physics::Sphere>(component.Radius);
}
if (ent.HasComponent<MeshColliderComponent>())
@@ -285,13 +270,22 @@ namespace Nuake
{
Logger::Log("Cannot create mesh collider, invalid submesh ID", "physics", WARNING);
}
Ref<Mesh> mesh = submeshes[subMeshId];
auto shape = CreateRef<Physics::MeshShape>(mesh);
rigidBody = CreateRef<Physics::RigidBody>(rigidBodyComponent.Mass, transform.GetGlobalPosition(), transform.GetGlobalRotation(), transform.GetGlobalTransform(), shape, ent);
PhysicsManager::Get().RegisterBody(rigidBody);
shape = CreateRef<Physics::MeshShape>(mesh);
}
}
if (!shape)
{
continue;
}
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);
PhysicsManager::Get().RegisterBody(rigidBody);
rigidBodyComponent.Rigidbody = rigidBody;
}
}