add testCollisions method for manual collision checking
This commit is contained in:
@@ -189,10 +189,10 @@ extern "C"
|
|||||||
FLUTTER_PLUGIN_EXPORT void ios_dummy();
|
FLUTTER_PLUGIN_EXPORT void ios_dummy();
|
||||||
FLUTTER_PLUGIN_EXPORT void flutter_filament_free(void *ptr);
|
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 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 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 set_parent(void *const sceneManager, EntityId child, EntityId parent);
|
||||||
|
FLUTTER_PLUGIN_EXPORT void test_collisions(void *const sceneManager, EntityId entity);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ namespace polyvox
|
|||||||
size_t getLightEntityCount(EntityId e) const noexcept;
|
size_t getLightEntityCount(EntityId e) const noexcept;
|
||||||
void updateAnimations();
|
void updateAnimations();
|
||||||
void updateTransforms();
|
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 setMaterialColor(EntityId e, const char *meshName, int materialInstance, const float r, const float g, const float b, const float a);
|
||||||
|
|
||||||
bool setMorphAnimationBuffer(
|
bool setMorphAnimationBuffer(
|
||||||
@@ -105,10 +106,8 @@ namespace polyvox
|
|||||||
const char* getEntityNameAt(EntityId entity, int index, bool renderableOnly);
|
const char* getEntityNameAt(EntityId entity, int index, bool renderableOnly);
|
||||||
void addCollisionComponent(EntityId entity, void (*onCollisionCallback)(const EntityId entityId1, const EntityId entityId2), bool affectsCollidingTransform);
|
void addCollisionComponent(EntityId entity, void (*onCollisionCallback)(const EntityId entityId1, const EntityId entityId2), bool affectsCollidingTransform);
|
||||||
void removeCollisionComponent(EntityId entityId);
|
void removeCollisionComponent(EntityId entityId);
|
||||||
void markNonTransformableCollidable(EntityId entity);
|
|
||||||
void unmarkNonTransformableCollidable(EntityId entity);
|
|
||||||
void checkNonTransformableCollisions();
|
|
||||||
void setParent(EntityId child, EntityId parent);
|
void setParent(EntityId child, EntityId parent);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AssetLoader *_assetLoader = nullptr;
|
AssetLoader *_assetLoader = nullptr;
|
||||||
|
|||||||
@@ -1042,7 +1042,6 @@ namespace polyvox
|
|||||||
|
|
||||||
_sceneManager->updateTransforms();
|
_sceneManager->updateTransforms();
|
||||||
_sceneManager->updateAnimations();
|
_sceneManager->updateAnimations();
|
||||||
_sceneManager->checkNonTransformableCollisions();
|
|
||||||
|
|
||||||
_cumulativeAnimationUpdateTime += tmr.elapsed();
|
_cumulativeAnimationUpdateTime += tmr.elapsed();
|
||||||
|
|
||||||
|
|||||||
@@ -566,15 +566,6 @@ extern "C"
|
|||||||
((SceneManager*)sceneManager)->addCollisionComponent(entityId, onCollisionCallback, affectsCollidingTransform);
|
((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) {
|
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);
|
return ((FilamentViewer*)viewer)->createGeometry(vertices, (size_t)numVertices, indices, numIndices, materialPath);
|
||||||
}
|
}
|
||||||
@@ -588,4 +579,8 @@ extern "C"
|
|||||||
((SceneManager*)sceneManager)->setParent(child, parent);
|
((SceneManager*)sceneManager)->setParent(child, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FLUTTER_PLUGIN_EXPORT void test_collisions(void *const sceneManager, EntityId entity) {
|
||||||
|
((SceneManager*)sceneManager)->testCollisions(entity);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1237,67 +1237,24 @@ namespace polyvox
|
|||||||
_collisionComponentManager->elementAt<0>(collisionInstance) = asset.asset->getInstance()->getBoundingBox();
|
_collisionComponentManager->elementAt<0>(collisionInstance) = asset.asset->getInstance()->getBoundingBox();
|
||||||
_collisionComponentManager->elementAt<1>(collisionInstance) = onCollisionCallback;
|
_collisionComponentManager->elementAt<1>(collisionInstance) = onCollisionCallback;
|
||||||
_collisionComponentManager->elementAt<2>(collisionInstance) = affectsTransform;
|
_collisionComponentManager->elementAt<2>(collisionInstance) = affectsTransform;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::markNonTransformableCollidable(EntityId entityId) {
|
void SceneManager::testCollisions(EntityId entityId) {
|
||||||
// Log("Marking entity %d as non-transforming collidable", entityId);
|
const auto &pos = _entityIdLookup.find(entityId);
|
||||||
std::lock_guard lock(_mutex);
|
if (pos == _entityIdLookup.end())
|
||||||
for(auto& existing : _nonTransformableCollidableEntities) {
|
{
|
||||||
if(existing == entityId) {
|
Log("ERROR: asset not found for entity.");
|
||||||
Log("Collision already exists");
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_nonTransformableCollidableEntities.push_back(entityId);
|
auto &asset = _assets[pos->second];
|
||||||
Log("Mark complete.");
|
|
||||||
}
|
|
||||||
void SceneManager::unmarkNonTransformableCollidable(EntityId entityId) {
|
|
||||||
// Log("Removing non-transformable collidable from entity %d", entityId);
|
|
||||||
|
|
||||||
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();
|
const auto& tm = _engine->getTransformManager();
|
||||||
for(const auto& entityId : _nonTransformableCollidableEntities) {
|
|
||||||
|
|
||||||
const auto &pos = _entityIdLookup.find(entityId);
|
auto transformInstance = tm.getInstance(asset.asset->getRoot());
|
||||||
if (pos == _entityIdLookup.end())
|
auto worldTransform = tm.getWorldTransform(transformInstance);
|
||||||
{
|
auto aabb = asset.asset->getInstance()->getBoundingBox();
|
||||||
Log("ERROR: asset not found for entity.");
|
aabb = aabb.transform(worldTransform);
|
||||||
continue;
|
_collisionComponentManager->collides(entityId, aabb);
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1305,6 +1262,7 @@ namespace polyvox
|
|||||||
std::lock_guard lock(_mutex);
|
std::lock_guard lock(_mutex);
|
||||||
|
|
||||||
auto &tm = _engine->getTransformManager();
|
auto &tm = _engine->getTransformManager();
|
||||||
|
|
||||||
for ( const auto &[entityId, transformUpdate]: _transformUpdates ) {
|
for ( const auto &[entityId, transformUpdate]: _transformUpdates ) {
|
||||||
const auto &pos = _entityIdLookup.find(entityId);
|
const auto &pos = _entityIdLookup.find(entityId);
|
||||||
if (pos == _entityIdLookup.end())
|
if (pos == _entityIdLookup.end())
|
||||||
|
|||||||
@@ -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<std::vector<filament::math::float3>> 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<filament::math::float3>{ 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));
|
|
||||||
@@ -6,6 +6,7 @@ import 'package:flutter/widgets.dart';
|
|||||||
|
|
||||||
import 'package:flutter_filament/animations/animation_data.dart';
|
import 'package:flutter_filament/animations/animation_data.dart';
|
||||||
import 'package:flutter_filament/entities/entity_transform_controller.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';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
|
|
||||||
// a handle that can be safely passed back to the rendering layer to manipulate an Entity
|
// 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,
|
{void Function(int entityId1, int entityId2)? callback,
|
||||||
bool affectsCollingTransform = false});
|
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.
|
/// 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].
|
/// Sets the parent transform of [child] to the transform of [parent].
|
||||||
///
|
///
|
||||||
Future setParent(FilamentEntity child, FilamentEntity 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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
@override
|
||||||
Future<FilamentEntity> createGeometry(
|
Future<FilamentEntity> createGeometry(
|
||||||
List<double> vertices, List<int> indices, String? materialPath) async {
|
List<double> vertices, List<int> indices, String? materialPath) async {
|
||||||
@@ -1489,4 +1479,9 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
}
|
}
|
||||||
set_parent(_sceneManager!, child, parent);
|
set_parent(_sceneManager!, child, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future testCollisions(FilamentEntity entity) async {
|
||||||
|
test_collisions(_sceneManager!, entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -891,22 +891,6 @@ external void add_collision_component(
|
|||||||
bool affectsCollidingTransform,
|
bool affectsCollidingTransform,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId)>(
|
|
||||||
symbol: 'mark_nontransformable_collidable',
|
|
||||||
assetId: 'flutter_filament_plugin')
|
|
||||||
external void mark_nontransformable_collidable(
|
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
|
||||||
int entityId,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId)>(
|
|
||||||
symbol: 'unmark_nontransformable_collidable',
|
|
||||||
assetId: 'flutter_filament_plugin')
|
|
||||||
external void unmark_nontransformable_collidable(
|
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
|
||||||
int entityId,
|
|
||||||
);
|
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
EntityId Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Float>,
|
EntityId Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Float>,
|
||||||
ffi.Int, ffi.Pointer<ffi.Uint16>, ffi.Int, ffi.Pointer<ffi.Char>)>(
|
ffi.Int, ffi.Pointer<ffi.Uint16>, ffi.Int, ffi.Pointer<ffi.Char>)>(
|
||||||
@@ -928,6 +912,13 @@ external void set_parent(
|
|||||||
int parent,
|
int parent,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId)>(
|
||||||
|
symbol: 'test_collisions', assetId: 'flutter_filament_plugin')
|
||||||
|
external void test_collisions(
|
||||||
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
|
int entity,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Pointer<ffi.Void> Function(
|
ffi.Pointer<ffi.Void> Function(
|
||||||
ffi.Pointer<ffi.Void>,
|
ffi.Pointer<ffi.Void>,
|
||||||
|
|||||||
Reference in New Issue
Block a user