From 1c13c7ef2d653f18a40fb55bd9a37d261220999e Mon Sep 17 00:00:00 2001 From: antopilo Date: Wed, 8 Mar 2023 22:37:03 -0500 Subject: [PATCH] Added mesh colliders --- .../src/ComponentsPanel/MeshColliderPanel.h | 40 +++++++++++++++++++ Editor/src/Windows/EditorSelectionPanel.cpp | 2 + Editor/src/Windows/EditorSelectionPanel.h | 2 + Nuake/src/Core/Physics/DynamicWorld.cpp | 12 ++---- Nuake/src/Scene/Components/MeshCollider.h | 19 ++++++++- Nuake/src/Scene/Entities/Entity.cpp | 3 ++ Nuake/src/Scene/Systems/PhysicsSystem.cpp | 29 ++++++++++---- 7 files changed, 88 insertions(+), 19 deletions(-) create mode 100644 Editor/src/ComponentsPanel/MeshColliderPanel.h diff --git a/Editor/src/ComponentsPanel/MeshColliderPanel.h b/Editor/src/ComponentsPanel/MeshColliderPanel.h new file mode 100644 index 00000000..b0cd959f --- /dev/null +++ b/Editor/src/ComponentsPanel/MeshColliderPanel.h @@ -0,0 +1,40 @@ +#pragma once +#include +#include "ComponentPanel.h" +#include "ModelResourceInspector.h" + +#include +#include + +#include +#include + +class MeshColliderPanel : ComponentPanel { +private: + Scope _modelInspector; + bool _expanded = false; +public: + MeshColliderPanel() + { + CreateScope(); + } + + void Draw(Nuake::Entity entity) override + { + using namespace Nuake; + if (!entity.HasComponent()) + return; + + MeshColliderComponent& component = entity.GetComponent(); + BeginComponentTable(MESH, MeshColliderComponent); + { + ImGui::Text("Model"); + ImGui::TableNextColumn(); + + ImGui::DragInt("##Submesh", &component.SubMesh, 0, 255); + ImGui::TableNextColumn(); + ComponentTableReset(component.SubMesh, 0); + } + EndComponentTable(); + } +}; \ No newline at end of file diff --git a/Editor/src/Windows/EditorSelectionPanel.cpp b/Editor/src/Windows/EditorSelectionPanel.cpp index 531306a9..a25845f5 100644 --- a/Editor/src/Windows/EditorSelectionPanel.cpp +++ b/Editor/src/Windows/EditorSelectionPanel.cpp @@ -101,6 +101,8 @@ void EditorSelectionPanel::DrawEntity(Nuake::Entity entity) mRigidbodyPanel.Draw(entity); mBoxColliderPanel.Draw(entity); mSphereColliderPanel.Draw(entity); + mMeshColliderPanel.Draw(entity); + /* if (Selection.Entity.HasComponent()) { diff --git a/Editor/src/Windows/EditorSelectionPanel.h b/Editor/src/Windows/EditorSelectionPanel.h index f4ea99a1..291e71a3 100644 --- a/Editor/src/Windows/EditorSelectionPanel.h +++ b/Editor/src/Windows/EditorSelectionPanel.h @@ -14,6 +14,7 @@ #include "../ComponentsPanel/RigidbodyPanel.h" #include "../ComponentsPanel/BoxColliderPanel.h" #include "../ComponentsPanel/SphereColliderPanel.h" +#include "../ComponentsPanel/MeshColliderPanel.h" class EditorSelectionPanel { private: @@ -26,6 +27,7 @@ private: RigidbodyPanel mRigidbodyPanel; BoxColliderPanel mBoxColliderPanel; SphereColliderPanel mSphereColliderPanel; + MeshColliderPanel mMeshColliderPanel; Ref currentFile; Ref selectedResource; diff --git a/Nuake/src/Core/Physics/DynamicWorld.cpp b/Nuake/src/Core/Physics/DynamicWorld.cpp index bc5742a6..08343187 100644 --- a/Nuake/src/Core/Physics/DynamicWorld.cpp +++ b/Nuake/src/Core/Physics/DynamicWorld.cpp @@ -254,6 +254,7 @@ namespace Nuake void DynamicWorld::DrawDebug() { + } void DynamicWorld::SetGravity(glm::vec3 g) @@ -371,6 +372,7 @@ namespace Nuake JPH::Vec3 position = bodyInterface.GetCenterOfMassPosition(bodyId); JPH::Vec3 velocity = bodyInterface.GetLinearVelocity(bodyId); JPH::Mat44 joltTransform = bodyInterface.GetWorldTransform(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), @@ -387,9 +389,6 @@ namespace Nuake transformComponent.SetGlobalPosition(Vector3(position.GetX(), position.GetY(), position.GetZ())); transformComponent.SetGlobalTransform(transform); transformComponent.SetLocalTransform(transform); - std::cout << "Object with Name: " << name << " has moved!"; - 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; @@ -404,12 +403,7 @@ namespace Nuake void DynamicWorld::Clear() { _stepCount = 0; - - for (auto& b : _registeredBodies) - { - _JoltBodyInterface->RemoveBody((JPH::BodyID)b); - } - + _JoltBodyInterface->RemoveBodies((JPH::BodyID*)_registeredBodies.data(), _registeredBodies.size()); _registeredBodies.clear(); } } diff --git a/Nuake/src/Scene/Components/MeshCollider.h b/Nuake/src/Scene/Components/MeshCollider.h index 7f294583..0d813853 100644 --- a/Nuake/src/Scene/Components/MeshCollider.h +++ b/Nuake/src/Scene/Components/MeshCollider.h @@ -6,8 +6,23 @@ namespace Nuake { class MeshColliderComponent { public: - Ref MeshShape; - Ref Mesh; + int SubMesh = 0; bool IsTrigger; + + json Serialize() + { + BEGIN_SERIALIZE(); + j["IsTrigger"] = IsTrigger; + SERIALIZE_VAL(SubMesh); + END_SERIALIZE(); + } + + bool Deserialize(const std::string& str) + { + BEGIN_DESERIALIZE(); + this->IsTrigger = j["IsTrigger"]; + this->SubMesh = j["SubMesh"]; + return true; + } }; } diff --git a/Nuake/src/Scene/Entities/Entity.cpp b/Nuake/src/Scene/Entities/Entity.cpp index 12405f29..ab7a57d9 100644 --- a/Nuake/src/Scene/Entities/Entity.cpp +++ b/Nuake/src/Scene/Entities/Entity.cpp @@ -48,6 +48,8 @@ namespace Nuake SERIALIZE_OBJECT_REF_LBL("BoxColliderComponent", GetComponent()); if (HasComponent()) SERIALIZE_OBJECT_REF_LBL("SphereColliderComponent", GetComponent()); + if (HasComponent()) + SERIALIZE_OBJECT_REF_LBL("MeshColliderComponent", GetComponent()); if (HasComponent()) SERIALIZE_OBJECT_REF_LBL("ModelComponent", GetComponent()); if (HasComponent()) @@ -78,6 +80,7 @@ namespace Nuake DESERIALIZE_COMPONENT(WrenScriptComponent); DESERIALIZE_COMPONENT(CharacterControllerComponent); DESERIALIZE_COMPONENT(BoxColliderComponent); + DESERIALIZE_COMPONENT(MeshColliderComponent); DESERIALIZE_COMPONENT(SphereColliderComponent); DESERIALIZE_COMPONENT(RigidBodyComponent); return true; diff --git a/Nuake/src/Scene/Systems/PhysicsSystem.cpp b/Nuake/src/Scene/Systems/PhysicsSystem.cpp index b83d6d64..28a44edc 100644 --- a/Nuake/src/Scene/Systems/PhysicsSystem.cpp +++ b/Nuake/src/Scene/Systems/PhysicsSystem.cpp @@ -3,7 +3,7 @@ #include "src/Scene/Components/BoxCollider.h" #include "src/Scene/Components/SphereCollider.h" #include "src/Scene/Components/MeshCollider.h" - +#include "src/Scene/Components/ModelComponent.h" #include #include "src/Scene/Entities/Entity.h" #include @@ -50,15 +50,28 @@ namespace Nuake PhysicsManager::Get()->RegisterBody(rigidBody); } - if (ent.HasComponent()) + if (ent.HasComponent()) { - float mass = rigidbody.Mass; + if (!ent.HasComponent()) + { + Logger::Log("Cannot use mesh collider without model component", WARNING); + } + const auto& modelComponent = ent.GetComponent(); + const auto& component = ent.GetComponent(); - const auto& component = ent.GetComponent(); - auto shape = CreateRef(component.Radius); - - rigidBody = CreateRef(mass, transform.GetGlobalPosition(), shape, ent); - PhysicsManager::Get()->RegisterBody(rigidBody); + if (modelComponent.ModelResource) + { + uint32_t subMeshId = component.SubMesh; + const std::vector>& submeshes = modelComponent.ModelResource->GetMeshes(); + if (subMeshId >= submeshes.size()) + { + Logger::Log("Cannot create mesh collider, invalid submesh ID", WARNING); + } + Ref mesh = submeshes[subMeshId]; + auto shape = CreateRef(mesh); + rigidBody = CreateRef(1.0f, transform.GetGlobalPosition(), shape, ent); + PhysicsManager::Get()->RegisterBody(rigidBody); + } } }