From ec2695bc6cb84f3f4507f2b93632c93755b8e4e4 Mon Sep 17 00:00:00 2001 From: Sergey Lapin Date: Thu, 2 Apr 2026 05:54:58 +0300 Subject: [PATCH] Now Mesh collider works --- src/features/editScene/physics/physics.cpp | 64 ++++++++++++++++--- .../editScene/systems/PhysicsSystem.cpp | 31 +++++++-- 2 files changed, 81 insertions(+), 14 deletions(-) diff --git a/src/features/editScene/physics/physics.cpp b/src/features/editScene/physics/physics.cpp index bd15c13..088f935 100644 --- a/src/features/editScene/physics/physics.cpp +++ b/src/features/editScene/physics/physics.cpp @@ -1117,22 +1117,70 @@ public: for (j = 0; j < indices.size() / 3; j++) triangles[j] = { indices[j * 3 + 0], indices[j * 3 + 1], indices[j * 3 + 2] }; + + // Validate we have enough data + if (vertices.size() < 3) { + Ogre::LogManager::getSingleton().logMessage( + "ERROR: Mesh has too few vertices: " + mesh->getName() + + " (" + Ogre::StringConverter::toString(vertices.size()) + ")"); + return JPH::ShapeRefC(); + } + if (triangles.size() < 1) { + Ogre::LogManager::getSingleton().logMessage( + "ERROR: Mesh has no triangles: " + mesh->getName()); + return JPH::ShapeRefC(); + } + JPH::MeshShapeSettings mesh_shape_settings(vertices, triangles); + + // Configure settings to be more permissive + mesh_shape_settings.mPerTriangleUserData = false; + + // Log mesh stats for debugging + Ogre::LogManager::getSingleton().logMessage( + "Creating mesh shape: " + mesh->getName() + + " - Vertices: " + Ogre::StringConverter::toString(vertices.size()) + + " - Triangles: " + Ogre::StringConverter::toString(triangles.size())); + + // Sanitize the mesh data to help with validation + mesh_shape_settings.Sanitize(); + JPH::ShapeSettings::ShapeResult result = mesh_shape_settings.Create(); - OgreAssert(result.Get(), "Can not create mesh shape"); + + if (!result.Get()) { + Ogre::LogManager::getSingleton().logMessage( + "ERROR: Failed to create mesh shape: " + mesh->getName() + + " - Error: " + result.GetError().c_str()); + return JPH::ShapeRefC(); + } + + Ogre::LogManager::getSingleton().logMessage( + "Successfully created mesh shape for: " + mesh->getName()); return result.Get(); } JPH::ShapeRefC createMeshShape(Ogre::String meshName) { - Ogre::DefaultHardwareBufferManager dmgr; - Ogre::MeshPtr mesh = - Ogre::MeshManager::getSingleton().getByName(meshName); - if (!mesh->isLoaded()) { - mesh->setHardwareBufferManager(&dmgr); - mesh->load(); + // Use singleton pattern like convex hull does + auto p = Ogre::DefaultHardwareBufferManager::getSingletonPtr(); + if (!p) { + new Ogre::DefaultHardwareBufferManager; + p = Ogre::DefaultHardwareBufferManager::getSingletonPtr(); } - return createMeshShape(mesh); + + Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().load( + meshName, "General"); + if (mesh.get()) { + if (!mesh->isLoaded()) { + mesh->setHardwareBufferManager(p); + mesh->load(); + } + return createMeshShape(mesh); + } + + Ogre::LogManager::getSingleton().logMessage( + "ERROR: Could not load mesh for collider: " + meshName); + return JPH::ShapeRefC(); } JPH::ShapeRefC createConvexHullShape(Ogre::MeshPtr mesh) { diff --git a/src/features/editScene/systems/PhysicsSystem.cpp b/src/features/editScene/systems/PhysicsSystem.cpp index 343e88e..b69deb7 100644 --- a/src/features/editScene/systems/PhysicsSystem.cpp +++ b/src/features/editScene/systems/PhysicsSystem.cpp @@ -79,16 +79,18 @@ JPH::ShapeRefC EditorPhysicsSystem::createShape(PhysicsColliderComponent& collid case PhysicsColliderComponent::ShapeType::Mesh: { if (!collider.meshName.empty()) { try { - // Ensure mesh is loaded first - Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().load( - collider.meshName, "General"); - if (mesh && mesh->isLoaded()) { - result = m_physics->createMeshShape(collider.meshName); + result = m_physics->createMeshShape(collider.meshName); + if (!result) { + Ogre::LogManager::getSingleton().logMessage( + "Mesh shape creation returned null for: " + collider.meshName); } } catch (const Ogre::Exception& e) { Ogre::LogManager::getSingleton().logMessage( - "Failed to create mesh shape: " + collider.meshName + + "Exception creating mesh shape: " + collider.meshName + " - " + e.getDescription()); + } catch (...) { + Ogre::LogManager::getSingleton().logMessage( + "Unknown exception creating mesh shape: " + collider.meshName); } } break; @@ -171,6 +173,23 @@ void EditorPhysicsSystem::updateRigidBody(flecs::entity entity, removeRigidBody(rigidBody); } + // Check for mesh colliders on dynamic bodies (not supported by Jolt) + bool hasMeshCollider = false; + entity.children([&](flecs::entity child) { + if (child.has()) { + auto& collider = child.get(); + if (collider.shapeType == PhysicsColliderComponent::ShapeType::Mesh) { + hasMeshCollider = true; + } + } + }); + + if (hasMeshCollider && rigidBody.bodyType == RigidBodyComponent::BodyType::Dynamic) { + Ogre::LogManager::getSingleton().logMessage( + "WARNING: Mesh colliders can only be used with Static or Kinematic bodies, not Dynamic." + " The body will be created but may not behave correctly."); + } + // Build collision shape JPH::ShapeRefC shape = buildCompoundShape(entity); if (!shape) return;