diff --git a/ios/include/FlutterFilamentApi.h b/ios/include/FlutterFilamentApi.h index e5ded8e0..fed53bc2 100644 --- a/ios/include/FlutterFilamentApi.h +++ b/ios/include/FlutterFilamentApi.h @@ -189,10 +189,10 @@ extern "C" FLUTTER_PLUGIN_EXPORT void ios_dummy(); FLUTTER_PLUGIN_EXPORT void flutter_filament_free(void *ptr); FLUTTER_PLUGIN_EXPORT void add_collision_component(void *const sceneManager, EntityId entityId, void (*callback)(const EntityId entityId1, const EntityId entityId2), bool affectsCollidingTransform); - FLUTTER_PLUGIN_EXPORT void mark_nontransformable_collidable(void *const sceneManager, EntityId entityId); - FLUTTER_PLUGIN_EXPORT void unmark_nontransformable_collidable(void *const sceneManager, EntityId entityId); + FLUTTER_PLUGIN_EXPORT EntityId create_geometry(void *const viewer, float* vertices, int numVertices, uint16_t* indices, int numIndices, const char* materialPath); FLUTTER_PLUGIN_EXPORT void set_parent(void *const sceneManager, EntityId child, EntityId parent); + FLUTTER_PLUGIN_EXPORT void test_collisions(void *const sceneManager, EntityId entity); #ifdef __cplusplus } diff --git a/ios/include/SceneManager.hpp b/ios/include/SceneManager.hpp index c72af09c..cbac0282 100644 --- a/ios/include/SceneManager.hpp +++ b/ios/include/SceneManager.hpp @@ -49,6 +49,7 @@ namespace polyvox size_t getLightEntityCount(EntityId e) const noexcept; void updateAnimations(); void updateTransforms(); + void testCollisions(EntityId entity); bool setMaterialColor(EntityId e, const char *meshName, int materialInstance, const float r, const float g, const float b, const float a); bool setMorphAnimationBuffer( @@ -105,10 +106,8 @@ namespace polyvox const char* getEntityNameAt(EntityId entity, int index, bool renderableOnly); void addCollisionComponent(EntityId entity, void (*onCollisionCallback)(const EntityId entityId1, const EntityId entityId2), bool affectsCollidingTransform); void removeCollisionComponent(EntityId entityId); - void markNonTransformableCollidable(EntityId entity); - void unmarkNonTransformableCollidable(EntityId entity); - void checkNonTransformableCollisions(); void setParent(EntityId child, EntityId parent); + private: AssetLoader *_assetLoader = nullptr; diff --git a/ios/src/FilamentViewer.cpp b/ios/src/FilamentViewer.cpp index 009b1484..4eb6a6c8 100644 --- a/ios/src/FilamentViewer.cpp +++ b/ios/src/FilamentViewer.cpp @@ -1042,7 +1042,6 @@ namespace polyvox _sceneManager->updateTransforms(); _sceneManager->updateAnimations(); - _sceneManager->checkNonTransformableCollisions(); _cumulativeAnimationUpdateTime += tmr.elapsed(); diff --git a/ios/src/FlutterFilamentApi.cpp b/ios/src/FlutterFilamentApi.cpp index e3e5e898..cd8c9ac9 100644 --- a/ios/src/FlutterFilamentApi.cpp +++ b/ios/src/FlutterFilamentApi.cpp @@ -566,15 +566,6 @@ extern "C" ((SceneManager*)sceneManager)->addCollisionComponent(entityId, onCollisionCallback, affectsCollidingTransform); } - FLUTTER_PLUGIN_EXPORT void mark_nontransformable_collidable(void *const sceneManager, EntityId entityId) { - ((SceneManager*)sceneManager)->markNonTransformableCollidable(entityId); - } - - FLUTTER_PLUGIN_EXPORT void unmark_nontransformable_collidable(void *const sceneManager, EntityId entityId) { - ((SceneManager*)sceneManager)->unmarkNonTransformableCollidable(entityId); - } - - FLUTTER_PLUGIN_EXPORT EntityId create_geometry(void *const viewer, float* vertices, int numVertices, uint16_t* indices, int numIndices, const char* materialPath) { return ((FilamentViewer*)viewer)->createGeometry(vertices, (size_t)numVertices, indices, numIndices, materialPath); } @@ -588,4 +579,8 @@ extern "C" ((SceneManager*)sceneManager)->setParent(child, parent); } + FLUTTER_PLUGIN_EXPORT void test_collisions(void *const sceneManager, EntityId entity) { + ((SceneManager*)sceneManager)->testCollisions(entity); + } + } diff --git a/ios/src/SceneManager.cpp b/ios/src/SceneManager.cpp index db6023ca..1f9e5b1f 100644 --- a/ios/src/SceneManager.cpp +++ b/ios/src/SceneManager.cpp @@ -1237,67 +1237,24 @@ namespace polyvox _collisionComponentManager->elementAt<0>(collisionInstance) = asset.asset->getInstance()->getBoundingBox(); _collisionComponentManager->elementAt<1>(collisionInstance) = onCollisionCallback; _collisionComponentManager->elementAt<2>(collisionInstance) = affectsTransform; - } - void SceneManager::markNonTransformableCollidable(EntityId entityId) { - // Log("Marking entity %d as non-transforming collidable", entityId); - std::lock_guard lock(_mutex); - for(auto& existing : _nonTransformableCollidableEntities) { - if(existing == entityId) { - Log("Collision already exists"); - return; - } + void SceneManager::testCollisions(EntityId entityId) { + const auto &pos = _entityIdLookup.find(entityId); + if (pos == _entityIdLookup.end()) + { + Log("ERROR: asset not found for entity."); + return; } - _nonTransformableCollidableEntities.push_back(entityId); - Log("Mark complete."); - } - void SceneManager::unmarkNonTransformableCollidable(EntityId entityId) { - // Log("Removing non-transformable collidable from entity %d", entityId); + auto &asset = _assets[pos->second]; - std::lock_guard lock(_mutex); - auto begin = _nonTransformableCollidableEntities.begin(); - auto end = _nonTransformableCollidableEntities.end(); - auto removed = std::remove_if(begin, end, [=](EntityId id) { return id == entityId; }); - _nonTransformableCollidableEntities.erase(removed); - } - - void SceneManager::checkNonTransformableCollisions() { - // Log("checkNonTransformableCollisions %d ", _nonTransformableCollidableEntities.size()); - std::lock_guard lock(_mutex); const auto& tm = _engine->getTransformManager(); - for(const auto& entityId : _nonTransformableCollidableEntities) { - const auto &pos = _entityIdLookup.find(entityId); - if (pos == _entityIdLookup.end()) - { - Log("ERROR: asset not found for entity."); - continue; - } - auto &asset = _assets[pos->second]; - auto root = asset.asset->getRoot(); - auto rootId = Entity::smuggle(root); - - auto transformInstance = tm.getInstance(root); - - if(!transformInstance.isValid()) { - Log("Invalid transform, skipping."); - continue; - } - auto parent = tm.getParent(transformInstance); - - if(!parent.isNull()) { - transformInstance = tm.getInstance(parent); - } - auto transform = tm.getTransform(transformInstance); - auto worldTransform = tm.getWorldTransform(transformInstance); - - Log("Entity id %d, Local Transform : %f %f %f World transform %f %f %f", rootId, transform[3][0],transform[3][1],transform[3][2], worldTransform[0], worldTransform[1], worldTransform[2]); - auto boundingBox = asset.asset->getInstance()->getBoundingBox(); - auto worldBoundingBox = boundingBox.transform(worldTransform); - Log("Checking bounding box at center %f %f %f (world transformed centger %f %f %f)", boundingBox.center().x,boundingBox.center().y, boundingBox.center().z, worldBoundingBox.center().x, worldBoundingBox.center().y, worldBoundingBox.center().z); - _collisionComponentManager->collides(entityId, worldBoundingBox); - } + auto transformInstance = tm.getInstance(asset.asset->getRoot()); + auto worldTransform = tm.getWorldTransform(transformInstance); + auto aabb = asset.asset->getInstance()->getBoundingBox(); + aabb = aabb.transform(worldTransform); + _collisionComponentManager->collides(entityId, aabb); } @@ -1305,6 +1262,7 @@ namespace polyvox std::lock_guard lock(_mutex); auto &tm = _engine->getTransformManager(); + for ( const auto &[entityId, transformUpdate]: _transformUpdates ) { const auto &pos = _entityIdLookup.find(entityId); if (pos == _entityIdLookup.end()) diff --git a/ios/src/Untitled-1.cpp b/ios/src/Untitled-1.cpp deleted file mode 100644 index 09599183..00000000 --- a/ios/src/Untitled-1.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// we know there's been a collision, but we want to adjust the direction vector to continue movement in the non-colliding direction - - // first, we need to find the AABB plane that we have collided with - - auto vertices = targetBox.getCorners().vertices; - - // each entry here is a plane from the target bounding box - // (we drop the fourth vertex because it's mathematically not necessary to define the plane) - std::vector> planes = { - { - vertices[0],vertices[2],vertices[4] // bottom - }, - { - vertices[1],vertices[3],vertices[5] // top - }, - { - vertices[0],vertices[1],vertices[4] // back - }, - { - vertices[0],vertices[1],vertices[2] // left - }, - { - vertices[4],vertices[5],vertices[6] // right - }, - { - vertices[2],vertices[3],vertices[6] //front - }, - }; - - // now, iterate over each plane and project the intersecting source vertex onto it - // the smallest value will be the closest plane - auto sourceVertex = sourceCorners.vertices[i]; - int planeIndex = -1; - int minDist = 999999.0f; - filament::math::float3 projection; - for(int j = 0; j < 6; j++) { - // translate the plane so the intersecting source vertex is at the origin - auto plane = std::vector{ planes[j][0] - sourceVertex, planes[j][1] - sourceVertex, planes[j][2] - sourceVertex }; - - // cross product of the two known co-planar vectors to find the normal - auto normal = normalize(cross(plane[1] - plane[0], plane[2] - plane[1])); - - // project the normal onto the original (untranslated) plane vector - auto dist = dot(planes[j][0], normal) / norm(planes[j][0]); - Log("Dist : %f", dist); - if(dist < minDist) { - minDist = dist; - planeIndex = j; - } - } - Log("Collision with plane index %d", planeIndex); - auto sourceNormal = normalize(cross(planes[planeIndex][1] - planes[planeIndex][0], planes[planeIndex][2] - planes[planeIndex][1])); - - projection = direction - (sourceNormal * dot(sourceNormal, direction)); \ No newline at end of file diff --git a/lib/filament_controller.dart b/lib/filament_controller.dart index 4e90b58c..aecfa87b 100644 --- a/lib/filament_controller.dart +++ b/lib/filament_controller.dart @@ -6,6 +6,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_filament/animations/animation_data.dart'; import 'package:flutter_filament/entities/entity_transform_controller.dart'; +import 'package:flutter_filament/generated_bindings.dart'; import 'package:vector_math/vector_math_64.dart'; // a handle that can be safely passed back to the rendering layer to manipulate an Entity @@ -594,16 +595,6 @@ abstract class FilamentController { {void Function(int entityId1, int entityId2)? callback, bool affectsCollingTransform = false}); - /// - /// Make [entity] collidable, without affecting its transform. - /// - Future markNonTransformableCollidable(FilamentEntity entity); - - /// - /// Make [entity] no longer collidable. - /// - Future unmarkNonTransformableCollidable(FilamentEntity entity); - /// /// Creates a (renderable) entity with the specified geometry and adds to the scene. /// @@ -614,4 +605,10 @@ abstract class FilamentController { /// Sets the parent transform of [child] to the transform of [parent]. /// Future setParent(FilamentEntity child, FilamentEntity parent); + + /// + /// Test all collidable entities against this entity to see if any have collided. + /// This method returns void; the relevant callback passed to [addCollisionComponent] will be fired if a collision is detected. + /// + Future testCollisions(FilamentEntity entity); } diff --git a/lib/filament_controller_ffi.dart b/lib/filament_controller_ffi.dart index 61477f2b..5218e30f 100644 --- a/lib/filament_controller_ffi.dart +++ b/lib/filament_controller_ffi.dart @@ -1437,16 +1437,6 @@ class FilamentControllerFFI extends FilamentController { } } - @override - Future markNonTransformableCollidable(FilamentEntity entity) async { - mark_nontransformable_collidable(_sceneManager!, entity); - } - - @override - Future unmarkNonTransformableCollidable(FilamentEntity entity) async { - unmark_nontransformable_collidable(_sceneManager!, entity); - } - @override Future createGeometry( List vertices, List indices, String? materialPath) async { @@ -1489,4 +1479,9 @@ class FilamentControllerFFI extends FilamentController { } set_parent(_sceneManager!, child, parent); } + + @override + Future testCollisions(FilamentEntity entity) async { + test_collisions(_sceneManager!, entity); + } } diff --git a/lib/generated_bindings.dart b/lib/generated_bindings.dart index 99d56974..2a33add6 100644 --- a/lib/generated_bindings.dart +++ b/lib/generated_bindings.dart @@ -891,22 +891,6 @@ external void add_collision_component( bool affectsCollidingTransform, ); -@ffi.Native, EntityId)>( - symbol: 'mark_nontransformable_collidable', - assetId: 'flutter_filament_plugin') -external void mark_nontransformable_collidable( - ffi.Pointer sceneManager, - int entityId, -); - -@ffi.Native, EntityId)>( - symbol: 'unmark_nontransformable_collidable', - assetId: 'flutter_filament_plugin') -external void unmark_nontransformable_collidable( - ffi.Pointer sceneManager, - int entityId, -); - @ffi.Native< EntityId Function(ffi.Pointer, ffi.Pointer, ffi.Int, ffi.Pointer, ffi.Int, ffi.Pointer)>( @@ -928,6 +912,13 @@ external void set_parent( int parent, ); +@ffi.Native, EntityId)>( + symbol: 'test_collisions', assetId: 'flutter_filament_plugin') +external void test_collisions( + ffi.Pointer sceneManager, + int entity, +); + @ffi.Native< ffi.Pointer Function( ffi.Pointer,